我正在研究处理消息的监控系统。消息处理管道如下: 新的 - >正在进行中 - >已处理 - >删除(历史)
系统必须能够:
我无法设计包含名词的RESTful URI,而不是动词。我很难在这个系统中找到正确的资源。
最简单的方法是使用像
这样的URIhost/messages/new
host/messages/processing
host/messages/processed
host/messages/removed
但它不是REST,因为 - 这仍然是相同的消息,但具有不同的字段值,它们不是新实体 - 我使用动词来识别状态,而不是资源
所以问题是如何在这里应用REST设计? 我很难想象处理对象状态监视的系统的REST设计。
我很感谢你对这个主题的想法和建议。
答案 0 :(得分:-1)
首先,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
或POST
。这也必须在新的或扩展的媒体类型中定义,并且可能由registering it with IANA提供给其他客户端,以便允许其他供应商在其框架中实现此媒体类型,从而允许其他客户端也可以使用这种媒体类型。
在创建新的媒体类型之前,您应该check the registered media types如果已经有类似的东西可以使用或进一步扩展。
请注意,他只是一个建议。由于REST不是协议,而只是一种架构风格,如果正确遵循,则允许分布式系统中的客户端与服务器API分离。如果您为自己的Web API维护自己的客户端,您当然可以按照自己的方式进行操作,但您可能应该将您的服务注释为简单的Web API并避免使用&#34;营销术语&#34; REST进一步。