如何设计RESTful搜索/过滤?
我目前正在用PHP设计和实现一个RESTful API。 但是,我一直未能实现我的初始设计。
GET /users # list of users
GET /user/1 # get user with id 1
POST /user # create new user
PUT /user/1 # modify user with id 1
DELETE /user/1 # delete user with id 1
到目前为止相当标准,对吧?
我的问题是第一个GET /users
。 我正在考虑发送请求主体中的参数来过滤列表。 这是因为我想能够指定复杂的过滤器而不需要获取超长的url,例如:
GET /users?parameter1=value1¶meter2=value2¶meter3=value3¶meter4=value4
相反,我想有这样的东西:
GET /users
# Request body:
{
"parameter1": "value1",
"parameter2": "value2",
"parameter3": "value3",
"parameter4": "value4"
}
这是更可读性,并给你很大的可能性来设置复杂的过滤器。
无论如何, file_get_contents('php://input')
没有返回GET
请求的请求正文。 我也试过http_get_request_body()
,但我使用的共享主机没有pecl_http
。 不知道这会有什么帮助。
我发现这个问题,并意识到GET可能不应该有一个请求主体。 这有点不确定,但他们反对。
所以现在我不知道该怎么做。 你如何设计一个RESTful搜索/过滤功能?
我想我可以使用POST
,但这看起来不是很RESTful。
实现RESTful搜索的最佳方式是将搜索本身视为资源。 然后,您可以使用POST动词,因为您正在创建搜索。 为了使用POST,您不必在数据库中逐字创建某些内容。
例如:
Accept: application/json
Content-Type: application/json
POST http://example.com/people/searches
{
"terms": {
"ssn": "123456789"
},
"order": { ... },
...
}
您从用户的角度创建搜索。 这个的实现细节是不相关的。 一些RESTful API甚至可能不需要持久性。 这是一个实现细节。
如果您在GET请求中使用请求正文,那么您打破了REST原则,因为您的GET请求将无法被缓存,因为缓存系统仅使用URL。
更糟糕的是,您的网址不能加入书签,因为该网址并未包含将用户重定向到此页面所需的全部信息
使用URL或Query参数而不是请求主体参数。
例如:
/myapp?var1=xxxx&var2=xxxx
/myapp;var1=xxxx/resource;var2=xxxx
实际上,HTTP RFC 7231说:
GET请求消息中的有效载荷没有定义的语义; 在GET请求上发送有效内容主体可能会导致一些现有的实现拒绝请求。
欲了解更多信息,请看这里
似乎资源过滤/搜索可以用RESTful方式实现。 这个想法是引入一个名为/filters/
或/api/filters/
的新端点。
使用这个端点过滤器可以被认为是一个资源,因此通过POST
方法创建。 这种方式 - 当然 - body可以用来承载所有参数以及可以创建复杂的搜索/过滤器结构。
创建这样的过滤器后,有两种可能性来获得搜索/过滤结果。
具有唯一ID的新资源将与201 Created
状态码一起返回。 然后使用此ID可以对/api/users/
like发出GET
请求:
GET /api/users/?filterId=1234-abcd
在通过POST
创建新过滤器POST
,它将不会回复201 Created
但会立即使用303 SeeOther
以及Location
标题指向/api/users/?filterId=1234-abcd
。 这个重定向将通过底层库自动处理。
在这两种情况下都需要两个请求来获得过滤结果 - 这可能被认为是一个缺点,特别是对于移动应用程序。 对于移动应用程序,我会使用单个POST
调用/api/users/filter/
。
如何保留创建的过滤器?
它们可以存储在数据库中并在以后使用。 它们也可以存储在一些临时存储中,例如redis,并且有一些TTL,在它们过期之后将被删除。
这个想法的优点是什么?
过滤器,过滤结果可以缓存,甚至可以书签。
链接地址: http://www.djcxy.com/p/7045.html