2013-07-08 10 views
7

各状態がハイパーリンクする必要があるというHATEOASの原則に従って、リソース状態を変更するリンクをモデル化する最良の方法は何ですか?HATEOAS - 状態を変更するリンク関係をモデル化する方法

のは、注文して古典的な例を見てみましょう:

{ 
    id : 12, 
    state: 'pending', 
    ..., 
    links: [ 
    ..., 
    { 
     rel: 'cancel', 
     href: '/orders/12/cancel' 
    }, 
    ... 
    ] 
} 

私はそのとtotall満足していない一部を「/キャンセル」 - 私が「PUT」リクエストを送信することができれば、私はかなり良く感じるだろう内容:

{ 
    status:'cancelled' 
} 

しかし、リンクセクションの「href」属性を使ってどのように表現すればよいですか?私はそこで利用可能な行動を表現したいと思います。例えば、注文をキャンセルすることは必ずしも可能ではありません( '完了'状態)。

「/ orders/12?action = cancel」のようなURLをRPCアプローチのように感じることがあり、何か不足している可能性があります。

おそらく素敵に見える別の可能性、そのようなリンクを持っているだろう:

{ 
    rel: 'cancel', 
    href: '/orders/12/', 
    type: 'PUT', 
    values: { 
    state: 'cancelled' 
    } 
} 

このソリューションは、多分、少し冗長に感じています。

どのようにその優雅に処理するためのアイデアですか?たぶん誰かがすでに同様の "問題"を解決しているのでしょうか?

答えて

0

これらの2つのモデルのいずれかをお勧めします。最初のものは古典的なものですが、rel="edit-form"PATCHを使用してください。もう1つは、HTTPリソース・モデルがアプリケーション・ドメイン・モデルにどのようにマップされるか(つまり、2つが1:1マッピングを持つ必要がないということ)に関するいくつかの側面から考える方法です。


ソリューション1つの

編集インプレース資源。互換

HTML:

HTTP/1.1 200 OK 
Content-Type: text/html 
Location: /orders/1/ 

...<a rel="edit-form" href="./edit">Edit</a>... 

HTTP/1.1 200 OK 
Content-Type: text/html 
Location: /orders/1/edit 

... 
<form action="../" method="POST"> 
    <input type="hidden" name="_METHOD" value="PATCH"> 
    <button type="submit" name="status" value="cancelled">Cancel Order</button> 
</form> 
... 

POST /orders/1 HTTP/1.1 
Content-Type: application/x-www-form-urlencoded 

_METHOD=PATCH&status=cancelled 

リッチクライアント(例えばHTML + Javascriptの)互換性:

PATCH /orders/1 HTTP/1.1 
Content-Type: application/x-www-form-urlencoded 

status=cancelled 

および/または

PATCH /orders/1 HTTP/1.1 
Content-Type: text/json 

{ 
    "status": "cancelled" 
} 

_METHODキーが原因HTTPのサポートのHTMLの不足のために正しい方法でRESTフレームワークを提供するの周知の手段です。この方法に関する詳しい情報は、


ソリューション2

あるいは、(ちなみに、新しいものを作成し、)リソースを削除

DELETE /orders/1 HTTP/1.1 

HTTP/1.1 201 Created 
Location: /cancelled-orders/1 

Webリソースをドメインオブジェクトにマッピングするには、see my answerも同様の質問になります。

もう1つの回答は、this oneです。

8

モデリングリソースは、RESTの最も難しい部分です。 /resource/:id/{action}を厳密に守れば、エンドポイントは理想的には常に「名詞」、決して「動詞」にならないので、「HTTPを正しく使用する」基準に違反していることになります(動詞はHTTPプロトコル)が提供さそう

、(つまり、リソースを設計の難しい部分)は、一般的に「それが依存」しながら、:。。。 オブジェクトモデルの状態がリソースそのもの

意味

、ご注文とみなすことができますステータスは、実際には(スタンドアロンの/orderstatusesリソースとして、またはサブリソースとして、たとえば/orders/:id/statusとして)照会できるリソースです。

アプリケーションステータスは、オーダー自体の現在のステータスに基づいてステータスリソースにリンクできるようになりました。あなたの「ステータス」スキーマは、この(擬似)のようになります場合:

key: 'status' 
values: ['pending', 'cancelled'] 

アプリでしその後、PUT /order/:id/status {status:'cancelled'}(整形状態)当時のご注文をキャンセルするように作用するだろうAPIへ。これらの用語では少し変わった考え方です(RPCはもっと直感的です)が、うまくいけばこれが役に立ちます。

1

何とかフォームを記述する必要があります。あなた「冗長」ソリューションは完全に大丈夫です:

{ 
    rel: 'cancel', 
    href: '/orders/12/', 
    type: 'PUT', 
    values: { 
    state: 'cancelled' 
    } 
} 

注:RDFカスタムMIMEタイプを定義したり、フォームを記述することのできる一般的なMIMEタイプ(例えば、コレクション+ JSON)を使用する必要があり、またはタイプ(これはHydraのようなRESTのvocabをサポートしています) - aka。統一されたインタフェース/ Iは、例えば、以来、そこに利用可能なアクションを表現したいと思います自己記述のメッセージ

、 注文をキャンセルすること(「完了」状態)は常に可能ではありません。

操作が利用できない場合は、その操作を指すリンクを送信しないでください。

0

ステータス遷移が常に利用可能なわけではない、papercowboyの回答に加えて、リソースとして現在可能なものを文書化することができます。

/order/:id/availableStates 

{ 
    "availableStates": [ 
     {"status": "cancelled"} 
    ] 
} 
関連する問題