我正在使API更加RESTful。目前我有一个像这样的端点:
/booking?bookingid=123
我已将端点更新为更加RESTful,如下所示:
/bookings/123
预订看起来有点像这样:
{
"bookingId":123,
"people":[
{
"personId":0,
"name":{
"forename":"Jon",
"surname":"Smith"
}
},
{
"personId":1,
"name":{
"forename":"Sarah",
"surname":"Jones"
}
}
]
}
如果预订中包含特定姓氏,我只想退回预订,如果预订中不存在姓氏,则返回Not Found。
我希望实现这一点的方法是添加一个查询字符串:
/bookings/123?surname="Jones"
这将返回上面的预订,因为Sarah的姓氏是" Jones"预订也将返回一个查询字符串姓氏,其值为" Smith"。
我遇到的第一个问题是,如果将姓氏的属性添加到预订对象中,看起来该查询与此相反,而我遇到的另一个问题是它是'查询单个实体而不是列表,这是一个RESTful方法,如果不是那么什么是更好的方法?
答案 0 :(得分:3)
社区不同意“RESTful”的定义。
与“RESTful”定义最接近的是Roy T. Fielding的Architectural Styles and the Design of Network-based Software Architectures,引入术语“REST”的论文。本论文中没有一个关于如何构建“RESTful”URL的单词。相反,我们的想法是服务器选择哪个URL方便,然后在超媒体链接中明确地将它们传达给客户端。在这种“RESTful”系统中,/booking?bookingid=123
是一个非常好的网址,/_content/AcmeWebApi.dll?ENDPOINT=booking&ID=123&tc=y
也是如此。
然而,在这篇论文(和“REST”这个术语)得到广泛认可之后,社区很快就从“REST”的概念转向了一系列其他的,相互矛盾的“REST是什么”的想法“,great dismay of Roy T. Fielding。
因此,您的问题无法得到有效回答。
考虑“RESTfulness”是否真的是您要优化的属性,或者您是否正在使用其他属性,例如:
并且每个都可能需要不同的URL设计。
答案 1 :(得分:1)
使用查询参数过滤掉单个资源并不常见,但它符合the spec。您可能希望自己的过滤器名称为?person-surname=
,以便以后保持灵活性。您还可以考虑过滤集合(/bookings?person-surname=
)并返回所有匹配的预订更有意义。
答案 2 :(得分:1)
当你通过id(即/ booking / 123 /)直接访问资源时,查询可能不是最好的选择。当你指定资源的UID [你知道肯定存在]并且期望“未找到”时,它们是不一致的。
我建议使查询更加统一,并保留在单个url参数中添加越来越多参数的规定。
/bookings?query="param1=value1 AND param2=value2"
在上面当然编码URL参数将是最佳选择,因此它将是
/bookings/123?query="param1%3Dvalue1%20AND%20param2%3Dvalue2"
这里param1可以是您的预订ID,其值为123,而param2可以是您需要的姓氏。
现在问题是param2(即姓氏)不是资源的直接属性,因此您需要考虑使用以下作为更加改进的版本。
/bookings?query="bookingId=123 AND people.surname=myname" // in your case people.name.surname
另请注意,您需要上面的param1和param2,就好像您只是传递第二个param booking.people.name.surname,有人可以预期它将返回所有带有人姓的预订值。