322

次のシナリオに適した方法で残りのエンドポイントを設計したいと考えています。

グループがあります。各グループにはステータスがあります。グループは、管理者がアクティブ化または非アクティブ化できます。

エンドポイントを次のように設計する必要があります

PUT /groups/api/v1/groups/{group id}/status/activate

また

PATCH /groups/api/v1/groups/{group id}

with request body like 
{action:activate|deactivate}
4

6 に答える 6

215

RESTのRはリソースを表します

(Representational の略であるため、これは正しくありませんが、REST におけるリソースの重要性を覚えておくには良い方法です)。

About PUT /groups/api/v1/groups/{group id}/status/activate: 「アクティブ化」を更新していません。「活性化」は物ではなく、動詞です。動詞は決して良いリソースではありません。経験則:アクション (動詞) が URL にある場合、おそらく RESTful ではありません

代わりに何をしていますか?グループのアクティベーションを「追加」、「削除」、または「更新」するか、必要に応じて、グループの「ステータス」リソースを操作します。個人的には、「アクティベーション」は「ステータス」という概念よりもあいまいではないため、「アクティベーション」を使用します。ステータスを作成することはあいまいですが、アクティベーションを作成することはあいまいではありません。

  • POST /groups/{group id}/activationアクティベーションを作成 (または作成を要求) します。
  • PATCH /groups/{group id}/activation既存のアクティベーションの一部の詳細を更新します。グループにはアクティベーションが 1 つしかないため、どのアクティベーション リソースを参照しているかがわかります。
  • PUT /groups/{group id}/activation古いアクティベーションを挿入または置換します。グループにはアクティベーションが 1 つしかないため、どのアクティベーション リソースを参照しているかがわかります。
  • DELETE /groups/{group id}/activationアクティベーションをキャンセルまたは削除します。

このパターンは、グループの「アクティブ化」に、支払いの実行、メールの送信などの副作用がある場合に役立ちます。POST と PATCH だけがこのような副作用を持つ可能性があります。たとえば、アクティベーションの削除でユーザーにメールで通知する必要がある場合、DELETE は適切な選択ではありません。その場合、おそらく非アクティブ化リソースを作成したいと思うでしょう: POST /groups/{group_id}/deactivation.

これらのガイドラインに従うのは良い考えです。この標準的なコントラクトにより、クライアント、およびクライアントとユーザーの間のすべてのプロキシとレイヤーが再試行しても安全な場合とそうでない場合を明確に把握できるためです。クライアントが不安定な wifi のある場所にあり、そのユーザーが「非アクティブ化」をクリックすると、DELETE次のようになります。それが失敗した場合、クライアントは、404、200、または処理できるその他の値を取得するまで、単純に再試行できます。しかし、それがトリガーされた場合、POST to deactivation再試行しないことがわかっています: POST はこれを意味します。
HTTP ライブラリがバックエンドへの呼び出しを再試行し続けたという理由だけで、「あなたのグループは非アクティブ化されました」という 42 通の電子メールの送信から保護されます。

単一属性の更新: PATCH を使用

PATCH /groups/{group id}

属性を更新したい場合。たとえば、「ステータス」は、設定可能なグループの属性である可能性があります。「ステータス」などの属性は、多くの場合、値のホワイトリストに限定するのに適した候補です。例では、いくつかの未定義の JSON スキームを使用しています。

PATCH /groups/{group id} { "attributes": { "status": "active" } }
response: 200 OK

PATCH /groups/{group id} { "attributes": { "status": "deleted" } }
response: 406 Not Acceptable

副作用なしでリソースを置き換えるには、PUT を使用します。

PUT /groups/{group id}

グループ全体を交換したい場合。これは必ずしも、サーバーが実際に新しいグループを作成し、古いグループを破棄することを意味するわけではありません。たとえば、ID が同じままである可​​能性があります。しかし、クライアントにとっては、これが PUT意味です。クライアントは、サーバーの応答に基づいて、まったく新しいアイテムを取得したと想定する必要があります。

クライアントは、PUTリクエストの場合、新しいアイテムを作成するために必要なすべてのデータを含むリソース全体を常に送信する必要があります。通常、POST-create が必要とするデータと同じデータです。

PUT /groups/{group id} { "attributes": { "status": "active" } }
response: 406 Not Acceptable

PUT /groups/{group id} { "attributes": { "name": .... etc. "status": "active" } }
response: 201 Created or 200 OK, depending on whether we made a new one.

非常に重要な要件は、べき等であることです。PUTグループを更新する (またはアクティベーションを変更する) ときに副作用が必要な場合は、 を使用する必要がありますPATCH。そのため、更新の結果としてメールが送信されるなどの場合は、使用しないでくださいPUT

于 2016-05-31T11:36:40.263 に答える
13

リソース「グループ」には多くのプロパティがありますが、この場合、アクティブ化フィールドのみを更新しているため (部分的な変更)、PATCH を使用することをお勧めします。

RFC5789 による ( https://www.rfc-editor.org/rfc/rfc5789 )

既存の HTTP PUT メソッドでは、ドキュメントを完全に置き換えることしかできません。この提案は、既存の HTTP リソースを変更するための新しい HTTP メソッド PATCH を追加します。

また、詳しくは、

PUT 要求と PATCH 要求の違いは、サーバーが囲まれたエンティティを処理して
、Request-URI によって識別されるリソースを変更する方法に反映されます。PUT 要求では、同封されたエンティティは、
オリジン サーバーに格納されているリソースの変更されたバージョンと見なされ、クライアントは格納されているバージョン
を置き換えるように要求しています。
ただし、PATCH を使用すると、囲まれたエンティティには、現在オリジン サーバーに存在するリソースを変更して新しいバージョンを生成する方法を説明する一連の指示が含まれます。PATCH メソッドは、Request-URI によって識別されるリソースに影響を与え
ます。また、他のリソースに副作用がある場合もあります。つまり、新しいリソース
を作成したり、既存のリソースを変更したりできます。
パッチ。

[RFC2616] のセクション 9.1 で定義されているように、PATCH は安全でも冪等でもありません。

クライアントは、PUT ではなく PATCH をいつ使用するかを選択する必要があります。たとえば、パッチ ドキュメントのサイズが 、PUT で使用される新しいリソース データ
のサイズよりも大きい場合、 PATCH の代わりに PUT を使用する方が適切な場合があります。 POST はさまざまな方法で使用され、サーバーが選択した場合は PUT や PATCH のような操作を含めることができるため、POST との比較はさらに困難です。操作が Request-URI によって識別されるリソースを予測可能な方法で変更しない場合は、PATCH または PUT の代わりに POST を考慮する必要があります。




PATCH の応答コードは次のとおりです。

204 応答コードが使用されるのは、応答にはメッセージ本文が含まれていないためです (200 コードの応答にはメッセージ本文が含まれます)。他の成功コードも使用できることに注意してください。

http://restcookbook.com/HTTP%20Methods/patch/ も参照してください。

警告: PATCH を実装する API は、アトミックにパッチを適用する必要があります。GET によって要求されたときにリソースが半分パッチされる可能性があってはなりません。

于 2016-06-20T12:13:17.447 に答える