我正在寻找关于RESTful API的URI设计的一些方向。我将有几个嵌套的链接资源,目前我的URI设计类似于这篇文章:Hierarchical RESTful URL design
以下示例不是我正在构建的,但我认为很好地说明了我的情况。 (假设节目只能属于一个网络)。
/networks [GET,POST]
/networks/{network_id} [GET,PUT]
/networks/{network_id}/shows [GET,POST]
/networks/{network_id}/shows/{show_id} [GET,PUT]
/networks/{network_id}/shows/{show_id}/episodes [GET,POST]
/networks/{network_id}/shows/{show_id}/episodes/{episode_id} [GET,PUT]
我的情况将进一步增加两个协会,但所有协会都是一对多。我正在考虑把它改成类似的东西:
/networks [GET,POST]
/networks/{network_id} [GET,PUT]
/networks/{network_id}/shows [GET,POST]
/shows [GET]
/shows/{id} [GET,PUT]
/shows/{id}/episodes [GET,POST]
/episodes [GET]
/episodes/{id} [GET,PUT]
我的问题是:
答案 0 :(得分:6)
第二个例子对我来说很好看。 URL描述了资源,并且正在使用正确的HTTP谓词。
如果有意义的话,将多个URL指向同一资源是完全没问题的。但更重要的是,确保资源包含将节目连接到网络的<link />
元素,将节目连接到节目等等。
答案 1 :(得分:1)
URI是“任何可以命名的信息”
您的问题是与域相关的问题,只有知道您使用URI命名的资源的人才能真正回答。
在尝试猜测您的域名时想到的问题是,“show”真的取决于“网络”吗?
您网域中的网络是什么?节目与网络之间的关系是什么?这只是播放节目的人吗?还是更多的是与生产信息有关?
我相信你的榜样2更合适。
答案 2 :(得分:1)
真正的问题是:你的第二个例子是否符合URI标准? URI标准规定,路径包含分层部分,查询包含非分层部分,但是afaik。它没有说明如何在您的情况下设计URI结构。 REST统一接口约束具有HATEOAS部分,这意味着您应该在您的情况下发送回链接,指向上层和下层资源。您应该使用元数据来注释这些链接,这些元数据可以由客户端处理,因此它将知道链接的内容。所以在实践中,URI结构并不重要......
GET /shows/123
{
"label": "The actual show",
"_embedded": {
"episodes": [
{
"label": "The first episode of the actual show",
"_embedded": {
"associations": [
//...
]
},
"_links": {
"self": {
"label": "Link to the first episode of the actual show",
"href": "/episodes/12345"
},
"first": {
"href": "/episodes/12345"
},
"duplicate": {
"href": "/networks/3/shows/123/episodes/12345"
},
"up": {
"label": "Link to the actual show",
"href": "/shows/123"
},
"next": {
"label": "Link to the next episode of the actual show"
"href": "/episodes/12346"
},
"previous": null,
"last": {
"href": "/episodes/12350"
}
}
}//,
//...
]
},
"_links": {
"self": {
"label": "Link to the actual show",
"href": "/shows/123"
},
"duplicate": {
"href": "/networks/3/shows/123"
},
"up": {
"label": "Link to the actual network",
"href": "/networks/3"
},
"collection": {
"label": "Link to the network tree",
"href": "/networks"
},
"next": {
"label": "Link to the next show in the actual network",
"href": "/shows/124"
},
"previous": {
"label": "Link to the previous show in the actual network",
"href": "/shows/122"
}
}
}
现在这只是具有IANA链接关系的HAL + JSON中的测试版,但您也可以使用带有RDF词汇表的JSON-LD(例如schema.org + hydra)。这个例子只是关于层次结构(up,first,next,previous,last,collection,item等),但你应该添加更多的元数据,例如哪个链接指向一个网络,一个节目,一个节目,等等...所以你的客户将从元数据知道内容是什么,例如,他们可以使用链接自动导航。这就是REST的工作原理。所以URI结构对客户来说并不重要。 (如果您想让响应更紧凑,也可以使用紧凑的URI和URI模板。)
答案 3 :(得分:0)
考虑到以下层次结构中存在一对多关系:
network --> shows --> episodes
我认为第二种设计没有向服务器端提供足够的信息来处理您的请求。例如,如果您有以下数据:
Network id show_id episode_id
1 1 1
1 2 1
1 1 2
第一个详细设计将在HTTP请求中提供足够的信息来获取数据:/networks/1/shows/1/episodes/1
第二种设计恰恰相反:
/episodes/1
在第二种设计中,服务器端无法知道您的数据是否意味着第1行或第2行
回答你的问题:
IMHO第二个设计可能不是您的示例的有效REST设计。一个 解决方法可能是传递查询参数
我认为设计1是自给自足的
更新:请忽略我上面的回答
此外:
/networks
/networks/{id}
/shows
/shows/{id}
/episodes
/episodes/{id}
应该有足够数量的REST URL
或换句话说,以下网址将是多余的:
/networks/{network_id} [GET,PUT]
/networks/{network_id}/shows [GET,POST]
/shows/{id}/episodes [GET,POST]
答案 4 :(得分:0)
我认为我们应该尽可能简单地保持REST API URL。
e.g。 https://www.yoursite.com/api/xml/1.0/
这里我以1.0版的XML API为例。请记住使用API的版本以供将来更新。
您可以查看客户请求的方法。
e.g. tag
<method>getEpisodes</method>
答案 5 :(得分:0)
我认为第二个选项是Ok,但如果你想验证关系,我会考虑第一个选项。例如,当您获得具有不同网络的剧集时,可能意味着该剧集在您的请求之前被修改了,因此您可能需要使用422响应,对于其他服务也是如此。有了这个,您可以确定您想要工作的实体是否涉及其父实体。
PD:抱歉我的英文。