我已经创建了一个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),或者我应该怎么做? 因为我没有看到任何理由创建报告资源,如相关问题。数据只是对现有资源的计算。
提前谢谢。
答案 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版本中)和/或一致的数据模型。
我希望这有帮助!祝你好运!