未熟学生エンジニアのブログ

TetsuFeの個人開発ブログ

TetsuFeはテツエフイー と読みます。FlutterやWeb周り全般、チーム開発について語るブログ

REST、GraphQL、gRPCの使い方中心のまとめ

僕はRailsで初めてRESTでCRUD APIを作ったのですが、その後いろいろなバックエンドアプリを実装したり、他の方の記事や実装をみたり、チュートリアルをこなしたりするうちに GraphQL、gRPCというものもここ数年普通に使われるようになってきているということを知り、そろそろそれらを選択肢として考えた上で採用する必要がある ように感じています。

この記事は、REST、GraphQL、gRPCの3つのAPI設計手法(思想?)を使い方中心に調べたことのまとめです。

ちなみに、詳しくはこちらの記事が詳しそうです。このブログ記事を書く際にも一部参考にしました。逆に詳しすぎて読む気があまり起こりません。次に新しいサービスを作る際や、新しい構成を考える際に読もうと思っています。(OpenAPIがRESTにあたるようです)

employment.en-japan.com

REST

  • HTTPメソッド(GET, POSTなど)とエンドポイント+リクエストボディ+αの組み合わせ
    • 例1: GET /api/users
    • 例2: POST /api/users リクエストボディ={'name': 'hoge', 'email': 'fuga@fuga.fuga'}
  • サーバー側の実装
    • 上記の組み合わせに応じてアクセスを受け取れるようにし、アクセスに対してレスポンスを返すように実装
  • フロントエンド側の実装
    • サーバ側の実装に対応するようにHTTPリクエストを送り、受け取れるように実装

RESTはrailsなどでおなじみという方は多いと思います。

railsを例にしたREST概念の説明についてはこちらがわかりやすそうです。

www.slideshare.net

実際にRailsAPIを作ってみる手順

qiita.com

GraphQL

参考:「GraphQL」徹底入門 ─ RESTとの比較、API・フロント双方の実装から学ぶ - エンジニアHub|若手Webエンジニアのキャリアを考える! など

  • エンドポイント+クエリ
  • エンドポイントは一つでも複数でも良い。リクエストボディに任意のクエリを指定することでそれに応じたレスポンスが返る。
  • サーバー側の実装
    • (一般に)単一のエンドポイントを用意。クエリに応じてレスポンスを返すように実装
  • フロントエンド側の実装
    • GET/POST + エンドポイント + クエリ とのセットを送り、返ってきたレスポンスを処理できるよう実装
  • クエリは二種類に大別され、それぞれ Query と Mutation という。これは言い換えると GET と POSTだけでいいということらしい。
    • RESTよりもいい感じにシンプルでわかりやすい
  • クエリがわかりやすいこと、クエリとレスポンスが同じような形式で返ってくることから、エンドポイントが一つでもクエリの意味が十分わかりやすいとのこと。
    • RESTよりもいい感じにシンプルでわかりやすい
  • クエリが柔軟に表現できるため、複数のテーブルからの情報をまとめたりといった複雑な参照系処理が得意。
    • 単純な表現しかできないRESTに比べて、ここが差をつけるポイントとなる

実例に関しては、先ほど上で挙げたブログ記事用のリポジトリが参考になりました。

https://github.com/gfx/graphql-blog/blob/master/frontend/App.tsx

https://github.com/gfx/graphql-blog/blob/master/frontend/client.tsx

gRPC

  • RPCという方式を使っているらしい。
  • エンドポイントが仮想的。パス指定自体をしないかのように利用できる
    • HTTPの1行目のリクエスト行は GET / または POST / になるということ
  • 全てPOSTという実装も全然OK
  • HTTP API の設計方向 - V - Medium
  • GraphQLも2種類になったとはいえ、それを凌駕するシンプルさ
  • Protocol Buffersというスキーマを定義して、そこからクライアント・サーバーのコードを自動生成可能
  • JSONを使わない。バイナリによる通信で高速。
  • Google系のライブラリを使っている場合は、意図せずgRPCを使っているかも・・。Firebase(Firestoreなど)はまさにそう

CRUDの実装は以下が参考になります。エンドポイントのパスが本当に一つしかありません(というか設定していません)

medium.com

github.com

導入事例

クックパッドがgRPCを採用するまで サービス間通信で抱えていた課題と、RubyでgRPCを運用するための工夫 - ログミーTech

比較ポイント

  • エンドポイントの数について
    • エンドポイントが一つだと、ログやキャッシュが特殊な方法になる場合がある。RESTはその点で従来の知見がたまっているため有利な印象。

その他見つけた記事

Googleによる比較記事 https://cloudblog.withgoogle.com/ja/products/api-management/understanding-grpc-openapi-and-rest-and-when-to-use-them/amp/