RESTにおけるPUTとPOSTの比較

HTTP/1.1 Spec.による。

POST`メソッドは、オリジンサーバーに対して、リクエストに含まれるエンティティを、Request-LineRequest-URIで識別されるリソースの新しい下位互換として受け入れることを要求するために使用されます。

つまり、POST作成に使われます。

また、POST作成に使われます。 PUTメソッドは、与えられたRequest-URIの下に格納されているエンティティを要求します。もしRequest-URIが既に存在するリソースを参照している場合には、含まれるエンティティはオリジンサーバーに存在するものを修正したものとみなされるべきです(SHOULD)。Request-URI`が既存のリソースを指しておらず、そのURIがリクエストしたユーザーエージェントによって新しいリソースとして定義できる場合、オリジンサーバーはそのURIでリソースを作成することができます."

つまり、PUT作成や更新に使われます。

では、リソースの作成にはどちらを使用すべきでしょうか?それとも、両方をサポートする必要があるのでしょうか?

ソリューション

Overall:

作成にはPUTとPOSTの両方が使用できます。

どちらを使うべきかを見分けるためには、「何に対してアクションを実行するのか」を問わなければなりません。例えば、質問をするためのAPIを設計しているとしましょう。 もしPOSTを使いたいのであれば、質問のリストに対して行います。PUTを使いたいのであれば、特定の質問に対して行います。

**どちらも使えるので、RESTfulなデザインではどちらを使うべきでしょうか。

PUTとPOSTの両方をサポートする必要はありません。

どちらを使用するかはあなた次第です。 しかし、リクエストで参照するオブジェクトに応じて、適切なものを使用することを忘れないでください。

いくつかの考慮事項があります。

  • 明示的に作成したURLオブジェクトに名前を付けるか、それともサーバーに任せるか?名前を付ける場合はPUTを使用します。 サーバーに任せるのであればPOSTを使います。
  • PUTはidempotentなので、あるオブジェクトを2回PUTしても効果はありません。 これは良い特性なので、可能な限りPUTを使用します。
  • PUTでは、同じオブジェクトのURLでリソースを更新したり作成したりすることができます。
  • POSTでは、2つのリクエストが同時に来てURLに変更を加えることができ、オブジェクトの異なる部分を更新することができます。

**例を挙げると

以下は、この件に関するSOの別の回答の一部として書いたものです

記事の内容は以下の通りです: POST: となっています。

リソースの修正や更新に使用する となっています。 POST /questions/ HTTP/1.1 ホスト: www.example.com/

以下はエラーとなりますのでご注意ください。

POST /questions/ HTTP/1.1 ホスト: www.example.com/

まだURLが作成されていない場合は URLが作成されていない場合は、POSTで作成すべきではありません。 名前を指定しながら作成することはできません。 これは 結果として 'resource not found'というエラーが発生します。 結果は 'resource not found'エラーとなります。なぜなら がまだ存在しないからです。 となります。 まず、をサーバーにPUTする必要があります。 リソースをサーバーにPUTする必要があります。

となってしまいます。 しかし、次のようにすることもできます。 POSTでリソースを作成します。

となります。 POST /questions HTTP/1.1 ホスト: www.example.com/ となります。 この場合、リソースの 名前が指定されていないので、新しいオブジェクトの URLパスが返ってくることになります。

PUT: となります。 リソースの作成や、上書きする際に使用します。 上書きします。 リソースの新しいURLを指定しますが リソースの新しいURLを指定します。

新しいリソースを作成します。

PUT /questions/ HTTP/1.1 ホスト: www.example.com/ となります。 既存のリソースを上書きする場合

既存のリソースを上書きする場合: > PUT /questions/ HTTP/1.1 ホスト: www.example.com/

解説 (41)

作成にはPOSTを、更新にはPUTを使います。Ruby on Railsではこのようにしています。

PUT    /items/1      #=> update
POST   /items        #=> create
解説 (8)

RESTは、非常にレベルの高いコンセプトです。実際には、HTTPについてはまったく触れられていません。

RESTをHTTPで実装する方法について疑問がある場合は、Atom Publication Protocol (AtomPub)の仕様を参考にしてください。AtomPubは、HTTPでRESTfulなWebサービスを書くための規格で、RESTの発明者であり、HTTPの(共同)発明者でもあるRoy Fielding氏の意見を取り入れながら、多くのHTTPおよびRESTの著名人によって開発されました。

実際、AtomPubを直接使うこともできるかもしれません。AtomPubは、ブログコミュニティから生まれたものですが、ブログに限定されるものではありません。RESTfullyに、任意のリソースの任意の(ネストされた)コレクションとHTTP経由で対話するための汎用プロトコルです。自分のアプリケーションをリソースのネストした集合体として表現できれば、AtomPubを使うだけで、PUTとPOSTのどちらを使うか、どのようなHTTPステータスコードを返すかなど、細かいことを気にせずに済むようになります。

AtomPubでは、リソースの作成について次のように説明しています(9.2節)。

コレクションにメンバーを追加するには、クライアントはコレクションのURIにPOSTリクエストを送信します。

解説 (9)