お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。
投稿日:
開発::設計開発::Web

この記事では下図のシステム構成を前提に話を進めるものとする。この時、BFFの部分のアーキテクチャをREST APIにするか、GraphQLにするかというのが今回の話。

http-archtecture.png

REST API

長所

  • Web標準であるため特別な技術が必要ない
    • ファイルアップロードのような特殊な通信プロセスも何も考えずに実装できる
    • エラーもエラーコードを返せばいい
  • 学習コストが低い
  • 設計が単純
    • エンドポイントに何かを要求すれば、それに対する応答が帰ってくるという点で非常にシンプル
    • CRUDはGET/POST/PUT/DELETEで分かれており、これも単純
  • 依存するライブラリがない
    • 破壊的変更を受ける可能性がない
    • renovateによるアップデート地獄とも無縁
  • BFFとフロントエンドで型情報の共有が容易
    • BFFをTypeScriptで実装していれば、そのまま型情報が流用できるし、他の言語で実装していてもOpenAPIを作り、そこから型情報を得ることが可能だ
  • curlからリクエストを投げやすい
    • 基本的にペイロードが単純であるため

短所

  • 複数のデータを取得する際に複数回APIを呼ぶ必要があり、オーバヘッドが大きい
    • 今回のケースでは呼び出し先のAPIはBFFによって集約されているため、適切にエンドポイントを設計すればこの問題は回避できる
  • オーバーフェッチとアンダーフェッチ
    • データを取得しすぎたり、取得しきれないといった問題が発生することがある
    • 例えば/api/v1/userからユーザー名だけを取得したい場合に、ユーザーIDや年齢といった余計なデータが付随してしまうことがあったり、このエンドポイントからそのユーザーのログイン履歴を取得することができなければそれはアンダーフェッチになる
    • 今回のケースでは呼び出し先のAPIはBFFによって集約されているため、適切にエンドポイントを設計すればこの問題は回避できる
  • エンドポイントが増えすぎると何が何かわからなくなる
    • GraphQLでもQueryが増えすぎれば同様の問題だと思うのでREST API固有の問題だとは思わない
  • レガシーな技術
    • レガシーというのはそれだけで悪である

GraphQL

長所

  • モダンであり、流行っている
    • モダンであり、流行っているということはREST APIより良い選択肢であると言える可能性がある
  • クエリを利用した柔軟な要求が可能
    • REST APIと異なり特定のエンドポイントに縛られることがない
    • またクエリを読むことで、フロントエンド側の実装のみで、どのような要求なのかを知ることができる
  • フロントエンド側で取得したいデータを制御できる
  • エコシステムが充実している
    • キャッシュやエラーハンドリングは勿論のこと、Reactなど特定のフレームワークと統合するための仕組みが存在する
  • デバッグ用のブラウザ拡張機能が存在する
    • デバッグ用のブラウザ拡張機能が存在し、これがあるとデバッグがしやすい

短所

  • Web標準ではない
    • ファイルアップロードのような特殊な通信プロセスは追加のライブラリなどが必要になるケースがある
  • 学習コストが高い
    • 非常に充実したエコシステムが存在するということは反面学ぶことも多いということになる
      • Web標準ではないが通信にはHTTPを使っているため、Web標準を知らなくていいわけではない
      • GraphQL標準のようなものは存在し、それと別にライブラリの構成についても学ぶ必要がある
    • REST APIのノリで利用するのであれば使う意味がない
  • 型システムとの相性が悪い
    • クエリを利用し柔軟にデータを要求できるということはデータ構造が不定であるため、静的型付け言語との相性が悪い
    • 多くの場合、辞書型を使って処理することになると思うが、このままでは不具合を引き起こしやすく、型の正規化を行う場合余計な処理プロセスが入ってしまう
    • また型の正規化をするための関数を個別に作っているとやっていることがREST APIと大差なくなる
  • 設計が難しい
    • スキーマ設計が難しいと言われており、HowTo記事が多くある。AWSにさえある
    • 何でもかんでも取得できる魔法のリゾルバみたいなのを作ってしまうとフロントエンド側で取得できてはならないデータまで取得できてしまうためよく考える必要がある
      • 例えばクエリに応じた内容をDBから引っこ抜いてくる実装だったりすると、他のユーザーの情報を取得するなどができてしまうので結局BFF側でもある程度の作りこみが必要になる
      • 他にもN+1問題が起きるとパフォーマンスが悪くなるどころか、最悪サーバーが落ちることすらあり得るだろう
  • 実装が難しい
    • 学習コストが高い部分と同じだが、全員がGraphQLとそのライブラリの理念を理解するのはあまり現実的ではなく、実装が難しくなる要因になると思う
  • 開発ツールの対応状況があまりよくない
    • VSCodeを開発に使おうとしたときにGraphQLの対応状況があまりよくなく、入力補完やLintなどをいい感じにしてくれる存在がいない
  • ライブラリの保守作業が必要
    • ライブラリはアップデートされ、時として破壊的変更も起きるものなので、それらの対応が必要
    • renovate地獄の一翼を担う存在になる
  • curlからリクエストを投げづらい
    • クエリ文が複雑になればなるほど投げづらくなる
    • 下手したらこれだけでオーバーフェッチとかどうでもよくなるレベルだと思う