web-dev-qa-db-ja.com

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

次の形式のURLがあります

/ instance/{instanceType}/{instanceId}

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

DRAFT、VALIDATE、CURATEなどのカスタムHTTPメソッドを使用できると考えました

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

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

そして、WebDavのようなツールは、独自の拡張機能のいくつかを作成します。

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

34
Juan Mendes

HTTPの基本的な制約の1つと、theRESTの中心的な設計機能は、均一なインターフェースは、(とりわけ)すべてのリソースに普遍的に適用されるメソッドの小さな固定されたセットによって提供されます。均一なインターフェースの制約には、多くの利点と欠点があります。私は引用していますfrom Fielding 自由にここに。

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

  • 簡単です。
  • 提供するサービスから実装を切り離します。
  • hTTPロードバランサー(nginx)やキャッシュ(ワニス)などのレイヤードアーキテクチャを許可します。

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

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

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

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

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

41
Rein Henrichs

これらをサブリソースとして設計し、その上で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要求への要求中に発生する必要があることについて非常に明確にすることができます。そこに投稿されるリソースには、詳細な引数を含めることができますおそらく、状態遷移を引き起こすイベント。

リソースで考えられる状態間を移動する「素朴な」アプローチを採用すると、これらの遷移の原因となったイベントを取得できないという欠点があります。

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

8

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

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

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

6
Robert de W