资源URL中的RESTful查询字符串

资源URL中的RESTful查询字符串,rest,restful-architecture,restful-url,api-design,Rest,Restful Architecture,Restful Url,Api Design,我正在使API更加RESTful。目前,我有这样一个端点: /booking?bookingid=123 /bookings/123 { "bookingId":123, "people":[ { "personId":0, "name":{ "forename":"Jon", "surname":"Smith" } }, {

我正在使API更加RESTful。目前,我有这样一个端点:

/booking?bookingid=123
/bookings/123
{
   "bookingId":123,
   "people":[
      {
         "personId":0,
         "name":{
            "forename":"Jon",
            "surname":"Smith"
         }
      },
      {
         "personId":1,
         "name":{
            "forename":"Sarah",
            "surname":"Jones"
         }
      }
   ]
}
我已将端点更新为更为RESTful,如下所示:

/booking?bookingid=123
/bookings/123
{
   "bookingId":123,
   "people":[
      {
         "personId":0,
         "name":{
            "forename":"Jon",
            "surname":"Smith"
         }
      },
      {
         "personId":1,
         "name":{
            "forename":"Sarah",
            "surname":"Jones"
         }
      }
   ]
}
预订看起来有点像这样:

/booking?bookingid=123
/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”的查询字符串姓氏


我遇到的第一个问题是,如果一个姓氏属性被添加到booking对象中,它看起来像是针对该属性的查询,而我遇到的另一个问题是它针对单个实体而不是列表进行查询,这是一种RESTful方法吗?如果不是,那么什么是更好的方法?

使用查询参数过滤单个资源并不常见,但它符合。您可能希望您的筛选名称为
?person-Nastname=
,以便以后保留灵活性。您也可以考虑过滤集合是否更有意义(<代码>预订/人姓氏=<代码>)并返回所有匹配的预订。

没有社区同意的“REST”定义。 最接近“RESTful”定义的是Roy T.Fielding,该论文引入了“REST”一词。这篇论文没有一个字是关于如何构造“RESTful”URL的。取而代之的是,服务器选择对其方便的URL,然后通过超媒体链接将它们显式地传递给客户端。在这种“RESTful”系统中,

/booking?bookingid=123
是一个非常好的URL,正如
/\u content/AcmeWebApi.dll?ENDPOINT=booking&ID=123&tc=y
一样

然而,在这篇论文(以及其中的“休息”一词)获得广泛认可后,社区很快就从“休息”的概念转向了一系列关于什么是“休息”或什么不是“休息”的相互冲突的概念,并最终走向了新的领域

因此,你的问题无法得到有效的回答

考虑“restfulity”是否真的是您试图优化的属性,或者您是否在追求其他属性,例如:

  • 客户机实现者易于理解
  • 与已部署组件(如HTTP缓存)的互操作性
  • 服务器将来更改URL的自由
  • 就像X公司的API一样

而且每种方法都可能需要不同的URL设计。

当您直接通过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.姓氏一样。有人可能期望它将返回所有带有个人姓氏和值的预订。

您能详细说明您的问题吗?我有点难以理解为什么要在booking对象中添加一个姓氏属性?@Coder问题不是技术性的,只是我的方法是否是RESTful。@EricStein添加姓氏的示例只是一个假设场景,以展示我对为什么我的方法可能不是RESTful的想法,在这种情况下,我实际上不会这么做,但在某些情况下,属性名称可能是相同的。