web-dev-qa-db-ja.com

APIでPOST HTTP動詞のみを使用している理由は何ですか?

作成中のWebサービスのAPIの作業を始める前に調査しています。目標は、他の開発者にとって非常に迅速かつ簡単に適応して使用できるようにすることですが、APIの背後にあるサービスへの呼び出しを行うためにWebappsのコレクションを使用するクライアントにはかなり隠されています。

内部で使用する以上のAPIを作成するのは初めてであり、私は RESTful の推奨に従うべきか、むしろPOSTリクエストと、必要なすべての情報を保持するJSONボディ。

GET/ HTTP-Verbsの使用に対する私の推論

  • このサービスは、すべての単一のユーザーおよびDBアイテムに対してかなり細かい読み取り/書き込み制御を備えています。そのため、単純なLISTリクエストでも資格情報だけでなく、クライアントがこの特定のデータについてこの質問をすることを許可されているかどうかを確認するために、一連の内部検証手順を実行する必要があります。
  • 簡単な実装:コーディング中、JSONペイロードを取得するために、GET UrlsとPOSTまたはPUT本文の間でホップする必要がないのは通常嬉しいことです。行。GETリクエストの場合はURLに追加し、POSTまたはPUTの場合は本文に追加します。したがって、POSTを使用するだけで手間がかかりません。それは誰にとっても真実ではなく、私の個人的な好みです-私は怠惰です;-)
  • とにかくSSLを使用しているため、実際には有効なポイントではありませんが、 https://stackoverflow.com/questions/198462/is-one-get-or-post-more-secure-than-the-other#1744404 は、少なくとも理論的には、あまり機密性の高いものをURLに押し込まない方が少し安全かもしれないことを示唆しています。特に、READ/LISTリクエストでさえサービスに対して機密であると考えられる場合、URL内で動作することは少なくとも少し奇妙に感じられます。

GETを使用する理由/ HTTP-Verbs

  • 互換性:標準は素晴らしいです。そして、RESTful APIは依然として最も一般的なもののようです。 GETは、ブラウザーからクライアントが簡単にテストまたは使用できます(それが本当にプラスであるかどうかはわかりませんが、1つになるかもしれません)。
  • RESTfulは、URLだけでなくHTTP動詞(GET/POST/PUTなど)を介して、細かい懸念の分離を強制します。 POSTを使用するだけで、URLまたは初期のJSON解析を通じて同じことができます。
  • これ blogpost は問題について少し説明します、私はとても役に立ちました

たとえば、RESTの原則が示唆するように、さまざまなHTTP動詞を使用する他の強力な理由はありますか?

異なるHTTP動詞を使用しないAPIが見つかりません。そのためには、非常に強い理由があるに違いないと思います。私は blogpost で言及されている理由が最も関連性があると思いますが、それ以上のものがあるか、そこで提案されているもの以外の解決策があるかどうか疑問に思います(最初のPOST、次に新しいGETableリソースを提供)そしてURLを返す)

この質問は私のものに似ていますが、少し異なる角度から来ます: POST APIのみで使用するのは悪いことですか?

9
gauguerilla

"APIでPOST HTTP動詞のみを使用する理由は何ですか?"

あなた自身の質問に答えました:

目標は、他の開発者のために非常に迅速かつ簡単に適応して使用することです...

他の開発者がAPIをすばやく理解して使用することが目標である場合は、ほとんどの開発者が期待する一般的に受け入れられている方法を使用してください。それはそれと同じくらい簡単です。

POSTを使用する理由を確認するには:

  • リスト操作でPOSTを使用するのは非常に奇妙だと思います
  • APIの実装の遅延は、他の開発者がAPIを使い始めたときに直接的なコストがかかり、なぜすべての操作でPOSTが必要になるのか不思議に思います
  • GETを使用する場合の仮想的なセキュリティリスクは、標準の議論よりはるかに重要です

自分だけが使用するAPIを試してみたい場合は、自由に何でもしてください。しかし、他の開発者にそれを使用させたい場合は、私たちのフラストレーションを救い、標準をそのまま使用してください。

11
Dan Wilson

GETリクエストは、日付の投稿に使用する場合はべき等であると想定されているため、これに違反し、APIのユーザーには予期されません。

5
Rob

APIを使用する開発者が簡単にできるようにする場合は、さまざまな動詞のRESTful性について心配する必要はありません。

クライアントを公開

クライアントを公開する場合、GETまたはPOSTは誰も気にしない実装の詳細です。開発者に独自のクライアントの作成を強制する場合は、ドキュメントを読んで、それがGETかどうかを確認する必要があります。またはPOST。

4
Ewan

ここに comment を追加しましたが、回答の中で推論について詳しく説明したいと思いました。

APIについて話すとき、通常はリモートAPI、特にHTTP REST APIsを意味します。ただし、APIはアプリケーションプログラミングインターフェースを意味するため、クラス/関数(ライブラリ)のコレクションを意味するだけかもしれません。

私の意見では、リモートAPIは基本的にリモートでアクセスされるAPIであり、「ローカル」API(ライブラリ)と同様に設計する必要があります。

ライブラリに明確に定義されたメソッド(適切に選択された名前とパラメーター)が含まれている場合は、リモートAPIも同様に設計する必要があります。

ライブラリAPIにはHTTPメソッドの概念がなく、名前とパラメーターのみがあるため、リモートAPIではHTTPメソッドを無視して、各エンドポイント(メソッド)に適切な名前とパラメーターを使用できると思います。

HTTPメソッドの場合、POSTを選択する必要があるので、POSTを選択します。POSTは、ボディを許可する最も一般的なメソッドです。

ライブラリメソッドは次のようになります。

class Documents {
  DocumentSearchResult findDocuments(DocumentFilter);
}

同等のリモートAPIメソッドは次のとおりです。

@Path("documents")
class Documents {
  @POST @Path("findDocuments")
  @Consumes(MediaType.APPLICATION_JSON)
  @Produces(MediaType.APPLICATION_JSON)
  DocumentSearchResult findDocuments(DocumentFilter);
}

リモートAPIは@Pathを介してクラス/インスタンスおよびメソッド名を公開する必要があることに注意してください。たぶんフレームワークがこれを自動的に処理できるので、@Path@POSTも(あるいはMediaTypeも)必要ありません。しかし、それは別の話です。とにかく、その場合、リモートAPIは次のように宣言されます(そう、ローカルライブラリインターフェースのように)。

class Documents {
  DocumentSearchResult findDocuments(DocumentFilter);
}

これらのメソッドを呼び出すときは、次のようにします。

// Local library API usage (pseudo-code, looks like Java)
DocumentSearchResult result = documents.findDocuments(filter);

// Remote API usage (pseudo-code, looks like Dart)
DocumentSearchResult result = await http.post("documents/findDocuments", body: filter);

それを無視したいので、POSTを実行していることを隠すこともできます。そのため、これらのhttp呼び出しを次のようなヘルパー関数でラップして、ローカルAPI呼び出しにさらに類似させることができます。

// Remote API usage using helper function (pseudo-code)
DocumentSearchResult result = await call("documents.findDocuments", filter);

このポイントに到達したら、さらに一歩進めて、このリモート呼び出しをラップするクラスを作成し、これを行うことができます(そう、ほとんどローカルライブラリ呼び出しのように)。

// Remote API usage using helper class (pseudo-code)
DocumentSearchResult result = await documents.findDocuments(filter);

これは手動で、またはコードジェネレータプラグインによって実行できます。しかし、それは別の話です。

2
Ferran Maylinch

POSTであり、PUTエンドポイントはCurlまたはブラウザのアドレスバーを使用してテストするのが少し厄介です。それは大きな問題ではないことを認めますが、GETを許可しても問題ないことを例示しています。それが得意なことをしてください。

0
user1172763