10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

nem / symbolAdvent Calendar 2024

Day 7

SymbolブロックチェーンでGraphQLを使いたい

Last updated at Posted at 2024-12-06

最近は本業の方でGraphQLを利用することが増えてきました。
そこで、SymbolでもREST APIだけではなくGraphQLを使ってノードからデータを取得できないかちょっと試してみます。

GraphQLを活用するメリット

複数のAPI呼び出しを1つのリクエストで実現

RESTでは複数のエンドポイントを順番に呼び出す必要がありますが、GraphQLでは必要なデータを一度に取得可能です。
例えば、こんな感じ。

query SymbolGqlExample {
  # ネットワークの情報
  getNetworkType {
    description
    name
  }
  # 接続先ノードの状態
  getNodeHealth {
    status {
      apiNode
      db
    }
  }
  # 特定のブロック高の中身
  getBlockByHeight(height: "65536") {
    ... on BlockInfoDTO {
      id
      block {
        beneficiaryAddress
        difficulty
      }
    }
  }
}

上記のクエリを実行すると以下のようなレスポンスが取得できます

{
  "data": {
    "getNetworkType": {
      "description": "Symbol Mainnet",
      "name": "mainnet"
    },
    "getNodeHealth": {
      "status": {
        "apiNode": "up",
        "db": "up"
      }
    },
    "getBlockByHeight": {
      "id": "65C57A484CF5710B720DB1A7",
      "block": {
        "beneficiaryAddress": "685B9B33391EFA3C823B696974702CBC56E1A57FE5F1321B",
        "difficulty": "78040468282391"
      }
    }
  }
}

クライアント側の柔軟性向上

SQLのSELECTのように、必要なデータだけを取得できます。

query SymbolGqlExample {
  # 接続先ノードの状態
  getNodeHealth {
    status {
      # apiNodeの状態はべつにいらねーや
      # apiNode
      db
    }
  }
}

結果↓

{
  "data": {
    "getNodeHealth": {
      "status": {
        "db": "up" // dbのステータスだけ取れる
      }
    },
}

こんな感じで、必要なデータだけ取得する事もでできるのでネットワークの帯域も節約できます。

GraphQLを使うために必要なもの

さて、GraphQLを使用するには、**リゾルバ(resolver)**の実装が必要です。リゾルバは、クライアントからのクエリに応じてデータを取得し、返却する役割を果たします。

また、リゾルバを構築するにはスキーマが必要です。スキーマはGraphQLでデータの構造やリクエストの形式を定義するものです。

今回どうするか

さすがにリゾルバやらスキーマやらを1から作っていくのは大変です。

今回はsymbol-blockchain-community/symbol-rest-clientで有志の方々がメンテしているOpenAPI仕様準拠のYAMLファイルを使って自動生成してみます。(このやり方には課題があるのですがそれは後ほど。)

やり方

(mod 2024.12.15)
執筆時動かなかったものがようやく動いたのでgithubで公開しました
symbol-graphql-server

こちらのREADME.MD記載の手順で 4.playgroundの起動 まで進めてください。
(日本語版READMEはこちら)

実際に使ってみた

image.png

Playgroundにアクセスするとこんな感じでGraphQLを試すことができます。

簡単にPlaygroundの使い方を解説すると以下のようになります。

  • 左:スキーマのdocumentやクエリの実行履歴などが確認できます。Explorerからはそのスキーマに定義されたフィールドを確認できますので、クエリ作成の参考になります。(どんなデータが取れるのかなど)
  • 中央: クエリを書く欄です。フォーマットもできますがコメントが消えるのでしないほうがいいw
  • 右側: 実行した結果が表示されます。

まとめと課題

今回は、OpenAPI形式のYAMLを使用してスキーマとリゾルバを自動生成し、REST APIをラップする形でGraphQLを実現しました。

ただし、この手法は以下の課題があります:

  • 現状、REST APIをラップしているだけであり、SymbolノードのDBに直接アクセスしているわけではない
  • そのため、複数のスキーマからデータを取得しようとした場合、それぞれのスキーマに対応する回数分のREST APIリクエストが内部で実行されてしまう。

将来的には、REST APIに依存せず、ノードのデータベースと直接やり取りできるようなリゾルバの実装を目指します。

この記事で紹介したOpenAPIを用いたGraphQLサーバーは、Symbol-blockchain-communityのGitHubリポジトリにサンプルとして公開予定です。
※現在は前述した私個人のGithubリポジトリを参照してください。いずれこちらに移します。

本バージョンをv1とし、データベース直接接続型のv2を順次実装していければなーと思います。

そんなわけで、symbol-graphql-serverへの貢献者を募集しています!

10
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?