自ブログからの引用です。
概要
あるとき、GraphQLを実務で利用している友人と飲みながら、彼が携わっているシステムに関して、GraphQLやBFF層がそのチームにとって本当に必要なのか?を議論したことがありました。
個人的には、GraphQLは複雑性を増したり、フロントエンドスピシフィックなアーキテクチャを生み出したりするため、GraphQLを利用する明確な理由がなければ、基本的にOpenAPIを利用したプラクティスの方がよりシンプルだと考えています。
その際に、彼から「でも、RESTは使いにくいよね」という反応がありました。
私はよく他のGraphQL, gRPC利用者からも同じような反応を受けることがあるのですが、RESTという言葉は本質的な観点を見落としている可能性があると感じています。
本記事では、なぜREST APIという用語に注意した方が良いのか?と、APIエンドポイントの技術選定に関する正しい観点を整理します。
APIモデリングのパラダイム
APIのエンドポイントを開発する上で、エンドポイントのモデリング方法(どのように整理するか?)に関しては主に2つのパラダイムがあります。
- リソース
- 関数
1はリソースによる整理で、クライアントがリソースごとアクセスできるように整理します。
2の場合は関数で整理する方法で、API側はクライアントのニーズに合わせてエンドポイントを整理します。
この2つはAPIエンドポイントのモデリング方針を決める上で基盤的な概念です。大まかな使いわけとしては、APIとクライアントが一体のシステムの場合は2のように機能ごとにモデリングすると便利なことが多く、クライアントがAPIと別のシステムになる場合、またはクライアントが不特定多数になる場合は、個別のクライアントのニーズに答え切ることが難しいため、2のリソースでの整理が多くなります。
RESTの再認識
1つ、Googleのポストを引用します。
最も使用頻度の低い API モデルは REST です。REST という単語が広く使用(あるいは乱用)されていても、この方法で設計されている API は非常に少数です。
実は、この記述を意外に感じた方も少なくないのではないでしょうか?
現実にはRESTなAPIはほとんど存在しません。それにもかかわらず、実際の現場ではよくRESTという用語をよく耳にすると思います。
このように、概念が間違った使われ方をしているために、正しい認識や議論が阻害されれている状況があると感じます。
では、REST APIとは本質的にどんな物でしょうか?RESTに関する正確な定義は、(私も詳しくないので)他の多くの情報元に譲るとして、重要な点の一つとしては、(REST)原則に則ってリソースで整理する点です。
例えば、id=100のユーザを取得したければ、クライアントがAPIの実装をよく知らなくても、GET: /user/100にアクセスすればよいということになります。
このように、REST APIではサーバーとクライアントの示し合わせの必要性が低くなるため、OpenAPIなどのIDLの利用価値がそれ程高くありません。
RPCとは?
では、OpenAPIを利用したプロジェクトのほとんどがRESTではないとしたら、実際はどのような概念を使っているのでしょうか?
一般的に、OpenAPIで管理されているAPIエンドポイントのほとんどが、RPCエンドポイントとしてモデリングされています。
PRCとは、ネットワークの先にあるシステムのプログラム(手続き)を呼び出すことです。例えば、ユーザの取得用にGET: /getUser?id={xxx}やGET: /search?userId={xxx}のようなエンドポイントを公開します。
つまり、RPCはリソースではなく、関数でAPIエンドポイントを整理します。
RPCエンドポイントの整理方法はAPI側次第なので、クライアントに対してどんなAPIエンドポイントが利用できるか?を教えてあげる必要があります。そのため、OpenAPIのようなIDLを利用することで、インターフェイスを効率よく交換することができる様になります。
このように、RESTはリソースで明示的に整理されるのでOpenAPIの利用価値がそれほど高くない一方で、RPCの場合はOpenAPIなどのIDLを利用しないと server - client 間のインターフェイスの調整が難しいため、OpenAPIをRESTと呼ぶのはある意味矛盾した表現にもなります。
なぜ、OpenAPIをRESTと呼ぶとよくないのか?
OpenAPIをRESTと表現する場合、RESTとRPCの特徴の区別を曖昧にするからです。
これは前述の、リソースと関数のどちらでモデリングするか?という重要な観点を曖昧にし、APIの技術選定において大きな認識の齟齬を生むことがあります。
例えば、あるシステムのバックエンドとフロントエンドを同じ組織で開発をしている場合は、本来一体であるシステムがたまたまネットワークで分断されているためにHTTPを利用しなければならないだけであって、両者が向き合っているドメインや抱えるニーズは全く同じなので、RPCを利用することで仮想的に一体のシステムとして開発を進めることができ、認知不可を軽減し、開発効率を高めることができます。
一方で、クライアント側が不特定多数の顧客で、多様なニーズに合わせて機能提供する必要がある場合には、より汎用的かつ明示的にリソースで整理する方が良いかもしれません。
その他にもたくさんのパターンが考えられますが、リソースと関数のどちらでモデリングするかは選定のベースラインになります。
また、GraphQLやgRPCなどの他のAPIプロトコルと比較検討する際も、リソースと関数の観点が重要です。
冒頭に述べた「RESTはなぁ〜」という議論は本質的でなく、OpenAPIと比較する場合はそもそもほとんどがRPCになるため、リソースでモデリングしたいのか?RPCでモデリングする場合どちらの技術の方が現況にマッチするか?といった観点が重要になります。
まとめ
本記事では、RESTとRPCの違いに関して整理し、OpenAPIを不用意にRESTと呼ぶことは、重要な論点を曖昧にするために好ましくないことを説明しました。
API構築は一連の開発業務の中でもコアな部分になるため、リソースと関数の観点を意識して状況にあった技術選定を検討していけると良いと思います。