我知道我很晚了,但也许我的想法可以帮助别人......
我的解决方案有点不同。
我将资源存储在每个资源的单个 uri(统一资源标识符)中。
用户
GET /user => INDEX
PUT /user => CREATE (RETURN LOCATION HEADER)
GET /user/{id} => FIND
POST /user/{id} => UPDATE
DELETE /user/{id} => REMOVE
留言
GET /user/{id}/message => INDEX
PUT /user/{id}/message => CREATE (RETURN LOCATION HEADER)
GET /user/{id}/message => FIND
POST /user/{id}/message/{id} => UPDATE
DELETE /user/{id}/message/{id} => REMOVE
朋友们
GET /user/{id}/friend => INDEX
PUT /user/{id}/friend => CREATE (RETURN LOCATION HEADER)
GET /user/{id}/friend => FIND
POST /user/{id}/friend/{id} => UPDATE
DELETE /user/{id}/friend/{id} => REMOVE
生成的内容类型可以通过客户端需要指定的HTTP-Header进行更改。
Accept: "application/vnd.com.example.api+json; version: 1.0;"
当前是Accept HTTP-Header字段,它告诉服务器要使用哪个版本和哪个内容类型。
为了保持浏览器或代理缓存功能,我决定在我的 api 上返回Vary HTTP Header字段,其中所有内容都在更改HTTP-Headers,以便浏览器可以通过uri 和 headers正确区分资源。
Vary: "Accept, Accept-Language"
最大的问题是,如何组合资源以防止客户端一次打开过多的 tcp 连接。
例如:如果您通过/user从我的 API 查询用户列表,API 将返回所需内容类型(JSON、XML、HTML)的用户对象数组。
我不会详细介绍,因为有可用的分页和过滤器/搜索支持。
每个用户对象都具有依赖资源,例如朋友和/或消息。
有一个非常好的结构化标准,称为HAL(超文本应用程序语言),它提供了一些简单的方法来将资源与其相关资源或链接资源结合起来。它使用 JSON 来表示数据。
看看Mike Kelly的http://stateless.co/hal_specification.html。
但是该解决方案也不会在一次调用中组合资源,它只是将依赖或链接资源的 uri 与有效负载一起发送到客户端。
这将让客户决定显示哪些附加信息。
当然,所有非常重要的缓存功能都在工作。
大多数流量,在浏览资源时,将是可以很容易缓存的重复请求。
如果您给出的示例想要在用户列表中显示用户的朋友数或消息数,请考虑将依赖资源添加为结果的键。
示例用户响应 (JSON)
{
id: 1,
email: test@test.com,
...
friends: {
count: 1,
_links: [{
'id': '2',
'name': 'Peter Parker',
'uri': '//api.example.com/user/2'
}]
},
messages: {
count: 1,
_links: [{
'id': 'x4gZ6',
'subject': 'Testmessage',
'uri': '//api.example.com/user/1/message/x4gZ6'
}]
},
...
}
现在我们来谈谈如何防止使用多个 TCP 连接!
有一个非常简单和好的方法......
为什么不使用:
Connection: "keep-alive"
这将使客户端能够根据需要一次查询尽可能多的资源。虽然所有资源都通过与服务器的单个 TCP 连接进行查询。
我知道保持活动连接还有其他问题,因此请随时与我讨论所有想法。
谢谢!