我正在使用apiary创建一些API,因此使用的语言是JSON。
我们假设我需要代表这个资源:
{
"id" : 9,
"name" : "test",
"customer_id" : 12,
"user_id" : 1,
"store_id" : 3,
"notes" : "Lorem ipsum example long text"
}
通过ID(12
,1
,3
)引用其他资源是否正确,或者我应指定这些资源的网址(即/customers/12
,/users/1
,/stores/3
)?
我没有使用HATEOAS而且我有点困惑。
答案 0 :(得分:15)
DO 在您的回复中包含absolute个实体URI(例如/customers/12
甚至http://www.example.com/customers/12
)。
不要在响应中只包含实体的ID(例如12
),因为这样会迫使客户自己将资源URI放在一起。为了做到这一点,他们需要事先知道有什么URI,并且你失去了对服务器端URI空间的控制。
(如果服务器指示客户端如何,例如通过发送URI template以及ID,那么将客户端放在一起就可以了;但如果它这样做,它也可以发送结果URI 。)
Article "REST APIs must be hypertext-driven" by Roy T. Fielding(REST的发起人)。特别注意这两个要点:
- “应输入REST API,除了初始URI(书签)之外没有任何先验知识。”
- “REST API不能定义固定资源名称或层次结构(客户端和服务器的明显耦合)。服务器必须能够自由控制自己的命名空间。相反,允许服务器指示客户端如何构造适当的URI [。]“
HAL,指定将相关资源的链接放入回复的标准方法。
JSON API - “使用JSON构建API的规范”
以上建议不仅适用于其他资源的ID(即“外键”,例如您的customer_id
);你也将资源自己的id
变成了所谓的“自我链接”;请参阅SO question "What is the importance of the self link in hypermedia APIs?"。
示例:强>
您的原始资源可以按照以下方式重新设计:
{
"type": "foobar",
"id": "9",
"links": {
"self": "//example.com/foobars/9"
},
"cashier": {
"type": "user",
"id": "1",
"links": {
"self": "//example.com/users/1"
}
},
"customer": {
"type": "customer",
"id": "12",
"links": {
"self": "//example.com/customers/12"
}
},
"name" : "test",
"notes" : "Lorem ipsum example long text",
"store": {
"type": "store",
"id": "3",
"links": {
"self": "//example.com/stores/3"
}
}
}
有几点需要注意:
type
,id
,links
。 type
似乎有点减少;通常,你隐含地知道期望什么样的对象。此属性可以帮助验证,还使您有机会区分对象类型和角色(例如,上例中的cashier
是一个user
。)答案 1 :(得分:5)
我看过其他流行的API(Facebook,Spotify),我相信以下是最好的方法:
{
"id" : 9,
"name" : "test",
"customer" : {
"id": 12,
"href": "/customers/12"
},
"user" : {
"id": 1,
"href": "/users/1"
},
"store" : {
"id": 3,
"href": "/stores/3"
},
"notes" : "Lorem ipsum example long text"
}