我目前正在用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方式实现。其思想是引入一个名为/filters/或/api/filters/的新端点。
使用这个端点过滤器可以被认为是一个资源,因此可以通过POST方法创建。当然,通过这种方式,body可以用来携带所有的参数,也可以创建复杂的搜索/过滤结构。
在创建这样的过滤器之后,有两种可能获得搜索/过滤器结果。
将返回一个具有唯一ID的新资源以及201已创建状态代码。然后使用这个ID可以向/api/users/ like发出GET请求:
得到/ api /用户/ ?filterId = 1234 - abcd
通过POST创建新过滤器后,它不会回复201 created,而是立即回复303 SeeOther,并附上指向/api/users/?filterId=1234-abcd的Location头。此重定向将通过底层库自动处理。
在这两种情况下,都需要发出两个请求来获得过滤后的结果——这可能被认为是一个缺点,特别是对于移动应用程序。对于移动应用程序,我将使用单个POST调用/api/users/filter/。
如何保持创建的过滤器?
它们可以存储在DB中,以后使用。它们也可以存储在一些临时存储器中,例如redis,并有一些TTL,在此之后它们将过期并被删除。
这个想法的优点是什么?
过滤器,过滤的结果是可缓存的,甚至可以收藏。
资源过滤/搜索似乎可以以RESTful方式实现。其思想是引入一个名为/filters/或/api/filters/的新端点。
使用这个端点过滤器可以被认为是一个资源,因此可以通过POST方法创建。当然,通过这种方式,body可以用来携带所有的参数,也可以创建复杂的搜索/过滤结构。
在创建这样的过滤器之后,有两种可能获得搜索/过滤器结果。
将返回一个具有唯一ID的新资源以及201已创建状态代码。然后使用这个ID可以向/api/users/ like发出GET请求:
得到/ api /用户/ ?filterId = 1234 - abcd
通过POST创建新过滤器后,它不会回复201 created,而是立即回复303 SeeOther,并附上指向/api/users/?filterId=1234-abcd的Location头。此重定向将通过底层库自动处理。
在这两种情况下,都需要发出两个请求来获得过滤后的结果——这可能被认为是一个缺点,特别是对于移动应用程序。对于移动应用程序,我将使用单个POST调用/api/users/filter/。
如何保持创建的过滤器?
它们可以存储在DB中,以后使用。它们也可以存储在一些临时存储器中,例如redis,并有一些TTL,在此之后它们将过期并被删除。
这个想法的优点是什么?
过滤器,过滤的结果是可缓存的,甚至可以收藏。