首先,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) –