用于消息监控系统的rest api URI设计

时间:2017-10-21 17:13:38

标签: rest api-design

我正在研究处理消息的监控系统。消息处理管道如下: 新的 - >正在进行中 - >已处理 - >删除(历史)

系统必须能够:

  • 请求所有消息和唯一标识符
  • 修改它们(我的意思是标记为已处理,标记为已删除等)
  • 使用消息字段过滤器进行搜索(例如,按消息搜索 所有者)

我无法设计包含名词的RESTful URI,而不是动词。我很难在这个系统中找到正确的资源。

最简单的方法是使用像

这样的URI
host/messages/new
host/messages/processing
host/messages/processed
host/messages/removed

但它不是REST,因为 - 这仍然是相同的消息,但具有不同的字段值,它们不是新实体 - 我使用动词来识别状态,而不是资源

所以问题是如何在这里应用REST设计? 我很难想象处理对象状态监视的系统的REST设计。

我很感谢你对这个主题的想法和建议。

1 个答案:

答案 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)提供了一些您可以在链接关系名称中使用的其他字段。如果这不足以满足您的需求,您必须通过为链接添加新字段来扩展媒体类型,这些链接指定应使用PUTPATCHPOST。这也必须在新的或扩展的媒体类型中定义,并且可能由registering it with IANA提供给其他客户端,以便允许其他供应商在其框架中实现此媒体类型,从而允许其他客户端也可以使用这种媒体类型。

在创建新的媒体类型之前,您应该check the registered media types如果已经有类似的东西可以使用或进一步扩展。

请注意,他只是一个建议。由于REST不是协议,而只是一种架构风格,如果正确遵循,则允许分布式系统中的客户端与服务器API分离。如果您为自己的Web API维护自己的客户端,您当然可以按照自己的方式进行操作,但您可能应该将您的服务注释为简单的Web API并避免使用&#34;营销术语&#34; REST进一步。