必要なデータを一回のリクエストで取得できるAPI
イクメンゴリラーの福田です。
突然ですがエンジニアのみなさん、
APIを用いたのWEBアプリケーションの開発をしていて、こんな不便を感じてはいませんか?
・APIのレスポンスで、必要のないデータまで返ってきてしまう。
・一つの処理を行うのに、いくつもAPIを走らせないといけない。
・バックエンド側でAPIの修正を行う際に、全体のどこで使われいるAPIなのか調べるのに時間がかかってしまう。
・結局、他の使用箇所に影響がないように、わざわざAPIをつくらないといけない。
・APIの数がどんどん増えていき、さらに管理しにくくなる・・・。
弊社MountainGorillaのWEBサービスの開発でもAPI使用することが多いのですが、
私は入社当時から上記の解決策を探し続けておりました。
先日「GraphQL」という技術を知り、もしかしたら上記の疑問が解消されるかも!?
と感銘を受けたので、少し紹介させて頂きたいと思います。
GrraphQLとは?
GraphQLは、Facebook社によって開発されたAPI向けのクエリ言語です。
2015年にオープンソース公開され、現在ではGitHubやNetflix、Spotify等でも導入され、注目が集まっています。
GraphQLの何がいいの?
GraphQLのいい点は、なんといっても「必要なデータを一回のリクエストで取得できる」ことです。
例えば、架空のスポーツジム、ゴリマッチョフィットネスの会員管理システムで、
会員一覧や、会員の「本日のトレーニングメニュー」等を確認できる機能があるとします。
上記の機能を実現するために、どのようなAPIが必要でしょうか。
一般的なAPIの場合
まず従来のAPIとして、最も一般的なRESTfull APIの場合を考えます。
RESTfull APIの場合、原則必要なリソース一つに対して一つのエンドポイント(データ取得用のURLのようなもの)を作成します。
そのため、各機能で以下のようなエンドポイントが必要になります。
例)会員一覧の取得
エンドポイント:gorilla-fitness/user
→APIからのレスポンス
{ "data": { "users": [ { "id": "1", "name:”ゴリラ太郎", "age”:”25", "initial_height”:”175", "initial_weight:”250", "customer_code”:”10", "entered_data”:”2021/01/10" }, { "id": "1", "name:”ゴリラ太郎", "age”:”25", "initial_height”:”175", "initial_weight:”250", "customer_code”:”10", "entered_data”:”2021/01/10" } ] }
・・・(以下省略)
ユーザーの一覧表示のため、ユーザー情報を取得しています。表示したいのは名前だけだったとしても、年齢や会員番号、入会日等、必要のないデータまで取得してしまっています。
例2)会員詳細
会員のうち、「ゴリラ太郎」さんの入会時の体重、今日の体重、今日のトレーニングメニュー、今日の食事メニュー、食事のカロリーを表示するとします。
まずは、基本情報として名前と入会時の体重を取得します。
エンドポイント①:gorilla-fitness/user/1
→APIからのレスポンス
{ "data": { "users": { "id": "1", "name:”ゴリラ太郎", "age”:”25", "initial_height”:”175", "initial_weight:”250", "customer_code”:”10", "entered_data”:”2021/01/10" } }
一つ目のAPIで、名前と入会時の体重を取得できましたが、
必要のないデータも取得してしまっています。
次に、ゴリラ太郎さんの本日の食事メニューを取得します。
エンドポイント②:gorilla-fitness/user/1/today_food
→APIからのレスポンス
{ "data": { "foods": [ { "id": "1", "name:”バナナ", "calorie”:”100", }, { "id": "2", "name:”リンゴ", "calorie”:”80", }, ] }
二つ目のAPIで、今日の食事メニューとカロリーを取得できました。
次に、本日のトレーニングメニューを取得します。
エンドポイント③:gorilla-fitness/user/today_training
→APIからのレスポンス
{ "data": { "training": [ { "id": "1", "name:”ランニング", "calorie_consumed”:”100", }, { "id": "2", "name:”ウェイトリフティング", "calorie_consumed”:”50", }, ] }
三つ目のAPIで、今日のトレーニングメニューと消費カロリーを取得できました。
RESTfull APIの場合、このように、一つの画面を表示するために複数のAPIを利用する必要があり、
表示とは関係のないデータも多く取得してしまいます。
これを回避するために専用のAPIを別に作成する方法もありますが、
エンドポイントが増えて、管理する手間が増えていきます。
GraphQLの場合
GraphQLを用いた場合、会員詳細画面のAPIは以下です。
エンドポイント:gorilla-fitness/graphql
リクエスト
{ user(id: 1) { name initial_weight food { name calorie } training { name calorie_consumed } } }
→APIからのレスポンス
{ "data": { "user": { "name:”ゴリラ太郎", "initial_weight:”250", "foods": [ { "id": "1", "name:”バナナ", "calorie”:”100", }, { "id": "2", "name:”リンゴ", "calorie”:”80", }, ], "training": [ { "id": "1", "name:”ランニング", "calorie_consumed”:”100", }, { "id": "2", "name:”ウェイトリフティング", "calorie_consumed”:”50", }, ] } } }
GraphQLを用いた場合、一回のリクエストでデータを取得できました。
GraphQLでは、リレーション先のデータも含めて、必要なデータのみ指定して取得できるので、
一度のリクエストで不可分なくデータが取得できます。
また、既存のプロジェクトがある場合、もとからあるRESTfull APIとの併用も可能です。
そのため、複雑なAPIに関しては従来のAPIを利用し、比較的シンプルなAPIだけGraphQLに変更していくことも可能です。
以上、GraphQLの紹介をさせて頂きました!引き続き、オススメの技術があれば、こちら紹介していきたいと思います!