web-dev-qa-db-ja.com

ペイロードにリソースIDを含めるか、URIから派生するには

APIを設計すると、更新されるリソースのIDをPUTペイロードに含める必要があるかどうかという問題に直面しました。

これは私たちが現在持っているものです:

PUT /users/123 Payload: {name: "Adrian"}

ルートコードはURIからIDを抽出し、更新を続行します。

APIの最初のユーザーは、ペイロードでIDを許可しない理由を質問しています。

PUT /users/123 Payload: {id: 123, name: "Adrian"}

許可しなかった理由は、IDがペイロードとURIで重複しているためです。

これについてもう少し考えて、リソースをURIに結合しています。

URIにIDがない場合、ペイロードを修正する必要があります。

PUT /no/id/here Payload: {name: "Adrian"} < What user???

しない理由はありますか?

13
Adrian Lynch

あなたは仮定でユニフォームResource識別子をresourceに結合します。

RESTがHTTPで実装されている場合、GETを使用してリソースの現在の値を取得し、PUTを使用して新しい値を設定します。GETにはペイロードがないため、リソースを特定する必要がありますまた、PUTは論理的に同じURIに対して行われ、ペイロードは次のGETが返すものとまったく同じに見えるはずです。

異なるURIにPOSTを使用できますが、GETに対して不必要に非対称であるため、あまり意味がありません。POST共通URIは、新しいリソースを作成する意味(POST /users/new、ペイロード:{name: "Adrian"}、応答{id: 345, name: "Adrian"})、ただしそれはべき等ではないであり、したがって回避する必要があります rESTを目指しているなら¹。代わりに、1回の呼び出しでIDを予約し、PUTを使用して新しいIDを設定する必要があります。これはフォールトトレラントです。最初のリクエストが失敗した場合、ID予約は最終的にタイムアウトになり、PUTはべき等です。または、クライアントが生成したUUIDを使用します。


= RESTの定義はべき等については何も言っていないので、RESTがべき等でない演算を持っている場合はそうではないと主張することはできません。それはべき等の要求に固執することで、複雑化することなく物事の信頼性が向上するという事実は変わらないため、推奨されます。

14
Jan Hudec

これについてもう少し考えて、リソースをURIに結合しています。

URIにIDがない場合、ペイロードを修正する必要があります。

PUT/no/id/hereペイロード:{name: "Adrian"} <どのユーザー???

しない理由はありますか?

この質問に対する答えは、クライアントがIDを変更できるようにするかどうかによって異なりますか?

クライアントがPUTを介してIDを変更できる場合、リソースのURIが変更されるため、リソースが古いURIにアクセスするときはいつでも、301 Moved Permanentlyを提供する必要があります。

たとえば、次のリソースから始めます。

/users/123

クライアントは以下をリソースにPUTします

{id: 222, name: "Adrian"}

リソースが更新され、そのURIが

/users/222

PUT応答のLocationフィールドには新しいURIが含まれている必要があり、/users/123に移動すると、301応答が返され、Locationフィールドが新しい/users/222リソースを指すようになります。

ほとんどの場合、実際にはクライアントがIDを変更できるようにする必要はありません。これにより、かなり乱雑になる可能性があります。その場合、IDはサーバーのみが変更できるものであり、クライアントはこの状態を更新できないため、PUT本文から除外する必要があります。

同じリソース上の別のURIに要求をPUTする場合は、

/users/adian_lync

次に、そのリソースが存在しない場合、サーバーはそれを作成し、作成時にIDを作成する必要があります。

2
Cormac Mulhall