POST後にコンテンツを返すことはRESTによって大丈夫ですか?


88

RESTletを使用していて、リソースを作成しました。acceptRepresentationメソッドをオーバーライドしてPOSTを処理します。

クライアントは私にいくつかのデータを送信する必要があり、それをDBに保存し、応答を201(SUCCESS_CREATED)に設定し、いくつかのデータをクライアントに返す必要がありますが、戻り値の型はacceptRepresentationですvoid

私の場合、クライアントがそのリソースにアクセスできるように、識別子を返す必要があります。

たとえば、URLのあるリソースが/resourceあり、クライアントがPOSTリクエストを送信した場合、DBに新しい行を追加すると、そのアドレスはになります/resource/{id}。送信する必要があります{id}

私は何か間違ったことをしていますか?RESTの原則では、POST後に何かを返すことができますか?はいの場合、どうすればそれを行うことができますか?いいえの場合、この状況に対処する方法は何ですか?


acceptRepresentation()内から応答本文を設定する方法については、Thomの回答を参照してください。
Avi Flax

回答:


96

RESTは、統一されたインターフェイスに準拠する必要があると言っているだけです。つまり、HTTP仕様に従ってPOSTが実行するはずのことを実行する必要があるということです。これが関連するその仕様からの引用です、

オリジンサーバーでリソースが作成されている場合、応答は201(作成済み)であり、要求のステータスを記述し、新しいリソースを参照するエンティティと、Locationヘッダーを含む必要があります(セクション14.30を参照)。

これからわか​​るように、新しく作成されたリソースが存在する場所をクライアントに示すことができる2つの場所があります。Locationヘッダーには、新しいリソースを指すURLが含まれている必要があり、詳細を含むエンティティを返すこともできます。

acceptRepresentation()のオーバーライドとpost()のオーバーライドの違いはわかりませんが、この例は、POSTから応答を返す方法を示しています。


2
@ del-boy:acceptRepresentation()内から応答本文を設定する方法については、Thomの回答を参照してください。
Avi Flax

1
HTTP仕様の見積もりでは、応答が禁止されていません。セクション6を見ると、次のことが明らかです。許可されている: Request and Response messages MAY transfer an entity if not otherwise restricted by the request method or response status code. An entity consists of entity-header fields and an entity-body, although some responses will only include the entity-headers.
MikeF 2015

@MikeF応答機関が許可されていないと推測することは私の意図ではありませんでした。私が引用した仕様の一部には、具体的に「エンティティが含まれている」と書かれています。私は自分のテキストをもっと明確にすべきだった。
ダレルミラー

16

応答の本文には何も送信しません。Location:を新しく作成されたリソースの(完全な)URLに設定するだけです。

あなたの説明は、これがまさにあなたのセマンティクスであることを示唆しています:

  1. それを作成するものを投稿する
  2. 2つのことを知るのに十分な応答をします。
    1. 創造が起こったこと(201)
    2. 新しいものを見つける場所(Locationヘッダー)

それ以外は不要です。


ウィキペディアは、常に良好な源である、ではないことが、そのまた、特許請求の範囲「[...]新たに作成されたリソースの位置に関する情報を提供する。このような状況では、Locationヘッダ201または202のHTTPステータスコードを用いて送信されるべきです。」
Arjan 2017年

1
POSTは、1つ以上のリソースを作成するロジックを実行する場合があります。処理の結果は、クライアントによって必要になる場合があります。そのため、応答で返すことで、APIに対して1つ以上のGET呼び出しを行う必要がなくなります。POSTメソッドによって作成/変更されたデータは、クライアントにとって不要ではない場合があります(多くの場合、不要ではありません)。
Paulo Merson 2017

10

2つの異なる質問:

RESTアプリケーションパターンは、POSTでのデータの返送をサポートしていますか?

RESTが明示的にそれを禁止しているとは思いませんが、Darrelの回答には好ましい扱いが詳しく説明されています。

RESTletフレームワークではPOSTでデータを返すことができますか?

はい、voidを返しますが、Resourceを拡張するクラスでは、getResponse()メソッドを介してResponseオブジェクトオブジェクトに完全にアクセスできます。したがって、必要なデータを使用してgetResponse()。setEntity()を呼び出すことができます。


6

要求された形式で出力します。それは次のようになります。

<success>
    <id>5483</id>
</success>

または:

{ "type": "success", "id": 5483 }

それはあなたが通常何をするかに依存します。データを期待していない場合は、無視する必要がありますが、データを適切に処理したいクライアントはすべて無視できるはずです。


わかりました。2つの可能な形式(htmlとxml)があります。要求された形式のタイプを処理する方法は知っていますが、応答にデータを追加する方法がわかりません。表現メソッドは表現を返すので、必要なものだけを返しますが、acceptRepresentationはvoidメソッドなので、データを返すことはできません...
del-boy

1

201 Created with the entity bodyではなく、Locationリダイレクトで応答する場合は、応答で表されているリソースを指すContent-Locationヘッダーを含めることをお勧めします。

これにより、潜在的な混乱を回避できます。クライアントは、応答エンティティが実際には作成されたリソースではなく、「作成者」の新しい状態を表していると(正当に)想定できます。

> POST /collection
> ..new item..

< 201 Created
< Location: /collection/1354
< Content-Location: /collection/1354
< <div class="item">This is the new item that was created</div>

3
Content-Locationは別の目的のためだと思います。HTTP仕様では、Content-LocationはPOSTおよびPUTに対して定義されていません。Locationヘッダーは、201-Createで使用されます。場所を返しても自動的にリダイレクトされるわけではありません。そのためには3XX応答コードが必要です。
ダレルミラー

1
ロケーションヘッダーは、作成されたリソースがどこにあるかを示すために(201応答で)使用されます。付随する応答のエンティティ本体とは関係ありません。私のポイントは、(クライアントを別のURIに転送/リダイレクトするのではなく)作成されたリソースを201応答自体に含めたい場合は、content-locationヘッダーを使用することをお勧めします。これはおそらく「ルールを少し曲げる」ことですが、新しいリソースの状態をクライアントに取得するために別の要求/応答サイクルを要求するよりも効率的です。
マイク

私には理にかなっています。私はこれまでContent-Locationヘッダーを使用したことがありません。
ダレルミラー

クライアントがブラウザを持っている人間の場合、Locationヘッダーを付けて201を返すことは意味がありません。ユーザーはそれをどうするかわかりません。クライアントがロボットの場合、ロケーションでのフォローアップGETのように、その対処方法を知ってプログラムすることができます。
評判の悪い2009

3
@irreputable:RESTはAPIを設計するためのものであり、AはレンダリングするHTMLを探すユーザーエージェントを表していないと思います。
エルメス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.