首先,RESTful系統不應該花費很多精力來設計URI,而應該專注於媒體類型的創建並使用URI的關係名稱,以便客戶端可以查找其中的含義媒體類型。客戶端本身不驗證或解釋URI,因此並不關心URI的外觀,它只是根據關係名稱根據媒體類型中概述的語義調用URI。
這具有將資源綁定到關係名稱而不是具體URI的優點。如果服務器更改資源的位置,則使用關係名稱而不是URI本身的客戶端仍然能夠處理請求,而不管URI指向的位置如何。
對於您的具體示例,您有一個消息資源和屬於該資源的某個狀態。你如何設計這種關係取決於你。如果您希望消息的實際有效負載不受影響,您可以將狀態信息放在標題中,這些標題基本上是返回文檔的元數據,或者將它們定義在相應消息的子資源中。您也可以使用(或定義您自己的)媒體類型,支持類似於HAL的嵌入資源,允許嵌入屬於某個資源的其他數據。
包含其當前狀態的消息的類HAL表示可能看起來像下面的示例。但請注意,這種表示不是基於實際的媒體類型,也不是完整的。它應該只是想象你可以在你的方法中使用的概念。
{
"_links": {
"self": {
"href": "/api/messages/1234",
"title": "Get the latest version of this message"
},
"states": {
"href": "/api/messages/1234/states",
"title": "List states the message has been in in chronological order"
},
"find": {
"href": "/api/messages{?id,sender,receiver,state}",
"templated": true,
"title": "Find messages"
},
"markAsProcessed": {
"href": "/api/messages/1234/states",
"title": "Mark message as processed",
"type": "application/vnd.your-comp.message-state-update+hal+json"
},
...
},
"sender": "User1",
"receiver": "User2",
...
"_embedded": {
"current_status": {
"_links": {
"self": {
"href": "/api/messages/1234/states/new"
}
}
"type": "new",
"timestamp": "2017-10-21'T'22:25:00Z",
...
}
}
}
在HTML數據要發送到的服務器通常在表現公式(<form>...</form>
)輸入。 HAL沒有明確定義這樣的結構。在擴展媒體類型時,現在可以在媒體類型中定義HTML表單的對應項,或者定義客戶端應該如何處理特定關係名稱的規則集。
在這個簡單的例子中,客戶必須根據數據交換的媒體類型來扣除如何處理某個鏈接關係,如markAsProcessed
。它可以定義調用markAsProcessed
鏈接關係的請求應該向服務器發送包含給定消息的最新狀態信息的PUT
請求。在這種情況下,明確列出發給服務器的請求應該與媒體類型application/vnd.your-comp.message-state-update+hal+json
兼容,它定義了服務器期望的有效載荷的實際語法和語義。
HAL (draft version 08)提供了一些您可以在鏈接關係名稱中使用的其他字段。如果這不足以滿足您的需求,則必須通過添加指定的PUT
,PATCH
或鏈接的新鏈接來擴展媒體類型。這也需要在新的或擴展的媒體類型中定義,並且可能由其他客戶端使用,以便允許其他供應商將這種媒體類型實現到其框架中,從而允許其他客戶端使用這個媒體類型。
但是,在創建新介質類型之前,如果有類似的東西已經可用,您可以使用或進一步擴展,則應該使用check the registered media types。
請注意,他只是一個建議。由於REST不是一種協議,而只是一種架構風格,如果遵循正確的話,它允許分佈式系統中的客戶端與服務器API分離。如果您爲自己的Web API維護自己的客戶端,那麼當然可以遵循自己的接受程序,不過您應該將您的服務標記爲簡單的Web API並進一步避免「營銷術語」REST。
如果downvoter可以解釋他在downvote背後的推理以改善答案,這樣會很好,因爲這裏概述的信息都不是我的知識中的錯誤,而是符合REST思想(而不是與所使用的營銷術語對於Web API) –