MeV*_*MeV 8 api rest json api-design hateoas
我正在使用apiary创建一些API ,因此使用的语言是JSON.
我们假设我需要代表这个资源:
{
"id" : 9,
"name" : "test",
"customer_id" : 12,
"user_id" : 1,
"store_id" : 3,
"notes" : "Lorem ipsum example long text"
}
Run Code Online (Sandbox Code Playgroud)
难道是正确的根据ID引用其他资源(12,1,3),或者我应该指定这些资源的URL(即/customers/12,/users/1,/stores/3)?
我没有使用HATEOAS,我有点困惑.
sta*_*ica 18
请在您的回复中包含绝对实体URI(例如/customers/12甚至http://www.example.com/customers/12).
不要12在响应中仅包含实体的ID(例如),因为这样会强制客户端自己组合资源URI.为了做到这一点,他们需要事先知道有什么URI,并且你失去了对服务器端URI空间的控制.
(如果服务器指示客户端如何,例如通过发送URI模板和ID,那么客户端将URI放在一起就可以了;但如果它这样做,它也可以发送生成的URI.)
Roy T.Fielding(REST的创始人)的文章"REST API必须由超文本驱动".特别注意这两个要点:
- "应输入REST API,除了初始URI(书签)之外没有任何先验知识."
- "REST API不能定义固定资源名称或层次结构(客户端和服务器的明显耦合).服务器必须能够自由控制自己的命名空间.相反,允许服务器指示客户端如何构造适当的URI [.]"
HAL,指定将相关资源的链接放入响应的标准方法.
JSON API - "用于在JSON中构建API的规范"
上述建议不仅适用于其他资源的ID(即您的"外键" customer_id); 你也将资源自己id变成了一个所谓的"自我链接"; 看到SO问题"超媒体API中自我链接的重要性是什么?" .
例:
您的原始资源可以按如下方式重新设计:
{
"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"
}
}
}
Run Code Online (Sandbox Code Playgroud)
有几点需要注意:
type,id,links.type可能似乎有点redudant; 通常,你隐含地知道期望什么样的对象.此属性可以帮助验证,还使您有机会区分对象类型和角色(例如,上例中的cashieris-a user).我看过其他流行的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"
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8098 次 |
| 最近记录: |