web-dev-qa-db-ja.com

REST APIパッチまたはPUT

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

グループがあります。各グループにはステータスがあります。グループは管理者によって有効化または無効化できます。

私は自分のエンドポイントを次のようにデザインすべきです

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

OR

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

with request body like 
{action:activate|deactivate}
234
java_geek

既存のリソース、つまりグループIDを更新しているので、ここではPATCHメソッドが正しい選択です。 PUTは、をリソース全体に置き換える場合にのみ使用してください。

部分的なリソース修正に関するさらなる情報は RFC 5789 で利用可能です。具体的には、PUTメソッドは次のように記述されています。

ハイパーテキスト転送プロトコル(HTTP)を拡張するいくつかのアプリケーションは部分的なリソース修正をする機能を必要とします。既存のHTTP PUTメソッドでは、ドキュメントを完全に置き換えることしかできません。この提案は、既存のHTTPリソースを変更するための新しいHTTPメソッドPATCHを追加します。

282
Luke Peterson

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

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

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

代わりに何をしていますか?グループ上で activation を "追加"、 "削除"、または "更新"している場合、またはグループの "status"リソースを操作している場合。個人的には、「ステータス」という概念よりも曖昧さが少ないので、「アクティベーション」を使用します。ステータスの作成は曖昧ですが、アクティブ化の作成はそうではありません。

  • 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を使用していて、そのユーザーが "deactive"をクリックすると、DELETEがトリガーされます。しかし、もしそれがPOST to deactivationをトリガーするなら、それは再試行しないことを知っています:POSTはこれを意味します。
どのクライアントにも契約があり、それに従うと、そのHTTPライブラリがバックエンドへの呼び出しを再試行し続けたという理由だけで、42の電子メール「あなたのグループは非アクティブ化されました」.

単一の属性を更新する:PATCHを使う

PATCH /groups/{group id}

あなたが属性を更新したい場合。例えば。 "status"は設定可能なグループの属性になります。 "status"などの属性は、値のホワイトリストに限定するのに適した候補です。例では未定義の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 can の意味です。クライアントは、サーバーの応答に基づいて、まったく新しい項目を取得したと想定する必要があります。

クライアントは、PUTリクエストの場合、常に新しいアイテムを作成するのに必要なすべてのデータを持つリソース全体を送信するべきです:通常はPOST作成と同じデータが必要です。

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が冪等であるということです:もしあなたがGroupを更新する時(あるいはアクティベーションを変更する時)に副作用が必要なら、PATCHを使うべきです。そのため、更新の結果がメールを送信するには、PUTを使用しないでください。

157
berkes

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

rFC5789に準拠( https://tools.ietf.org/html/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はさまざまな方法で使用されているため、POSTとの比較はさらに困難です。
は、サーバーが選択した場合のPUTおよびPATCHのような操作を含みます。もし
操作はRequest-URIによって識別されるリソースを予測可能な方法で変更しません、POSTはPATCHの代わりに考慮されるべきです
またはPUT。

PATCHの応答コードは

レスポンスはメッセージボディ(200コードのレスポンスは持つ)を運ばないため、204レスポンスコードが使用されます。他の成功コードも使用できることに注意してください。

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

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

11

RESTアーキテクチャースタイルを使用してAPIを設計したいので、ユースケースを考慮して、どの概念がリソースとして公開するのに十分重要かを判断する必要があります。グループのステータスをサブリソースとして公開することにした場合は、次のURIを指定してGETメソッドとPUTメソッドの両方のサポートを実装できます。

/groups/api/groups/{group id}/status

修正のためのPATCHに対するこのアプローチの欠点は、グループの複数のプロパティにアトミックおよびトランザクション的に変更を加えることができないことです。トランザクションの変更が重要な場合は、PATCHを使用してください。

状況をグループのサブリソースとして公開することにした場合、それはグループの表現内のリンクになるはずです。たとえば、エージェントがグループ123を取得してXMLを受け入れる場合、レスポンスボディには次のものが含まれます。

<group id="123">
  <status>Active</status>
  <link rel="/linkrels/groups/status" uri="/groups/api/groups/123/status"/>
  ...
</group>

ハイパーリンクは、RESTアーキテクチャスタイルの アプリケーション状態のエンジンとしてのハイパーメディア 条件を満たすために必要です。

7

activate/deactivateサブリソース(rel=serviceを持つLinkヘッダーによってリンクされている)のように、私は一般的に少し単純なものを好むでしょう。

POST /groups/api/v1/groups/{group id}/activate

または

POST /groups/api/v1/groups/{group id}/deactivate

消費者にとって、このインタフェースは非常に単純であり、個々のリソースとして「アクティベーション」を概念化することに煩わされることなくREST原則に従います。

0
rich remer