RESTfulなWebサービスにおいて「指定したIDでリソースを新規作成するか、既に存在するのであればエラーとしたい」という場合どうするのが一般的でしょうか。

といった受け答えをしたい場合です。
以下のようなものを考え、それぞれ疑問点を付記しました。

1. POST /user/foo
RFC2616 によると「新しい従属{subordinate} として、リクエストに同封されるエンティティを受け入れる事を要求する」とあり、新規作成はコレクションリソース (この場合 users) にすべきなのでしょうか。

2. POST /users (POSTパラメータとしてid=foo)
そもそもPOSTで作成するリソースのIDを指定してもいいのでしょうか。

3. PUT /user/foo
重複IDをエラーとするので、リソースを更新できないことになってしまいます。

4. PUT /user/foo?new=on
パラメータを付記することで、「既にリソースが存在する場合はエラーにして欲しい」とするものです。
べき等性のを考えると疑問があります。

既存のパターンや落とし所などあれば教えていただきたいです。
よろしくお願いします。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2012/10/01 13:11:56
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:tkawa No.2

回答回数1ベストアンサー獲得回数1

ポイント200pt

結論から言うと、2か3がよく、1や4も場合によってはOKだ思います。

一般的には、URLをサーバが決定する場合はPOST、クライアントが決定する場合はPUTと言われています(Webを支える技術 p.95)。
それに従うならばこの場合はPUTで 3 ということになります。PUTでリソースの更新を許すかどうかというのは、新規作成できるユーザと、更新できるユーザは権限が異なるという認証や認可(権限)の問題なので、適切に設計すれば大丈夫でしょう。
ステータスコードは、成功なら201、失敗なら権限なしということで401/403になります。(更新成功なら200)

新規作成と更新の操作を明確に区別したいということであればPOSTで 2 でもいいと思います。パラメータでURL(の一部)を指定することは問題ありません。
この場合、成功なら201、失敗なら409ですかね。

4 に関しては、If-None-Match: * というリクエストヘッダが相当します。リソースが存在しなければ実行しろという意味になります。この場合は失敗すると412となります。ある意味ではこれが一番RESTfulかも。

自分が実装するとしたら、他の条件にもよりますが単純に 2 にすると思いますね。

その他の回答1件)

id:oil999 No.1

回答回数1728ベストアンサー獲得回数320

ポイント100pt

RESTfulなWebサービスというのはオープンな(インターネットに対して開かれた)サービスのことで、リソースというのがファイルシステム上のサブディレクトリやファイル、またはデータベースの物理テーブルのようなものを生成するという意味であれば、そもそも論として、POSTでリソースを新規作成指示してはなりません。
というのは、サイバー攻撃として新規リソース作成要求をかけられてしまうと、Webシステムに膨大な負荷がかかるためです。

オープンなWebサービスにおいて新規リソース作成要求をかけたいなら、SSL通信が大前提です。
次に、クライアント証明書を送るなり、OAuthを利用するなりして、クライアント認証を行う必要があります。
ここまでクリアしたら、あとはPOSTでIDを送ることになります。リソースIDの範囲が "foo" だけなら、ご質問にある2の方法が妥当でしょう。リソースが存在したらエラーを返すのが前提の処理なら、4にするのは回りくどい気がします。

id:taketyan

ありがとうございます。
前半の件については、Web サービスといってもクローズドなものなので問題無いです。
社内のサービスから使用される共通の Web API で、SSL 接続を前提としています。
認証については、社内からしか使われない前提なので、パラメータを利用した簡単な認証を行っています。

2 が妥当、4 は回りくどい、というご意見ありがとうございます。
参考にさせていただきます。

2012/09/26 20:18:03
id:tkawa No.2

回答回数1ベストアンサー獲得回数1ここでベストアンサー

ポイント200pt

結論から言うと、2か3がよく、1や4も場合によってはOKだ思います。

一般的には、URLをサーバが決定する場合はPOST、クライアントが決定する場合はPUTと言われています(Webを支える技術 p.95)。
それに従うならばこの場合はPUTで 3 ということになります。PUTでリソースの更新を許すかどうかというのは、新規作成できるユーザと、更新できるユーザは権限が異なるという認証や認可(権限)の問題なので、適切に設計すれば大丈夫でしょう。
ステータスコードは、成功なら201、失敗なら権限なしということで401/403になります。(更新成功なら200)

新規作成と更新の操作を明確に区別したいということであればPOSTで 2 でもいいと思います。パラメータでURL(の一部)を指定することは問題ありません。
この場合、成功なら201、失敗なら409ですかね。

4 に関しては、If-None-Match: * というリクエストヘッダが相当します。リソースが存在しなければ実行しろという意味になります。この場合は失敗すると412となります。ある意味ではこれが一番RESTfulかも。

自分が実装するとしたら、他の条件にもよりますが単純に 2 にすると思いますね。

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません