用于在restful API中对结果进行高级过滤的URL设计

时间:2013-08-22 11:52:19

标签: php api http rest search

让我们以您使用PHP构建的restful API建模的资源的通用示例。

  • 车库有多辆车和多个机械师。
  • 一辆车只有一个车库。
  • 机修工有多辆车和多个车库(他是工作狂好的!)。

所以逻辑说我们的端点应该是

/v1/garages  
/v1/garages/1234
/v1/mechanics
/v1/mechanics/1234
/v1/cars
/v1/cars/1234

如果我们想要获得车库1234的所有车辆,我们会使用 GET /v1/garages/1234/cars

如果我们想要车库34中的机械师12的所有车辆,我们会使用 GET /v1/mechanics/12/garage/34/cars

但是如果我们想要车库56和78的所有车呢? 我有一些想法,但我能想到的最好的是 GET /v1/cars?garage=[id=[56,78]]

这将允许我们从任何有黄色油漆和碳帽的车库通过两个或四个门抓住所有绿色汽车 GET /v1/cars?garage=[paint=yellow,bonnet=[material=carbon]]&color=green&doors=[2,4]

这看起来是一个合理的想法,还是我会遇到与嵌套复杂的问题,如果这很容易用PHP解析?

我的另一个想法是Json,据我所知,所有json在网址中都有效,所以

GET /v1/cars?{"color":"green","doors":[2,4],"garage":{"paint":"yellow","bonnet":{"material":"carbon"}}}

这使得开发人员可以非常轻松地使用,因为几乎所有编程语言现在都支持json,而在API端我们只能使用json_decode($_SERVER[''QUERY_STRING])所以使用Json有什么问题吗?

第三个想法“创造一个搜索”

我的意思是我们使用

POST /cars/search使用上面的Json作为发布数据,请求将只返回搜索的ID,然后通过GET /cars/search/{id}将结果提取到这将减轻我的复杂性并避免请求的限制为8kb(这是一个API,不应由浏览器地址栏使用)。但我担心,如果我这样做,那么它会破坏顶级GET /v1/cars端点的目的吗?

1 个答案:

答案 0 :(得分:0)

感谢有帮助的人在#laravel irc channel与我进行了长时间的对话,我们有一个似乎有效的答案。

我们根据以下几点选择了这个答案:

  • 易于人类阅读
  • 查询的力量
  • 平坦度(易于解析)
  • 易于过滤

基本要求是

GET /v1/cars?color=green
            &doors=2,4
            &garage[paint]=yellow
            &garage[bonnet][material]=carbon

与以下代码结合使用时

$query = array();
parse_str($_SERVER['QUERY_STRING'], $query);

吐出一个如下所示的数组,可以在API中轻松迭代以进行过滤:)

Array
(
  [color] => green
  [doors] => 2,4
  [garage] => Array
    (
      [paint] => yellow
      [bonnet] => Array
        (
          [material] => carbon
        )
    )
)