ブロックチェーン企業で働くエンジニアのブログ

ブロックチェーン企業でエンジニアとして働いています。ブロックチェーンに限らずDXなどもメイン活動に

The GraphとVue Apolloを組み合わせてVue.jsからEthereumのイベントを取得する

前回はEthereum上のイベントをGraphQLで取得するThe Graphの使い方について書きました。

www.blockchainengineer.tokyo

今回はより実践的に、Vue.jsを用いてThe Graphを使ってみます。

curlで投げてみる

今回、例としてENSのSubGraphにGraphQLのクエリを投げてみます。

f:id:naomasabit:20210607083045p:plain

https://thegraph.com/explorer/subgraph/ensdomains/ens

ENSのドメイン発行イベントから、id, name, labalnameを取得するクエリを投げてみます。

{
  domains(first: 5) {
    id
    name
    labelName
  }
}

curlで投げてみると、以下のようになります。ドメインが取れていますね。

% curl -X POST -H "Content-Type:application/json" -d '{"query":"{domains(first: 5) {id name labelName}}"}' https://api.thegraph.com/subgraphs/name/ensdomains/ens
{
   "data":{
      "domains":[
         {
            "id":"0x0000000000000000000000000000000000000000000000000000000000000000",
            "labelName":null,
            "name":null
         },
         {
            "id":"0x0000044a32f0964f4bf8fb4d017e230ad33595c0e149b6b2d0c34b733dcf906a",
            "labelName":"taoli",
            "name":"taoli.eth"
         },
         {
            "id":"0x00001fea5a96f3dea9967dd87e483399bc2f02b630988fd598c77460a1d3d415",
            "labelName":"linliu",
            "name":"linliu.luxe"
         },
         {
            "id":"0x00002116a545ddf10770e5b2d77f3302a31b0ae318c0a671f9e4ba350019a628",
            "labelName":"concord",
            "name":"concord.eth"
         },
         {
            "id":"0x0000258e7beff0c13718249fdd6add115bc49c70c678e9928b455dfd18bf7c3a",
            "labelName":"7261111",
            "name":"7261111.eth"
         }
      ]
   }
}}                       

Vue Apolloで投げてみる

JSからGraphQLで投げるフレームワークApolloがあります。Vueと連結するフレームワークのVue Apolloを使います。

apollo.vuejs.org

Vue Apolloのセットアップ

https://apollo.vuejs.org/guide/installation.html#manual-installation こちら参考です。

npm install --save vue-apollo graphql apollo-boost

or

yarn add vue-apollo graphql apollo-boost

でインストールします。

Vue.jsへの組み込みは以下のようにします。mainのVueインスタンス生成部分に設定します。

import {ApolloClient} from 'apollo-client';
import VueApollo from 'vue-apollo';
import { HttpLink } from 'apollo-link-http';
import {ApolloLink, concat} from 'apollo-link';
import { InMemoryCache } from 'apollo-cache-inmemory';
import gql from 'graphql-tag'

Vue.use(VueApollo);

const httpLink = new HttpLink({
  uri: 'https://api.thegraph.com/subgraphs/name/ensdomains/ens',
});

const apolloClient = new ApolloClient({
  link: httpLink,
  cache: new InMemoryCache()
});

const apolloProvider = new VueApollo({
  defaultClient: apolloClient,
  defaultOptions: {
    $loadingKey: 'loading'
  }
});

new Vue({
  el: "#app",
  router,
  store,
  apolloProvider,
  render: h => h(App),
})

クエリの設定

クエリの設定のために切り出します。 ens-query.js を作ります。

import gql from 'graphql-tag'

// 全ての発行済tokenを取得
export const DOMAINS = gql`
{
    domains(first: 5) {
      id
      name
      labelName
    }
  }
`

apolloコンポーネントの設定

apollo呼び出し元のVue.jsファイルに以下のように記述します。既に設定したVueインスタンスから作られていればapolloが使えるはずです。

<script lang="ts">
...
export default {
  data() {
    return {
      ...,
    }
  },
  apollo: { // 1. apolloコンポーネントの設定
  }
}
</script>

クエリの呼び出しとプロパティへの設定

apolloコンポーネントの設定をした、apollo呼び出し元のVue.jsファイルに追記します。

  1. queryの読み込み
  2. propertyの設定
  3. クエリ呼び出しの設定
<script lang="ts">
import {DOMAINS} from "../../graphql/ens-query";  // 2. queryの読み込み

export default {
  data() {
    return {
      ...,
      domains: [], // 3. propertyの設定
    }
  },
  apollo: { // 1. apolloコンポーネントの設定
     domains: DOMAINS, // 4. クエリ呼び出しの設定
  }
}
</script>

DOMAINSの返り値の期待値はcurlで呼び出した以下になります。返り値のdata直下の domains について、apolloコンポーネント内のdomainsというpropertyと名前が一致していますね。これが一致していると自動的にデータを設定してくれます。ここに気づかないと少しはまります。

{
   "data":{
      "domains":[
         {
            "id":"0x0000000000000000000000000000000000000000000000000000000000000000",
            "labelName":null,
            "name":null
         },
         {
            "id":"0x0000044a32f0964f4bf8fb4d017e230ad33595c0e149b6b2d0c34b733dcf906a",
            "labelName":"taoli",
            "name":"taoli.eth"
         },
         {
            "id":"0x00001fea5a96f3dea9967dd87e483399bc2f02b630988fd598c77460a1d3d415",
            "labelName":"linliu",
            "name":"linliu.luxe"
         },
         {
            "id":"0x00002116a545ddf10770e5b2d77f3302a31b0ae318c0a671f9e4ba350019a628",
            "labelName":"concord",
            "name":"concord.eth"
         },
         {
            "id":"0x0000258e7beff0c13718249fdd6add115bc49c70c678e9928b455dfd18bf7c3a",
            "labelName":"7261111",
            "name":"7261111.eth"
         }
      ]
   }
}

SubGraphの返り値を描画

呼び出し元のVue.jsファイルで domains propertyを描画します。

<div>{{ domains }}</div>

....
<script lang="ts">
....

Vueを起動してブラウザでアクセスしてみると以下のように描画されます。

f:id:naomasabit:20210607082039p:plain

きちんと取れていますね。

ブラウザのNetworkタブはこんな感じです。

request

f:id:naomasabit:20210607082244p:plain f:id:naomasabit:20210607082315p:plain

response

f:id:naomasabit:20210607082359p:plain

まとめ

実際にやってみたのですが、めちゃくちゃ便利です。Ethereumは巨大なデータベースであり、そこから自由にイベントデータを取得できるSubGraphはDapps開発においてこれからより活用されるでしょう。 GraphQLによるアクセスの増加は見込まれれるはずなので、安定的な稼働が気にはなりますが、今のところサッと返ってはきます。