API設計の流儀
- アプリケーションサーバ開発の大まかな流れとは:
- リクエスト形式を規定し、
- これを API仕様; API specification と呼ぶことが多い
- 規定したリクエストに対応する機能を実現しつつ、
- 規定したとおりの応答を行うよう、プログラムを実装する
- この際、どのようなAPI仕様とするか、全くオリジナルに考えるのは苦労が多い。
- 何らかの指針があったほうが開発者としては嬉しいし、
- 利用者側としても異なるサービス間で大まかな指針が共通していれば、理解が早い
- コードの共有を図れる可能性も上がる
- いくつかのAPI設計パターンが提唱されており、用途や適正に合わせて利用される
- RESTful
- 「リソースに対する操作」を、
- 「HTTPで定義済みのMethodを活用して表現」する、
- 「ステートレス; Stateless」(後述)なプロトコル設計思想
- 厳密なものから「なんちゃって」まで含めると、非常に幅広くWeb APIで利用されている
- Bodyの形式(IDL; Interface Description Language)としては XML や JSON を使うことが多い
- 問題点もある
- 表現力が限定的。「リソース」と「それに対する操作」では表現しにくい処理も多くある
- Bodyの形式を厳密に定義するための スキーマ言語; Schema Language とセットになっていない
- IDLごとに一応存在するが、使いにくかったり、表現力が低かったりすることもある
- 結果、API spec/documentationの形式がバラバラになったり、コード自動生成がしづらかったり
- 複数の処理を組み合わせるための統一的な手法がない
- 複数のリソースへの処理を同時に行いたい場合に、複数のHTTPリクエストの発行が必要になりがち
- grpc
- HTTP 2.0 上で実現するプロトコル
- HTTP 2.0では一つのTCPコネクションを維持した上で、その中で複数のHTTPリクエストを往復させられる
- IDLとして Protocol Buffer (protobuf) を用いる。 スキーマ言語を同梱
- RPC; Remote Procedure Call は、その名の通り遠隔サーバ上に命令を送ること、及びその形式
- RPCと名乗るプロトコルの場合:
- アプリケーションサーバ側で実行されるべき処理内容をより具体的に表現したリクエスト形式であることが多い
- 別のプロトコルを、そのRPCのリクエストを転送するための手段としてだけ用いる(transport protocol)
- 例) grpcでは、HTTP 2.0をtransport protocolとして利用するが、
一旦接続が確立されたら、処理内容を決めるのはあくまでprotobufで記述されたBodyの中身のみ
- 転送経路を確立したあとは、利用するのはbodyだけなので、URLはただ一つであることが多い
- Transport protocolは交換可能であることも多い。HTTP 1.1/2.0, Websocket, Raw TCP
- じわじわと利用が広がっている
- GraphQL
- Query と Mutation という枠組みでリソースに対する操作を表現する方式
- RESTfulの抱えるいくつかの問題に対するアンサーとなっており、
- 複数の処理の組み合わせ記述、
- スキーマ言語、
- 取得する情報の絞込み、などの特長を備える
- 多くはHTTP 1.1上で実現されるが、こちらもRPC的なインターフェイス(bodyですべてを表現)であるため、
原理的にはtransport protocolはなんでも良い
- ところどころ使われてはいる
状態、ステート、State
- という言葉がすでに出てきている
- ステートフル; Stateful なプロトコルは、クライアントとサーバの間で何らかの順序・手順に基づいた情報交換がなされ、
全体として正しく処理が実施されるかは、それまでの処理の結果(=状態)に依存する
- ステートレス なプロトコルは、各リクエストがそれぞれ独立しており、それまでの処理の結果によらない
- HTTPに乗っかっている、アプリケーション(API)レイヤでは:
- 大抵の場合いわゆる「ログイン状態」のような、
- 本人認証が完了しており、
- 有効期限内の認証トークンが発行されている期間(セッション; session)を意味する概念がある
- セッション制御は、どうあがいても本質的には ステートフル である
- サーバ側かクライアント側、どちらかに状態を必要とする。さもなければ毎リクエスト個別に認証しなければならない
- それ以外にもアプリケーションは 状態の宝庫 である
- 電子商取引; E-Commerce システムでは、「買い物かご」や「口座」といった概念は頻出
- RESTfulの指針の一つに「ステートレス」があるものの、これをうまく捉えるのははっきり言って難しい
- 個人的に新人の頃の理解の助けになったのは以下のブログ記事
- 「長期的に永続化されるリソースの状態」と、
「短期的にクラサバ間で共有するアプリケーションの状態」を分けて考える方が良い
- RESTfulがAPI設計によって分離しようとする「状態」はどちらかというと後者
- この辺は実際に製品開発を行いながら感覚を培って欲しい
- ついでなので言葉だけ挙げておくと、 冪等性; idempotency という概念もAPI設計において重要になる