2011-01-12 5 views
4

私はRESTの原則にかなりよく知っているし、関連する論文、Wikipediaのエントリ、ブログ記事の束と被写体上のStackOverflowの質問を読んでいるが、それでも一般的な場合には簡単な答え見つけていない:読み取り専用と編集可能なリソースをRESTスタイルで取得するにはどうすればよいですか?

私は表示するリソースを要求する必要があります。リソースの状態に応じて、私は読み込み専用か編集可能な表現のどちらかをレンダリングする必要があります。どちらの場合でも、私はリソースを取得する必要があります。読み取り専用または編集可能なバージョンを取得するURLを作成するにはどうすればよいですか?

私のユーザーがGET /resource/<id>へのリンクをたどっている場合は、読者のみが読み込み専用の表現を必要としていることを示すだけで十分です。しかし、編集可能なフォームをサーバーに置く必要がある場合、そのURLはどのように見えますか? GET /resource/<id>/editは明らかですが、URLに動詞が含まれています。 GET /resource/<id>/editableにそれを変更することで、この問題は解決されていますが、見た目は明らかに表面的なレベルです。動詞を形容詞に変えることがすべてあるのでしょうか?

代わりにPOSTを使用して編集可能なバージョンを取得する場合、最初に取得したPOSTと保存しているPOSTを区別するにはどうすればよいですか? POSTを使用する私の(弱い)言い訳は、編集可能なバージョンを取得するとサーバーの状態が変わるということです:リソースをロックします。しかし、それは私の要求がそのようなロックを実装する必要がある場合にのみ成立します。常にそうであるとは限りません。同じ理由でPUTが失敗します。また、実行中のWebサーバーでPUTがデフォルトで有効になっていないため、使用しない実用的な理由(およびDELETE)があります。

編集可能な状態であっても、まだ変更を加えていないことに注意してください。おそらく私がリソースをWebサーバーに再度提出すると、私はそれをPOSTします。しかし、私が後でPOSTできる何かを得るためには、サーバーは最初にに対応しなければなりません。

私は別のアプローチは、コレクションレベルで別々のリソース持っているだろうと思います: GET /read-only/resource/<id>GET /editable/resource/<id>またはGET /resource/read-only/<id>GET /resource/editable/<id>を...しかし、それは私にはかなり見苦しいです。

思考?

答えて

6

1)2つの異なるリソース(表示用とドメインコンセプトの編集用)を持つことは完全に有効です。 RESTの観点からは2つの異なるURIであるため、2つの異なるリソースであることに注意してください。ドメインオブジェクトとリソースを競合させる人があまりにも多い。だからこそ、彼らはCRUDをしているだけで立ち往生してしまうのです。

2)リソースの名前にぎこちないようにしないでください。重要なことは、URIが指していることが「もの」、つまり「リソース」であることを認識していることです。それがeditの代わりにeditableでより明白な場合は、それを使用してください。あなたのURLに動詞を付けるだけで、アプリケーションが間違ってしまうことはありません。それは、人間開発者にとって読みにくいものになります。 URLの動詞を使用してHTTPメソッドのセマンティクスを再定義しようとすると、これは統一インターフェース制約の違反です。

+0

re#2、私はそれについてかなり訓練されています。私は、POSTとGETを通じてすべての読み取り要求を介してすべての状態変更要求を送信します。 PUTまたはDELETEを使用するのは現実的ではありません。違いについての良い点。リソースとドメインobj。私は、リソースを特定の状態のオブジェクトの要求と考える傾向があります。 – Val

1

代わりにPOSTを使用して編集可能なバージョンを取得すると、最初に取得したPOSTとそれを保存しているPOSTを区別できますか?

リソースを読み込むためにGET(POSTではなく)を実行し、リソースを書き込むにはPOST(またはPUT)を実行します。

問題のリソースに対してロックを作成する場合は、POSTを使用してリソース(またはPOSTの本体にエンコードされたリソースIDを持つリソースのコンテナ)に書き込み、サーバーでロックを作成させますを新しいリソースとして追加し、そのリソースのIDをPOSTへの応答として返します。

(ご質問や、この答えの範囲を超えて認証の問題で)その後のいずれか、ロックを解除するロックリソースにDELETEを使用するか、またはPOSTロックのコンテナへ。

+0

はい、私は知っています、それは私の問題の要です。私は、たとえ私がほんのわずかな意味の理由を見つけることができたとしても、私が*働かないと考えるアプローチのPUTとPOSTの例を挙げました。だから、GETに戻ってください。編集可能な表現と編集不可能な表現を区別するにはどうすればよいですか? – Val

+0

なぜ彼らは違うでしょうか? (GETの文脈で) –

+0

編集可能にする必要があるため、それらは異なるでしょう。つまり、フォームをレンダリングする必要があります。要求されたリソースをフォームにレンダリングするかどうかを知る必要があります。リソースのレンダリング方法はどのように知っていますか? – Val

2

読み取り専用または編集可能なバージョンを取得するためにURLを作成するにはどうすればよいですか?

ここには、最初にURLを構築していることがあります。ハードコードされたURLにIDを追加することは、RESTではありません。 Roy Fielding has written about this very mistake。どちらの文書でもリソースを編集するかどうかを尋ねるメッセージには、そのリソースの編集可能なバリアントへのURIが含まれている必要があります。それが/resource/editable/editable/resourceであるかどうかは、そのURIに従ってください。

+0

はい、それはまさに何が起こるかです。私はそのようなリソースのコレクションのリストから個々のリソースにアクセスし、そのリストは、ターゲットリソースの状態に基づいてリンクされ、それぞれの個々のリソースにハイパーリンクします。コレクションには 'GET/resources/resource/23'と' GET/resources/resource/24/edit'のようなリンクがあります。それは、私がsezを読んだことのすべてが、URL内の動詞(例えば、 'edit')を持つことが悪い匂いであるということです。私はそれを乗り越えるべきですか? – Val

+0

Fieldingにはブログがありますか? +11111111 – Anders

+0

ああ、そう、つまらない。私はそれを大雑把に守ることは重要だと思いますが、決して白黒の問題ではありません。実際に起こっていることは、実際に編集を実行するのではなく、編集可能なバージョンのリソースを取得しているということです(私はあなたのアプローチは問題ではありません)。クライアント、プロトコルの一部ではない)。 – Jim

3

RESTでは、既存のリソースの編集は、クライアントがそのリソースの表現を取得し、表現を変更してから、新しい表現のPUTをサーバーに戻して実行します。

だからあなたのRESTクライアントプログラムはどうしたらリソース読むために:

GET http://www.example.com/SomeResource 
... edit it ... 
PUT http://www.example.com/SomeResource 

通常、同時更新がさせることで処理されます。そのリソースは

GET http://www.example.com/SomeResource 

そして編集することをサーバに到着した最後のPUTは、それがより新しい状態を表すと仮定して、以前のものを上書きする。しかし、あなたの場合は、これを守ることを望みます。

メインリソースごとにオプションの並列ロックリソースを維持するための@ Jasonの提案を慎重に検討してください。あなたのクライアントは最初にロックを作成し、編集してロックを削除します。ロックを行ったユーザーがその後変更を保存しないと、システムは自動的にロックを解除する必要があります。これは、次のようになります。

GET http://www.example.com/SomeResource  
... user presses an edit button ... 
PUT http://www.example.com/SomeResource/lock  
... user edits the resource's representation ... 
PUT http://www.example.com/SomeResource 
DELETE http://www.example.com/SomeResource/lock 

ユーザーが他の誰かによってロックされているリソースを編集しようとしている場合は、いくつかの適切なエラー処理を行う必要があると思います。

現在のHTMLの制限に縛られているように感じます。 Restlet(Javaの場合)のようなサーバー側のRESTフレームワークを使用する場合は、POSTを使用できますが、method = PUTまたはmethod = DELETEのようなクエリ文字列引数を指す "overloaded POST"という概念がサポートされています。独自のサーバーサイドコンポーネントを作成する場合は、このトリックも使用できます。

HTMLレベルでもプレイできるトリックがあります。たとえば、ページに最初に表示される読み取り専用の部分(および)が最初は表示されません。ユーザーが編集ボタンを押すと、JavaScriptは読み取り専用部分を隠し、入力フォームを表示します。

RichardsonとRubyのRestful Web Services(O'Reilly)も必ずお読みください。非常に便利です。

+0

私の問題は編集を保存するPOSTではない。それは完全にはっきりしています。それはGETにあります。サーバーはそのリソースの状態を保存しているため、リソースが編集可能かどうかを知ることができます。私は「HTMLトリックをする」ことができると思うが、それはアーキテクチャを乱用するようだ。代わりに、リソースの編集可能な表現を要求したいと思います。あなたの最初のGETの例はそれをスキップします。リソースを取得してから「編集」ボタンをクリックすると、ボタンがサーバーから要求するURLは何ですか?それがJavaScriptのブラウザ上にあれば、それはあらゆる種類の制約を課し、単に問題に取り組むだけです。 – Val

+0

ガード:http://en.wikipedia.org/wiki/HTTP_ETag – RobEarl

3

フォームの返却や値の単なる値は、RESTサーバーまでですが、クライアントの責任ではありません。リソースが編集可能かどうかは、リソースのプロパティであり、URLによって定義されたものではありません。

つまり、リソースを取得するためのURLはGET /resource/<id>です。これには編集可能なプロパティがあります。ユーザーがフォームを必要とする場合は、同じURLからリソースを取得してフォームに入力できます。クライアントは、PUT/POST変更よりも可能です。

+0

「編集可能」プロパティはどこに保存されていますか?どのように入手できますか? URLで定義されていると期待していますが、URLに_specified_と期待しています。私のサーバーはリソースを提供しているので、私が要求したURLに基​​づいて適切な表現を提供することはサーバーの責任です。そしてフォームとDIVの束はまったく同じ抽象リソースの表現の違いです。 – Val

+0

あなたはリソースの状態からそれを推論します。それはあなた自身が言ったことです。「リソースの状態によっては、読み込み専用または編集可能な表現のどちらかをレンダリングする必要があります。しかし、あなたはURLでそれを判断したいと思うかもしれません。この場合、出発点に戻ります。しかし、あなたはおそらく間違った方法で問題を見ているでしょう。同じリソースのさまざまな表現を表示するのは、RESTfulではありません。「サーバーはユーザーインターフェイスに関係しません」 – ontrack

+0

編集可能であるという理由だけで編集したいというわけではなく、現在のユーザーに編集権限があります。コレクションページで、使用可能な状態のURLを表示するようにします。私は、承認などに基づいて適切なReadとEditリンクを表示しますが、私はURLが必要です。それがRESTの発見可能な部分です。私は最後のビットをgrokしないでください。私のUIレイヤはUIに関係していますが、私はまだステートに基づいて別の表現を提供する必要があります。 URLは状態を表します。 RESTは、同じリソースに対して異なる表現を表示することに非常によく似ています。 – Val

0

あなたの質問は、「PUTアクションでGETアクションで返される読み取り専用表現を特定する方法」でしょうかと思います。これを行うことができます:

<Root> 
<readonly> 
<p1><p1> 
... 
<readonly> 
<others> 
... 
<others> 
<Root> 

PUTから要求XMLを解析した後、読み取り専用部分を無視して他のものを処理することができます。レスポンスで200のステータスを返し、読み取り専用の部分が無視されているというメッセージを残します。 それはあなたの期待ですか?

関連する問題