RESTful 资源中的查询字符串 URL
RESTful Querystring in Resource URL
我正在制作 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"
}
}
]
}
如果预订包含特定姓氏,我只想 return 预订;如果预订中不存在该姓氏,我希望 return 未找到。
我想要实现的方法是添加一个查询字符串:
/bookings/123?surname="Jones"
这将 return 以上预订,因为 Sarah 的姓是 "Jones" 预订也将 return 使用查询字符串 姓氏 值为 "Smith".
我遇到的第一个问题是,如果 姓氏 的 属性 被添加到预订对象中,看起来查询是针对那个和另一个的我遇到的问题是它针对单个实体而不是列表进行查询,这是一种 RESTful 方法吗?如果不是,那么什么是更好的方法?
使用查询参数过滤掉单个资源并不典型,但它符合the spec。您可能更喜欢将过滤器名称设为 ?person-surname=
,以便以后保持灵活性。您可能还会考虑过滤集合 (/bookings?person-surname=
) 和 return 所有匹配的预订是否更有意义。
没有社区同意的“RESTful”定义。
最接近“RESTful”定义的是 Roy T. Fielding 的 Architectural Styles and the Design of Network-based Software Architectures,这篇论文引入了术语“REST”。这篇论文只字未提“RESTful”URL应该如何构建。相反,这个想法是服务器选择对它方便的 URLs,然后在超媒体链接中明确地将它们传达给客户端。在这种“RESTful”系统中,/booking?bookingid=123
是一个非常好的URL,/_content/AcmeWebApi.dll?ENDPOINT=booking&ID=123&tc=y
也是如此。
然而,在这篇论文(以及与之相关的术语“REST”)获得广泛认可之后,社区很快就从“REST”这个概念转向了一系列其他关于什么是或不是的相互矛盾的想法“REST”,到 great dismay of Roy T. Fielding.
因此,您的问题无法有效回答。
考虑“RESTfulness”是否真的是您要优化的 属性,或者您是否在追求其他一些属性,例如:
- 客户端实施者易于理解
- 与 HTTP 缓存等已部署组件的互操作性
- 服务器在未来URLs的自由更改
- 像 X 公司的 API
并且每个都可能需要不同的 URL 设计。
当您直接通过 ID(即 /booking/123/)访问资源时,事后查询可能不是最佳选择。当您指定资源的 UID [您肯定知道它存在] 并期望 "Not Found" 时,这是不一致的。
我建议使查询更加统一,并保留在单个 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,就像您只传递第二个参数一样 booking.people.name.surname 有人可以预期它会 return 所有带有此人姓氏的预订以及该值。
我正在制作 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"
}
}
]
}
如果预订包含特定姓氏,我只想 return 预订;如果预订中不存在该姓氏,我希望 return 未找到。
我想要实现的方法是添加一个查询字符串:
/bookings/123?surname="Jones"
这将 return 以上预订,因为 Sarah 的姓是 "Jones" 预订也将 return 使用查询字符串 姓氏 值为 "Smith".
我遇到的第一个问题是,如果 姓氏 的 属性 被添加到预订对象中,看起来查询是针对那个和另一个的我遇到的问题是它针对单个实体而不是列表进行查询,这是一种 RESTful 方法吗?如果不是,那么什么是更好的方法?
使用查询参数过滤掉单个资源并不典型,但它符合the spec。您可能更喜欢将过滤器名称设为 ?person-surname=
,以便以后保持灵活性。您可能还会考虑过滤集合 (/bookings?person-surname=
) 和 return 所有匹配的预订是否更有意义。
没有社区同意的“RESTful”定义。
最接近“RESTful”定义的是 Roy T. Fielding 的 Architectural Styles and the Design of Network-based Software Architectures,这篇论文引入了术语“REST”。这篇论文只字未提“RESTful”URL应该如何构建。相反,这个想法是服务器选择对它方便的 URLs,然后在超媒体链接中明确地将它们传达给客户端。在这种“RESTful”系统中,/booking?bookingid=123
是一个非常好的URL,/_content/AcmeWebApi.dll?ENDPOINT=booking&ID=123&tc=y
也是如此。
然而,在这篇论文(以及与之相关的术语“REST”)获得广泛认可之后,社区很快就从“REST”这个概念转向了一系列其他关于什么是或不是的相互矛盾的想法“REST”,到 great dismay of Roy T. Fielding.
因此,您的问题无法有效回答。
考虑“RESTfulness”是否真的是您要优化的 属性,或者您是否在追求其他一些属性,例如:
- 客户端实施者易于理解
- 与 HTTP 缓存等已部署组件的互操作性
- 服务器在未来URLs的自由更改
- 像 X 公司的 API
并且每个都可能需要不同的 URL 设计。
当您直接通过 ID(即 /booking/123/)访问资源时,事后查询可能不是最佳选择。当您指定资源的 UID [您肯定知道它存在] 并期望 "Not Found" 时,这是不一致的。
我建议使查询更加统一,并保留在单个 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,就像您只传递第二个参数一样 booking.people.name.surname 有人可以预期它会 return 所有带有此人姓氏的预订以及该值。