web-dev-qa-db-ja.com

REST GETの代わりにPOSTを使用するAPI

サービスが次のように使用できる機能を提供すると仮定します。

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

POSTクエリで使用できると言うのは正しいですか?

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

これらの2つのクエリは同じですか?いずれの場合でも2番目のバリアントを使用できますか、ドキュメントでGETクエリとPOSTクエリの両方を使用できることを明示的に記載する必要がありますか?

50
hank

これらのメソッドを個別に使用して呼び出すようにビルドされていない場合、APIまたはPOSTを使用してGETを使用することはできません。あなたのAPIが言うなら

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

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

一般に、POSTメソッドでは、_のexのcontent-typeヘッダーで説明されている、指定された形式でコンテンツを本文で送信する必要があります。 JSONデータのapplication/json

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

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

32
Sachin

確認するために、RESTには、開発者がそれを作成するために従うべき特定のプロパティがありますRESTful

RESTとは何ですか?

ウィキペディアによると:

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

  • Client–server:サーバーはユーザーインターフェイスやユーザー状態に関係しないため、サーバーをよりシンプルでスケーラブルにできます。
  • Stateless:クライアントとサーバーの通信は、リクエスト間でサーバーに保存されるクライアントコンテキストがないため、さらに制約されます。
  • Cacheable:応答は、暗黙的または明示的に、それ以降の要求に応答してクライアントが古いデータや不適切なデータを再利用するのを防ぐために、自身をキャッシュ可能として定義する必要があります。
  • 階層化システム:クライアントは、通常、エンドサーバーに直接接続されているか、途中で仲介者に接続されているかを判断できません。中間サーバーは、負荷分散を有効にし、共有キャッシュを提供することにより、システムのスケーラビリティを改善できます。
  • オンデマンドのコード(オプション):サーバーは、実行可能コードの転送により、クライアントの機能を一時的に拡張またはカスタマイズできます。
  • ユニフォームインターフェース:以下で説明するクライアントとサーバー間のユニフォームインターフェースは、アーキテクチャを簡素化および分離し、各部分が独立して進化できるようにします。 (つまり、HTTP GET、POST、PUT、PATCH、DELETE)

動詞がすべきこと

SOユーザーDaniel Vasalloは、質問でこれらのメソッドの責任を適切にレイアウトしましたRESTの理解:動詞、エラーコード、および認証

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

GET:コレクションのメンバーを一覧表示し、さらにナビゲーションするためにメンバーURIを付けます。たとえば、販売されているすべての車をリストします。

PUT:「コレクション全体を別のコレクションに置き換える」と定義される意味。

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

DELETE:「コレクション全体を削除する」という意味。

だから、あなたの質問に答えるために:

POSTクエリで使用できると言うのは正しいですか? ...

これら2つのクエリは同じですか?いずれの場合でも2番目のバリアントを使用できますか、ドキュメントではGETクエリとPOSTクエリの両方を使用できることを明示的に記載する必要がありますか

単純な古いRPC API呼び出しを記述している場合、処理サーバー側が両方の呼び出しで違いがなければ、技術的に交換可能です。ただし、呼び出しをRESTfulにするには、GETメソッドを介してエンドポイントを呼び出すには、POSTメソッド(新しいリソースを作成する)とは異なる機能(リソースを取得する)が必要です。

サイドノート:POSTもリソースの更新に使用できるかどうかについては、いくつかの議論があります...私はそれについてコメントしていませんが、私はあなたにいくつかを伝えています人々はその点に問題があります。

57
Kristian

POST bodyを使用するのは、以下の理由から、重要なアプリケーションや基幹業務用のアプリではありません

  1. セキュリティ-クエリ文字列とhttpsでGETを使用する場合、クエリ文字列をサーバーログに保存し、参照リンクとして転送できます。これらの両方は、サーバー/ネットワーク管理者と、アプリを離れた後にユーザーがアクセスした次のドメインに表示されます。したがって、顧客の名前などの機密PIIデータを含むクエリを送信する場合、これは望ましくない場合があります。
  2. URLの最大長-大きな問題ではありませんが、一部のブラウザーでは長さに制限があります。そのため、クエリ、ページング、返すフィールドなどのURLに複数のアイテムがある場合...
  3. デフォルトでは、投稿はキャッシュされません。キャッシングが望ましいと言う人もいます。ただし、とにかくキャッシュがタイムアウトする前に発生する正確な顧客の正確なオブジェクトの検索条件のまったく同じセットはどれくらいの頻度ですか?

ところで、フィールド名を公開したくないので、POST本文に返すフィールドも配置します。セキュリティはタマネギのようなものです。多くの層と私たちは泣きます!

38
Scott Peal

考えてみてください。クライアントがURI Xに対してGETリクエストを行うと、サーバーに対して言っていることは、「Xにあるリソースの表現が必要です。この操作はサーバー上の何も変更すべきではありません。」 PUTリクエストは、「Xにあるリソースを、このリクエストの本文で提供している新しいエンティティに置き換えてほしい」と言っています。 DELETEリクエストは、「Xにあるリソースをすべて削除してほしい」と言っています。パッチは「この差分を提供しています。Xのリソースに適用して、成功したかどうかを教えてください」と言っています。しかし、POSTは次のように言っています。「私はこのデータをXのリソースに従属させて送信しています。これで何をすべきかについて、以前の合意があります。」

リソースがPOSTを期待してそれを処理することを文書化していない場合、POSTを次のように動作することを期待して送信することは意味がありません。 GET。

RESTは、基盤となるプロトコルの標準化された動作に依存します。POSTは、標準化されていないアクションに使用されるメソッドです。 GET、PUT、およびDELETE要求の結果は標準で明確に定義されていますが、POSTは定義されていません。 POSTの結果はサーバーに従属するため、POSTを使用して何かを実行できることが文書化されていない場合は、できないと想定する必要があります。

9
Pedro Werneck

RESTがHTTP動詞(定義どおり)に意味をもたらすのは素晴らしいことですが、Scott Pealに同意することを好みます。

また、WIKIの POSTリクエスト に関する拡張説明の項目もあります。

HTTP GETは、データの取得にも適さない場合があります。この例は、URLで大量のデータを指定する必要がある場合です。ブラウザとWebサーバーは、切り捨てまたはエラーなしで処理するURLの長さに制限を設けることができます。 URLおよびクエリ文字列の予約文字のパーセントエンコーディングは、文字列の長さを大幅に増やすことができます。ApacheHTTPサーバーはURLで最大4,000文字を処理できますが[5]、Microsoft Internet ExplorerはURLで2,048文字に制限されます。同様に、リクエストを完了するためにユーザー名やパスワードなどの機密情報を他のデータとともに送信する必要がある場合は、HTTP GETを使用しないでください。 HTTPSを使用している場合でも、転送中にデータが傍受されるのを防ぎ、ブラウザーの履歴とWebサーバーのログには完全なURLがプレーンテキストで含まれている可能性が高く、いずれかのシステムがハッキングされた場合に公開される可能性があります。これらの場合、HTTP POSTを使用する必要があります。[7]

RESTチームに提案することができたのは、HTTPプロトコルのより安全な使用を検討して、消費者が安全でない「グッドプラクティス」に苦しむのを避けることです。

4
user7071799

RESTでは、各HTTP動詞には場所と意味があります。

例えば、

  • GETは、URLで指し示されている「リソース」を取得することです。

  • POSTは、バックエンドを構造化して、URLでポイントされた「タイプ」のリソースを「作成」します。 POST操作の補足として、POST呼び出しの本文のパラメーターまたは追加データを使用できます。

あなたの場合、クエリを使用して情報を「取得」することに関心があるため、POST操作ではなくGET操作である必要があります。

これ wikiが役立つかもしれません 物事をさらに明確にします。

この助けを願っています!

3
Ming Chan