REST资源相关数据

时间:2013-12-17 23:15:00

标签: rest restful-url restful-architecture

我已经创建了一个REST API,我认为我遇到了RESTful问题。

它与以下问题有关:

我有一个名为"案例"的资源。案例还有相关数据,如用户和消息。 问题是我想从案例中获取相关的查询用户和消息数据,但我不确定URI设计。还有不同种类的相关/计算数据。这些相关数据应该用于创建数据可视化。

我如何获得案例/用户/消息是RESTful:

http://example.com/cases (and with id for a single case)
http://example.com/cases/{id}/users (same idea as above)
http://example.com/cases/{id}/messages (same idea as above)

我首先考虑创建相关资源(我认为URI看起来不对,它可能会有点RPC?):

相关数据1:

http://example.com/cases/{id}/analysis/messages-network-traffic

{
    "sender": "an user jack", 
    "receiver": "an user steph", 
    "amount_messages": 51
}, 
{
    "sender": "an user test", 
    "receiver": "an user test4", 
    "amount_messages": 3
}
...

相关数据2:

http://example.com/cases/{id}/analysis/messages-timeline?receiver=testuser1&sender=testuser2
{
    "amount_messages": 24, 
    "timestamp": 1387321576
}, 
{
    "amount_messages": 50, 
    "timestamp": 1387321576
}
...

这些对URI设计的正确思考(我认为它是那种RPC),或者我应该怎么做? 因为我没有看到任何理由创建报告资源,如相关问题。数据只是对现有资源的计算。

提前谢谢。

3 个答案:

答案 0 :(得分:3)

仅仅因为可以提供实现并不意味着这样做是有意义的。例如,在http://example.com/cases上执行PUT可能没有意义。你会改为http://example.com/cases/1或类似的东西。一个特定的例子。同样,在http://example.com/cases/1上执行POST可能也没有意义。您可以使用REST的语法来决定应用程序的语义。

我认为您的REST设计没有任何问题 - 只要端点以“声明”方式命名,那么就可以了。如果他们有一些“程序”名称,例如:http://example.com/cases/goDoSomething,那将引起关注。

请记住,您的REST设计是您的客户用来与您的服务进行交流的“语言”,因此请设计该语言,以便通信具有声明性并适合手头的任务。为USERS设计,而不是为了您自己在后端的便利。

答案 1 :(得分:2)

我意识到你已经在这里接受了答案,但我觉得这两个答案都错过了一点。

为您的问题设计一个RESTful解决方案 nothing 与您的URL看起来一样所有与提供关系链接作为表示本身的一部分。您需要使用允许您表达这些链接关系的媒体类型。 HTML确实如此,但XML和JSON本身并不存在。我个人最喜欢的是HAL over JSON。

以下是使用HAL over JSON的示例:

请求:

GET /cases/1 HTTP/1.1
Host: example.com

<强>响应:

HTTP/1.1 200 OK
Content-Type: application/hal+json;profile=vnd/com.example-v1

{
  _links: {
    "self": {
      href: "/cases/1"
    },
    "users": {
      href: "/cases/1/users"
    },
    "newest_user": {
      href: "/users/371629"
    },
    "messages": {
      href: "/cases/1/messages"
    }
  },
  "case-name": "Foo",
  "case-created-date": "2013-11-01"
  ..... <more case attributes here>
} 

请注意,指向“newest_user”的链接指向单个用户,并且该引用是不透明的(即,如果服务器没有为您提供该值,您将无法猜测它)。从技术上讲,在这样的架构中,所有URL都应该被视为不透明(即使其中一些URL是人类可读的并且以resource/id/subresource方式组织)。

因此,当您编写API指南时,您可以指定每个链接关系的含义(本例中为users,newest_user和messages),客户端将知道他们在每个链接后获得的内容,无论URL是什么样的

顺便说一下,这种类型的信息在REST世界中被称为超媒体作为应用程序状态的引擎,a.k.a。“超媒体约束”。这是REST的统一接口约束的要求。

答案 2 :(得分:0)

您的这些网址似乎很好:

  

http://example.com/cases(以及单个案例的ID)

     

http://example.com/cases/ {id} / users(与上述相同)

     

http://example.com/cases/ {id} / messages(与上述相同)

就你的相关数据以及如何查询它们而言,我建议首先你应该决定返回数据结构,考虑到在这两种情况下你都要返回“消息”这一事实(尽管有些不同)数据)。我要做的是,对于两个相关的资源网址,我会有一个共同的json结构

  

{“sender”:“用户测试”,

     

“receiver”:“用户test4”,

     

“amount_messages”:3,

     

“timestamp”:12312421424}

我的资源网址看起来有点像这样:

  

获取http://example.com/cases/ {id} / messages

     

获取http://example.com/cases/ {id} / messages?receiver = testuser1&amp; sender = testuser2

我不明白网址中“/ analysis”的原因。它有点多余(除非当然有一个非常具体的原因)。将要使用您的api的客户希望返回数据是通用的,特别是当他们尝试对同一资源进行过滤查询时。在你的情况下,我们要么列出“消息流量”(我称之为列出“所有消息”)或列出“消息流量”WHERE发送者是FOO而接收者是BAR(我将调用过滤“所有消息”数据)发件人和收件人信息。

保持返回数据模型的一致性有助于客户端开发人员生成POJO(在java版本中)和/或一致的数据模型。

我希望这有帮助!祝你好运!