2009-09-15 13 views
19

私はカウンタを持つリソースを持っています。例のために、のは、プロファイルリソースを呼びましょう、とカウンターはそのプロファイルのビューの数です。リソースカウンタをRESTfulな方法でインクリメントする:PUTとPOST

REST wikiによれば、PUTリクエストはリソースの作成または変更に使用する必要があり、冪等でなければなりません。名前を何か1000回設定して結果が変わらないPUTリクエストを発行できるので、プロファイルの名前を更新すると、その組み合わせはうまくいきます。これらの標準のPUT要求の場合

、私はブラウザのような何かをしている:カウンタをインクリメントするために

PUT /profiles/123?property=value&property2=value2 

を、人はそうのようなURLを呼び出します。

PUT /profiles/123/?counter=views 

各呼び出しはカウンターになります増分される。技術的には更新操作ですが、それは冪等性に違反します。

私はガイダンス/ベストプラクティスを探しています。あなたはPOSTとしてこれをやっていますか?

答えて

8

別のリソースをシステムに追加して、プロファイルの表示を追跡することもできます。あなたはそれを「見る」と呼ぶかもしれません。プロファイルに閲覧を

追加するには

GET /プロファイル/ 123 /視聴:

は、プロファイルのすべての視聴を表示するには

POST /プロファイル/ 123 /視聴には、あなたを#hereリクエスト本文にカスタムメディアタイプを使用して詳細を送信します。

既存の表示更新するには:

PUT /視聴を/ 815#は、作成したカスタムメディアタイプを使用して要求本体に表示の改訂属性を提出します。

表示の詳細にドリルダウンする:なぜならあなた」、また

DELETE /視聴/ 815

:表示を削除するには

GET /視聴/ 815

ベストプラクティスを求める場合は、RESTfulシステムがhypertext-drivenであることを確認してください。

ほとんどの場合、URIでクエリパラメータを使用する際に何も問題はありません。クライアントにそれらを操作できるという考えを与えないだけです。

代わりに、パラメータがモデル化しようとしている概念を具体化するメディアタイプを作成します。このメディアタイプには、簡潔でわかりやすく記述的な名前を付けます。次に、このメディアタイプを記録します。 RESTでクエリパラメータを公開するという実際の問題は、実際には帯域外通信が行われ、クライアントとサーバー間の結合が増加することです。

次に、システムに統一されたインターフェイスを与えます。たとえば、新しいリソースの追加は常にPOSTです。リソースの更新は常にPUTです。削除はDELETEで、getiingはGETです。

RESTの最も難しい部分は、メディアの種類がシステム設計にどのように反映されているかを理解することです(Fieldingが時間を使い果たしたためにFieldingが論文から脱した部分です)。メディアタイプを使用しているハイパーテキスト駆動型システムの特定の例が必要な場合は、Sun Cloud APIを参照してください。

+0

明確にするために:/ viewings/815はプロフィールの815番目の閲覧を参照していますか? –

9

正しい答えはPATCHを使用することだと思います。私はアトミックカウンタをインクリメントするために使用されるべき推奨誰を見ていないが、私はRFC 2068は非常によく、それをすべて言うと信じて:

PATCHメソッドは、エンティティはの リストが含まれていることを除いてPUTに似ていますRequest-URIによって識別されるリソース の元のバージョンと、PATCHアクションが適用された後にリソース の望ましいコンテンツとの間の相違。相違点のリストは、 エンティティのメディアタイプで定義された形式(例: "application/diff")であり、 の元のファイルを元に変換するのに必要な変更を再現できるだけの十分な情報を含まなければならないリソースを必要なバージョンに更新します。

だから、私は希望、プロファイル123のビュー数を更新します(私はちょうど製)x-countersメディアタイプがfield operator scalarタプルの複数のラインで構成され

PATCH /profiles/123 HTTP/1.1 
Host: www.example.com 
Content-Type: application/x-counters 

views + 1 

views = 500またはviews - 1またはviews + 3はすべて構文上有効です(ただし、意味的には禁止されている可能性があります)。

もう1つのメディアタイプを作成する際に悩ましいことを理解できますが、POST/PUTの代替方法よりも正しいことを謙虚に示唆しています。フィールドのリソースを作り、それ自身のURI、特にそれ自身の詳細(私が持っているものはすべて整数です)は完全に間違っていて、面倒です。維持するカウンターが23個ある場合はどうなりますか?

+1

「PATCHアクションが適用された後にリソースの望ましい内容」がないため、標準から逸脱しています。例えば。エンティティは、実行される命令であり、所望の結果ではない。 – Pocketsand

+0

@ Pocketsandが述べたことに続いて、このアプローチは、「統一インターフェース」制約の下で「表現を通じてリソースの操作」サブ制約に違反しないのですか?どのように操作するかについての指示を送るのではなく、見たいリソースの表現を送り返すべきです。 – dayuloli

+0

@dayuloliまだ解決策を検討している場合は、[回答を追加しました](https://stackoverflow.com/questions/1426845/incrementing-resource-counter-in-a-restful-way-put-vs-post)/44852115#44852115)私は一緒に行くことを決めたので、あなたのニーズに合っているかもしれません。 – Pocketsand

0

私はYanicとRichの両方のアプローチが相互に関係していると思います。 PATCHは安全である必要はありませんが、並行性に対してより堅牢なものにすることができます。 Richのソリューションは、「標準的な」REST APIで使用するのが確実に簡単です。

RFC5789を参照してください:[RFC2616]、セクション 9.1で定義されているよう

PATCHは安全でもべき等でもありません。

PATCH要求はまた、同様の時間枠内で同じリソース上の2つの PATCH要求間の衝突から悪い結果を防ぐことができます 、冪等するような方法で発行することができます。 複数のPATCH要求からの衝突は、 PUT衝突より危険です。一部のパッチ形式は、既知の基準点 から動作する必要があるため、衝突する可能性があります。そうしないと、リソースが破損します。

0

以前の回答を評価した後、私は簡単な作業のためのContent-Typeの周りKISS principleの違反をしていじって、私の目的のために、PATCHが不適切と判断しましたと。 ++がメッセージボディであり、1つによってリソースをインクリメントする命令として制御装置によって解釈される

PUT /profiles/123$views 
++ 

:私は私はちょうどこれをしたN + 1をインクリメントする必要がありました。

私はそれがlegal sub-delimiterあるとして、リソースのフィールド/プロパティをdeliminateする$を選んだと、私の目的のために、私の意見では、traversabilityの雰囲気を持っている、/よりも直感的に思えました。

関連する問題