POST だけ?こんな馬鹿げた API デザインの議論を終わらせよう
"POST だけ" API の神話を打ち破り、なぜそれが API デザイン原則の誤解に基づいているのかを説明し、RESTful と RPC のアーキテクチャスタイルの適切な使用事例を明確にします。
最近、"POST だけ" を使って API を設計するべきかどうかの議論が私の注意を引きました。この議論を掘り下げてみると、人々が争っている問題が無意味であるばかりでなく、多くの開発者が API デザインの本質を誤解していることも明らかになりました。今日は、API デザインの核心的な考え方に深く迫り、この議論が最初から存在するべきではない理由を見ていきましょう。
"POST だけ" の誤解
"POST だけ" を使って RESTful API 仕様を置き換えることを支持する開発者は、明らかに API デザインの最も重要な点を理解していません。彼らの主張は通常、以下のようなものです:
- 設計の簡素化: 1 つのメソッドですべてを処理できる
- セキュリティ: POST パラメータは URL に表示されない
- 柔軟性: POST は任意のデータ構造を送信できる
一見すると、これらの主張には一理あるように見えます。しかし、実際には、これは HTTP メソッドの選択と API デザインスタイルの混同、すなわち異なるレベルの問題を混同しているに過ぎません。POST は HTTP プロトコルの 1 つのメソッドに過ぎませんが、REST は API デザインのスタイルです。
API デザインの本質
具体的な API スタイルについて議論する前に、まず API デザインの核心的な目的が何であるかを理解する必要があります。優れた API は 次のようであるべきです:
- 明確で理解しやすい: 他の開発者(将来の自分自身も含む)が、各エンドポイントの目的を直感的に理解できる
- 一貫性がある: 一定の仕様に従い、学習コストを削減する
- 拡張性がある: バージョン管理や機能の拡張を簡単に行える
- 効率的である: パフォーマンスやリソースの利用効率を考慮する
RESTful API: HTTP メソッドの選択だけではない
RESTful API は多くの API デザインスタイルの中の 1 つであり、リソースとリソースに対する操作に焦点を当てています。簡単なブログシステムを例にして、RESTful APIがどのように設計されているかを見てみましょう:
-
すべての記事を取得:
-
特定の記事を取得:
-
新しい記事を作成:
-
記事を更新:
-
記事を削除:
この例では次のことがわかります:
- API は "記事" リソースを基盤に設計されています
- 異なる操作を表すために異なる HTTP メソッドが使用されています
- URL 構造は操作されているリソースを示しており、明確です
この設計アプローチによって、API はより直感的で自己説明的になり、開発者が各エンドポイントの機能を理解しやすくなります。
RPC: "POST だけ" の背後にある API スタイルを理解する
RPC (Remote Procedure Call) スタイルの API デザインの目的は、リモートサービス呼び出しをローカル機能の呼び出しのようにシンプルに見せることです。
興味深いことに、"POST だけ" を支持する人々は、実際には RPC スタイルを説明していることに気づいていないかもしれません。
RESTful API に比べて、RPC はリソースよりも操作そのものに重点を置いています。これが、RPC スタイルの API が通常 "動詞 + 名詞" 形式を使用する理由です。例えば getProduct(productId)
や createUser(userData)
です。
多くの RPC 実装では、すべての操作が通常同じエンドポイントに POST リクエストとして送信され、リクエストボディ内で特定の操作とパラメータが指定されます。これが "POST だけ" の考えが実際には RPC に近い理由です。
例えば、HTTP ベースの RPC スタイルでの "商品の取得" リクエストは次のようになります:
現代の RPC フレームワーク(例えば gRPC)は、より強力で効率的な実装を提供しています。これを例にして RPC スタイルを説明しましょう:
まず、サービスとメッセージ形式を定義します(Protocol Buffers を使用):
次に、Node.js クライアントでこのサービスを使用するのは、ローカル関数を呼び出すように簡単です:
この RPC スタイルの例では、次のことがわかります:
- サービス定義が利用可能なすべての操作を明確にリストしています(この簡略化された例では
GetArticle
とCreateArticle
)。 - 各操作には明確に定義されたリクエストとレスポンスのタイプがあります。
- クライアントコードは、非同期のローカル関数を呼び出すように見えます。
await
を使用して結果を待機し、ネットワーク通信の複雑さをさらに隠しています。 - 手動で HTTP リクエストを構築したり、JSON レスポンスを解析したりする必要はありません。
潜在的に HTTP/2 をトランスポートプロトコルとして使用している場合がありますが、RPC フレームワーク(例えば gRPC)は、リモート呼び出しをローカル関数呼び出しのように見せる抽象化層を提供します。
したがって、"POST だけ" と RESTful API に関する議論の多くは、実質的にこれら 2 種類の API スタイル、すなわち REST と RPC に関する議論であることがわかります。しかし、重要なのは、これら 2 種類のスタイルがそれぞれの適用シナリオを持ち、選択はプロジェクトの具体的なニーズに基づいて行われるべきだということです。個人的な好みで選んではいけません。
REST vs RPC: 絶対的な優劣はない
REST と RPC の違いを理解したところで、それぞれの適用シナリオを見てみましょう:
- REST は次のような場合に適しています:
- リソース指向のアプリケーション(例えば、コンテンツ管理システム、ブログプラットフォーム、E コマースウェブサイト)
- 優れたキャッシュサポートが必要なシナリオ(GET リクエストは自然にキャッシュ可能です)
- HTTP のセマンティクスを有効活用したいプロジェクト(適切なステータスコードの使用など)
- 発見性や自己説明が求められる公開 API
- RPC は次のような場合に適しています:
- アクション指向のアプリケーション(例えば、複雑なデータ処理操作、ワークフローコントロール)
- 高性能で低遅延が求められるシステム(例えばリアルタイム取引システム)
- 内部マイクロサービス間の通信(より柔軟なパラメータ伝達が必要かもしれません)
- 操作が単純に CRUD(Create, Read, Update, Delete)操作にマッピングできない場合
スタイルの選択はあなたの具体的なニーズに基づくべきです。場合によっては、違うパーツのニーズに応じて、同じシステム内でこれら 2 種類のスタイルを混在させることさえあります。
結論
- API デザインの核心は、特定のメソッドやスタイルを固守することではなく、明確さ、一貫性、拡張性、効率にあります。
- RESTful と RPC のどちらも成熟した API デザインのパラダイムです。選択はプロジェクトの要件に基づいて行われるべきで、個人的な好みに基づくべきではありません。
- "POST だけ" を使用することを決定した場合は、RPC スタイルに従って API を設計してください。RESTful のように、それは業界でよく使用されている API 仕様ですが、適切なシナリオで 使用されるべきです。
- 表面的な技術的細部に惑わされないでください。重要なのは、あなたの API が効果的にユーザーやビジネスニーズに応えることができるかどうかです。
- API を設計する際には、どの HTTP メソッドを使用するかにこだわるのではなく、リソースモデル、ビジネスロジック、ユーザーのニーズについてもっと考える時間を費やしましょう。
こうした無意味な議論から注意を逸らし、本当に優れた API を設計することに集中しましょう。結局のところ、テクノロジーは問題を解決するためのものであり、それを作り出すためのものではありません。