見出し画像

GraphQLとはなんぞや

やっと本題のGraphQLにはいるんですが、その前にそもそもGraphQLって? って方がまだ多いのでここでおさらい。

GraphQLとは新しいAPIのスタイルです。
HTTPの上でやり取りされます。

REST APIの弱点

一般的に実装例の多いREST APIですが、弱点があるわけです。

"Chatty" な性質

特に英語ではよく "chatty" と言われる性質です。

以下のようにお買い物カゴの中の画面を作ろうと思います。
対して利用可能なAPIのエンドポイントは右の通り。
さて画面を生成するのに何回のAPIリクエストを送らなければいけないでしょうか。

まず最初に /cart にアクセスして現在のカートの状況をとってきます。
画面要素のうちでは合計金額を取得できます。

次に該当のカゴIDに紐づけられたカートの中身を取得します (/cartItems)。
これはごそっととってくることができる想定。
それぞれの行の数量とか小計とかを取得できます。

さて先ほどのリクエストで製品のIDは取得できましたが、IDを表示されてもユーザーは何のことかわからないので表示名を取得したいです (/products)。
1個目のプロダクト。

2個目のプロダクト。

3個目のプロダクト。

都合5回のリクエストを送信してやっと画面要素が揃いました。
このように何度も行ったり来たりしないと画面要素が揃わない性質を "chatty" と表現したりします。
ここまでの間ユーザーは画面が表示されるまで待っているわけです。

だったら全部の要素をバックエンドで結合すればいいじゃないか!
というのがよくある結合です。

とはいえこれ適切なデータ粒度ってどうでしょう。
PCのブラウザで表示するとき、タブレットで表示するとき、スマートフォンで縦長の画面で表示するとき、横長の画面で表示するとき、それぞれ画面要素に欲しいものだったりレコードの数だったりってバラバラではありませんか?

検索条件の柔軟性

REST APIで条件指定ってできますよね。
でも比較とかOR条件とかも含めた柔軟なクエリは吸収しづらいので、 [/search] のようにファンクションを実装してその中で条件を指定する設計にしたりします。

最初はREST APIをどこもデータベースのテーブル構造をそのまま発行するところが多いのですが、そこから柔軟なクエリを使えるように色々作りつけていくと、だんだんどんな条件が指定できるかみんな忘れていったりします。

GraphQLとは

GraphQLはこれらのREST APIの弱点を克服するようなAPIのスタイルです。SOAPとかRESTではなくどちらかというと使い勝手はSQLに近いです。

例えば従業員の情報を取得するためREST APIではこういうやりとりになりますよね。左がリクエスト、右がレスポンス。

REST API

GraphQLは例えばこう。

GraphQL

リクエストのBodyの中にどのオブジェクトからどの条件でデータを欲しいのか、どの属性が欲しいかを書きます。
レスポンスでは該当したデータを受け取ることができます。
このようにデータのやりとりに特化し、SQL文のような使い勝手を定期ょいうできるのがGraphQLです。

詳細はぜひGraphQLのページで。

GraphQLのアクセスコントロールってどうなの

HTTPなのでOAuthは使えるんですが、問題はURLごとのアクセスコントロール、およびレコードレベルのアクセスコントロールの部分です。

ページ見ていただくとお気づきいただけると思うのですが、全てのオブジェクトが一つのURLで提供されます。
典型的なのは /graphql です。

REST APIではオブジェクトがURLとして表現されるので、API GatewayはリクエストのURLを見ながらアクセスコントロールをしているわけです。

GraphQLはURLレベルでのアクセスコントロールはできないので、例えば上記の例で言うと employees へのアクセスを許可できるかできないかは、受け取った後にビジネスロジック内で判定しないといけないのですよね。

できるかできないかでいえばできるので問題はないのですが、実装の中でのアクセスコントロールの実装ボリュームが多そうです。

Bodyの中を見ないといけないと言う点からAPI Gatewayでのメトリックも取りづらくなります。
なんだかんだでどのオブジェクトにどの種類のクライアントがどのエンドポイントにどれだけアクセスしているかのデータはとても便利なので。

そのうちBodyを見ながらメトリックをとったり認可をコントロールしてくれるGraphQL専用のソリューションが出るんじゃないでしょうか。

この記事が気に入ったらサポートをしてみませんか?