0

次のような URL があります。

http://www.example.com/users/

PUT リクエストで新しいユーザーを作成したい:

requests.put('http://www.example.com/users/john/', data={'password': 1234})

実際、このリクエストは新しいユーザー リソースを作成し、201 "Created" ステータス コードを返します。そのリソースを更新したい場合は、次のようなリクエストを作成できます。

requests.put('http://www.example.com/users/john/', data={'username': 'jane'})

まあ、301 "Moved Permanently" ステータス コードと Location ヘッダーに新しく作成された URL を含む応答を返すことができます。問題は、コントローラーコードにそのようなロジックを実装しようとしているときに発生します。ロジックの一部に、次のようなユーザー名の存在をチェックするコードがあります。

if username in users:
  # do something

新しいリソースを作成するために PUT を使用すると、この場合はユーザー名が既に存在すると言って、ユーザー名が存在しない場合、「ユーザー名は既に存在します。別のものを選択してください」のようなメッセージで 409「競合」ステータス コードを返すことができます。 「存在しません。201 の「作成済み」を返すだけです。論理的には、この作成操作は認証を必要としないため、「サインアップ」操作のようなものです。

一方、リソースの更新を要求するときは、ユーザーが自分のアカウント情報を更新できるようにするために、何らかの認証を行う必要があります。

したがって、ユーザー名変数を使用して実行する必要がある操作を決定し、ユーザー名が既に存在する場合、認証が必要か無効なユーザー名の応答でいつ応答するかわかりません。

私が最初に考えたのは、POST リクエストを使用して新しいユーザーを作成し、更新動作のためだけに PUT することでしたが、サーバーによって作成されていない識別子のリソースを作成するために POST を使用するのは悪い考えのようです。

私の質問は、PUT リクエストを使用して作成機能と更新機能の両方を実装する方法があるかどうかです。

4

1 に答える 1

1

更新の場合、別のオプションは PATCH であり、その要求を認証して純粋な更新として扱うことができます。

オブジェクトを作成すると、コレクションに対して作成し、201 を返すことができます。完全なリソースを完全に置き換えると、ユーザー リソースに対して PUT を実行できます。PATCH は部分的な更新用である可能性があります。

Create (Anonymous)
Request  : [POST|PUT]  /users/        body=full object (incuding name)
Response : 201 LOCATION =  /users/123

Overwrite (Auth)
Request   : [PUT]      /users/123     body=full object - id implies overwrite    
Response  : 200

Update (Auth)
Request   : [PATCH]    /users/123     body=partial objects      
Response  : 200

親リソース (この場合は users コレクション) に対して (POST | PUT を介して) リソースを作成します。それは問題を解決します。それも良い習慣です。また、パーマリンク (int id または guid) を持つリソースを作成して、ユーザーが自分の名前を変更し、保存された参照が壊れないようにする必要があります。

識別子をパーマリンクにしたい場合、(コメントで提案されているように) クライアントによって作成されるようにする場合は、識別子に GUID のようなものを使用する必要があります。

于 2013-03-04T22:57:36.760 に答える