GraphQL
https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/GraphQL_Logo.svg/2000px-GraphQL_Logo.svg.png
https://graphql.org/
2015年に Facebook により開発された、API用のデータクエリ、及び操作用言語で、2018年に Linux Foundation に属する GraphQL Foundation に移管された。
GraphQLの目標は あらゆるWebプラットフォームにおいて広く使えるフォーマットを用意すること。
GraphQL の仕様には、型システムや、クエリ言語、静的解析や、型インストロペクションが含まれ、データの読み書きに加えてリアルタイム更新(Subscribe)がサポートされる。
REST は API を実装するための設計モデルで決まった仕様は設計はないが、GraphQL という標準化された言語、型付、仕様により、異なるデバイス間の通信に標準化された言語、大型なアプリケーションの開発がより、厳格でシンプルに進められるようになるということらしい。
つまりどういうことかと言うと GraphQL で喋ればアプリケーションを動かすために必要なリソースを、使用の範囲であれば悩むことなくうまくやりとりできるようになるということのようだ。そしてGraphQLで問い合わせた結果得られるデータの元はデータベースであってもいいし、別なREST APIでも良いということであり、取りに行き方とデータの返し方のマッピングさえ行っておけばうまく回せるということのようだ。
https://graphql.org/learn/ も参考されたし。
GraphQL を使うと何が嬉しいのか?
WebAPI を作成する上では REST とよく比較される事が多い。
基本的には下記のようなメリットを得られる。
REST だと膨大になりがちなAPIリクエスト数の抑制
データ構造の最適化
スキーマによるリクエストの型チェック
参考サイトの例 を引用しつつまとめる。
主に文脈としては、画面を形作るためのAPIリクエストという形で進行する。
リポジトリはココ なので手を動かして見ながら見ると良さそう。
RESTの課題点
まず、RESTを前提とすると参考サイトの例では、リスト自体とリストに表示されるn個の要素の詳細それぞれのデータを取得するために、1 + n 回のAPIリクエストが必要になること。
HTTPリクエストはそもそも重い処理なので、基本的に気軽に叩いて良いものでない。
また、要素の数が膨大になれば画面設計にもよるがそれだけAPIのリクエストが増えていく構図になる。
この点を解決するには、画面構成に必要な要素を詰め込んだ専用のAPIを作るなどを行えば、リクエスト回数を減らすようなことはできる。
しかしながら用途に応じてAPIのエンドポイントを無尽蔵に増やしていけばあっという間に破綻し、後の負債となる。
RESTful API で取得されたデータが必ずしもすべて、画面構成で必要にならないこと。
上記で対処した専用のAPIを使うにしても戻ってきた body すべてを使うわけでもないシーンは多く、クライアント側でのパース処理に無駄にリソースを消費することになる。
gRPC のパース処理のコストでも記載したが、基本的に文字列の操作はすごく重い処理なので無用に実行することは出来ない。
パースされる文字列量を抑えるには必要になる要素だけを拾えるようクエリパラメータを設定できるようなAPIにすることで対処可能
しかしながら専用のAPIが増えていく課題が残る。。。
GraphQL によるクエリ
シンプルにクライアントが必要としている情報をクエリとして発行する
下記のクエリはリストとリストに含まれる要素のうち必要とするデータ(名前と画像)だけを拾うクエリになる
code:query.gql
query ListAndItems {
lists {
name
image
items {
name
images
}
}
}
クエリの構造は事前にスキーマで定義されて、APIから提供される
開発環境においては GraphQL は標準で GraphiQLというWebIDEを装備しているのでそれを使うとよい
GraphQL の考え方
REST とは異なり URI によるマッピングを行わない。
つまりほしい情報をほしいときにほしいだけクエリにより取得できる。
レスポンスのデータサイズはクライアント側から常に制御が可能になり効率がいい。
RPC的であり、URLやメソッドの設計に悩まずに済む。
GraphQLはスキーマを用いてAPIの定義ができるような設計になっている。
先程のクエリを処理できる(であろう(未検証))スキーマは以下の通り。
型 List, Item がそれぞれリンクする形になっており、 schema の query から 取得できるデータの様式が設定されている(?)
code:sample.gql
schema {
query: Query
}
type Query {
lists: List
items: Item
list(id: Int!): List
item(id: Int!): Item
}
type List {
id: Int
name: String
image: String
items: Item
}
type Item {
id: Int
name: String
image: String
items: Item
}
その他
独自のキャッシュ機構が仕様で定義されている
gRPC での Protocol Buffers がそうであったようにスキーマからクライアントやドキュメントを作成できる。
https://graphql-code-generator.com/
参考
https://www.webprofessional.jp/rest-2-0-graphql/
https://github.com/sitepoint-editors/sitepoint-graphql-article