GETではなくPOSTを使用するREST API

あるサービスが、このように使える機能を提供しているとします。

GET /service/function?param1=value1&param2=value2

これをPOSTクエリで使えると言っていいのでしょうか?

POST /service/function { param1 : value1, param2 : value2 }

この2つのクエリは同じものですか?どのような場合でも2つ目のバリエーションを使用することができますか?あるいは、ドキュメントにはGETとPOSTの両方のクエリを使用できることを明示すべきでしょうか?

おさらいですが、RESTには、RESTfulにするために、開発者が従うべき一定の性質があります。

RESTとは?

wikipediaによると。

RESTのアーキテクチャスタイルは、以下の6つの制約を記述しています。 アーキテクチャに適用され、個々のコンポーネントの実装は 個々のコンポーネントは自由に設計することができます。

  • Client-server: サーバーはユーザーインターフェースやユーザーの状態を意識しないため、サーバーはよりシンプルでスケーラブルなものになります。
  • Stateless: クライアントとサーバー間の通信は、リクエスト間でサーバーにクライアントのコンテキストが保存されないことで、さらに制約を受けます。
  • Cacheable: レスポンスは、暗黙的または明示的に、キャッシュ可能か否かを定義しなければならず、クライアントが古いデータや不適切なデータを再利用することを防ぎます。 クライアントは、エンドサーバーに直接接続されているのか、それとも途中の中間サーバーに接続されているのか、通常はわかりません。中間のサーバーは、負荷分散や共有キャッシュを提供することで、システムのスケーラビリティを向上させることができます。
  • Code on demand (optional):サーバーは、実行可能なコードを転送することで、クライアントの機能を一時的に拡張またはカスタマイズすることができます。
  • 統一インターフェース: 後述するクライアントとサーバー間の統一インターフェースにより、アーキテクチャが単純化、切り離され、各部分が独立して進化することが可能となる。(例:HTTP GET, POST, PUT, PATCH, DELETE)

動詞がすべきこと

SOユーザーのDaniel Vasalloは、Understanding REST: Verbs, error codes, and authenticationという質問の中で、これらのメソッドの責任についてうまく説明しています。

http://example.com/resources/ のようなコレクションURIを扱う場合。

GET: コレクションのメンバーをリストアップし、そのメンバーを完全に表示します。 GET:** コレクションのメンバーを、メンバーのURIとともにリストアップします。例えば、販売されているすべての車をリストアップします。

PUT: "replace the entire collection with another > collection" と定義されています。 コレクションに置き換えてください。

POST: IDがコレクションによって自動的に割り当てられているコレクションに新しいエントリを作成します。 コレクションに新規エントリを作成します。作成されたIDは、通常、返されるデータの一部として この操作で返されるデータの一部として含まれます。

DELETE: "コレクション全体を削除する"と定義されています。

では、ご質問にお答えします。

POSTクエリで使えるということでよろしいでしょうか ...

この2つのクエリは同じものですか?どのような場合でも2つ目のバリアントを使用できるのでしょうか、それともドキュメントにGETとPOSTの両方のクエリを使用できると明示すべきでしょうか?

もしあなたが普通のRPC APIコールを書いていたとしたら、サーバー側の処理がどちらのコールでも変わらない限り、技術的には交換可能です。しかし、RESTfulであるためには、GETメソッドによるエンドポイントの呼び出しは、POSTメソッド(新しいリソースを作成する)とは異なる機能(リソースを取得する)を持つ必要があります。

余談ですが、POSTをリソースの更新に使用することも許可すべきかどうかについては、いくつかの議論があります...私はそれについてコメントしていませんが、その点について問題がある人がいることをお伝えしているだけです

解説 (1)
ソリューション

API」を「POST」や「GET」を使って使用することは、これらのメソッドを個別に使用して呼び出すように構築されていない場合はできません。例えば、あなたのAPIが

/service/function?param1=value1&param2=value2

GET メソッドを使用してアクセスされた場合のように。例えば、{{22844074}}のようなAPIがGETメソッドでアクセスされている場合、作成者によってPOSTメソッドとして指定されていなければ、POSTメソッドで呼び出すことはできません。そのようなことをすると、405 Method not allowedというステータスが発生する可能性があります。

通常、POSTメソッドでは、content-typeヘッダーに記述されている特定のフォーマットでコンテンツをボディに送信する必要があります。例えば、jsonデータの場合は application/json となります。

そしてその後、リクエストボディはサーバ側でシリアル化されます。そのため、クライアントからシリアライズされたデータを渡す必要がありますが、それはサービス開発者によって決定されます。

しかし一般的には、GETはサーバーがクライアントに何らかのデータを返し、サーバーに影響を与えない場合に使用されるのに対し、POSTはサーバーに何らかのリソースを作成する場合に使用されます。ですから、一般的には同じであってはいけません。

解説 (1)

RESTでは、それぞれのHTTP動詞には場所と意味があります。

例えば、以下のようなものです。

  • GET は、URL で指し示された 'Resource(s)'を取得することです。

  • POSTは、URLで指し示された 'type'のリソースを 'create'するようにバックエンドを指示します。 POST操作には、POSTコールのボディにパラメータや追加データを入れることができます。

あなたの場合、クエリを使用して情報を 'get'することに興味があるので、POST操作ではなくGET操作にする必要があります。

この wiki may help を参考にすると、より明確になります。

ご参考になれば幸いです。

解説 (0)