カスタムHTTPメソッドの実装に問題はありますか?


34

次の形式のURLがあります

/ instance / {instanceType} / {instanceId}

標準のHTTPメソッドで呼び出すことができます:POST、GET、DELETE、PUT。ただし、「下書きとして保存」や「キュレート」など、いくつかのアクションがあります

ドラフト、検証、キュレートなどのカスタムHTTPメソッドを使用できると考えました

基準が言うので、これは許容できると思います

「HTTP / 1.1の共通メソッドのセットを以下に定義します。このセットは拡張できますが、追加のメソッドは、個別に拡張されたクライアントとサーバーで同じセマンティクスを共有することはできません。」

また、WebDavなどのツールは独自の拡張機能を作成します。

カスタムメソッドで誰かが遭遇した問題はありますか?プロキシサーバーとファイアウォールを考えていますが、他の懸念事項は大歓迎です。安全な側にとどまり、action = validate | curate | draftのようなURLパラメーターを設定するだけですか?


6
RFC 1925から再び引用したように、「プロトコル設計では、追加するものが何もないときではなく、奪うものが何もないときに完全に達しました。」-機能する場合、httpに追加する理由はありません。

4
現在、HTTPではなくカスタムプロトコルを使用していることを認識している限り、問題はありません。
user16764

10
@ user16764「HTTP / 1.1の共通メソッドのセットを以下に定義します。このセットは拡張できますが、追加のメソッドは、個別に拡張されたクライアントとサーバーで同じセマンティクスを共有するとは限りません。」w3.org/Protocols/rfc2616/rfc2616-sec9.htmlしたがって、許可され、HTTPのままです
フアンメンデス

メソッド定義では、HTTP / 1.1スコープ内でカスタムメソッドを使用することは既に許容されているが、同じセマンティクスを共有することは期待できないと記載されているため、@ MichaelTとJuan Mendesの両方からややなだめする
Prof83

回答:


42

HTTPの基本的な制約とのRESTの中央設計上の特徴である均一なインターフェース(とりわけ)によって提供されるすべてのリソースに普遍的に適用する方法の小さい、固定セット。統一されたインターフェイス制約には、多くの利点と欠点があります。私はここで自由にフィールディングから引用しています。

統一されたインターフェース:

  • より簡単です。
  • 提供するサービスから実装を分離します。
  • HTTPロードバランサー(nginx)やキャッシュ(ワニス)などを含む、階層化されたアーキテクチャを許可します。

一方、統一されたインターフェース:

  • 情報はアプリケーションのニーズに固有の形式ではなく、標準化された形式で転送されるため、効率が低下します。

トレードオフは「Webの一般的なケース向けに設計されている」ため、Webアーキテクチャの一般的な問題の多くに対する解決策を提供する大規模なエコシステムを構築できます。統一されたインターフェイスを守ることで、システムはこのエコシステムの恩恵を受けることができますが、それを壊すことはそれを難し​​くします。nginxのようなロードバランサーを使用することもできますが、現在はDRAFTとCURATEを理解するロードバランサーのみを使用できます。VarnishなどのHTTPキャッシュレイヤーを使用することもできますが、ドラフトとキュレートを理解するHTTPキャッシュレイヤーのみを使用できるようになりました。サーバー障害のトラブルシューティングの支援を誰かに依頼したいが、CURATE要求のセマンティクスを誰も知らない場合があります。新しいメソッドを理解して正しく実装するために、好みのクライアントまたはサーバーライブラリを変更するのは難しいかもしれません。等々。

これを表す正しい*方法は、リソース(または関連リソース)の状態変換としてです。投稿をドラフトするのではなく、そのdraft状態を変換するtruedraft、以前のドラフトバージョンへの変更とリンクを含むリソースを作成します。投稿をキュレーションせずに、その投稿を変換しますcurated状態をするtruecuration、投稿をキュレーションしたユーザーとリンクするリソースを作成します。

* RESTアーキテクチャの原則に最も厳密に従うという点で正しい。


負荷分散に関するコメントをありがとう、私は間違いなくそれを見ていきます。カスタムメソッドが受け入れられるかどうかを示すリソースを知っていますか?
フアンメンデス

2
カスタムメソッドがWEBDAVのような広くサポートされている拡張機能の一部である場合を除き(その場合でもそれほどではありません)、カスタムメソッドの利点は見当たりません。これらの変更を状態変換として扱うことをお勧めします。Webは、すでにある方法でうまく機能します。統一されたインターフェイス(PATCHなど)の一部として意味をなさない限り、実際に追加する正当な理由はありません。
ラインヘンリッヒス

5
HTTPサービスを自分で動作させる方法を設計することには利点があると思います。ただし、「追加のメソッドは同じセマンティクスを共有することは想定できません」-十分に公正ですが、それでもHTTP / 1.1スコープの一部であるため、ファイアウォール、プロキシ、ロードバランサなどがこの可能性を許可する必要があります。その後、彼らはHTTP / 1.1を適切に実装していないのですか?
Prof83

あなたはおそらく安っぽいPOVから正しいでしょう、しかし、私はなぜカスタム動詞が問題になるべきかを見ることができません。すべてのツールは、POSTのようにそれらを処理する必要があります。つまり、「リソースが変更される可能性があり、それは私たちが知っているすべてです」。
maaartinus

7

これらをサブリソースとして設計し、その上でPOSTリクエストを実行することをお勧めします。

あなたがでリソースを持って考えてみましょう/instance/type/1のようなリソース上で実行することができる「アクション」へのリンクのカップルを伝える私はそのリソースの表現を持っているだろう、/instance/type/1/draft/instance/type/1/curate。JSONでは、これは次のように簡単です。

{
    "some property":"the usual value",
    "state": "we can still inform the client about the current state",
    "draft": "http://server/instance/type/1/draft",
    "curate": "http://server/instance/type/1/curate"
}

これにより、curateメンバーが提供するリンクへのPOSTリクエスト中に、クライアントは何が起こる必要があるかについて非常に明確になります。そこに投稿されたリソースには、状態遷移を引き起こす可能性のあるイベントの詳細を示す引数を含めることができます。

リソースの可能な状態間を移動する「単純な」アプローチを採用すると、これらの遷移につながったイベントをキャプチャしないというデメリットがあります。

状態遷移は通常、特定のイベントに応答して発生します。クライアントに何かが特定の「状態」にあると判断させるのではなく、それらのイベントをキャプチャしたいのです。また、検証がずっと難しくなります。さらに、州自体の「引数」についても説明しない限り、「引数」をキャプチャすることはできません。そして、いくつかのコードが実際の状態遷移なしでそれらを変更し、検証が必要になると、すべてが厄介になり、すべてがすぐに混乱になります。


いい答えだ。状態遷移への引数を提供し、サーバーにこれらをカプセル化して管理させることが、最善のアプローチです。
トーマスW

私が現在いる会社(VMware)がこれを行っています。のGETは、次の/vms/some-idようなアクションへのリンクを返します。POST /vms/some-id/restartこれを使用して、アクションを有効にするか無効にするかを決定します。私はHATEOASと愛/憎しみの関係があります :)
フアンメンデス

実行されているアクションがリクエストの動詞である場合、ランダムクエリパラメーター、リソースパスセグメント、または本体プロパティである場合、非常に意味があります。
マシューホワイトニング

動詞にリンクすることはできません。
デイブヴァンデンアインデ

6

エンティティアクションを実装するには、カスタムHTTPメソッドが最適な方法だと思います。エンティティ本体(POST)にアクションを追加することは正しくないと思われますが、エンティティの一部ではありません(ただし、結果はエンティティに保存される場合があります)。また、カスタムHTTPメソッドプロキシを使用すると、エンティティ本体を解析する必要なく、プロキシがアクションを決定できます。

CRUDのようなもので、常にそれらを実装する必要がありますが、独自の特定のアクションセット(エンティティごと)もあります。それらを拡張する問題はどうなるのか、私には本当にわかりません。

また、@ Rein Henrichs「投稿を下書きせず、ドラフトの状態をtrueに変換するか、ドラフトリソースを作成します」は私には間違っているようです。draftsプロパティは、永続的ではない変換を行うため、状態を保存するために使用されるであろう。アクションは、必ずしも「状態」になるわけではなく、プロパティに保存されるわけでもありません。状態/変換ごとに個別のエンティティを作成すると、さらに曖昧になります。エンティティへの同じ参照(URI)を維持するようにしてください。


1
これは公正に意見の相違があるものの、公正なポイントであり、その背後にある理由を見ることができ、ダウン投票に同意しません(特に投票者からのコメントはありません)。PHPの例外処理を例に取りましょう。「ベストプラクティス」では、RuntimeExceptionとBadMethodCallExceptionのような実際のメッセージを無視して、特定の例外タイプを使用して例外の種類を提案します。では、カスタムメソッドの使用が既にHTTP / 1.1スコープの一部と見なされている場合、DRAFTの使用に対してこれほど広く議論されているのはなぜですか?そして、ロードバランサーとプロキシもこの可能性を本当に受け入れるべきです
Prof83
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.