RESTful API - URI结构建议

时间:2014-09-03 06:26:57

标签: api rest restful-url

我的REST API URL结构类似于:

/api/contacts                 GET          Returns an array of contacts
/api/contacts/:id             GET          Returns the contact with id of :id
/api/contacts                 POST         Adds a new contact and return it with an id added
/api/contacts/:id             PUT          Updates the contact with id of :id
/api/contacts/:id             PATCH        Partially updates the contact with id of :id
/api/contacts/:id             DELETE       Deletes the contact with id of :id

我的问题是:

/api/contacts/:id             GET

假设除了通过ID获取联系人之外,我还想通过一个唯一的别名来获取它。

如果我希望能够通过ID或别名获取联系人,那么URI结构应该是什么?

4 个答案:

答案 0 :(得分:4)

如果你的别名不是数字我会建议使用相同的URI结构,并确定它是你的ID或别名。就像Facebook使用username和user_id一样。 facebook.com/user_id或facebook.com/username。

另一种方法是让客户端使用带有一些额外GET参数的GET / contacts作为过滤器来首先搜索联系人,然后从该响应中查找ID。

我认为最后一个选项是使用像GET / contacts / alias /:alias这样的结构。但这有点意味着别名是联系的子资源。

答案 1 :(得分:2)

IRI的路径和查询部分取决于您。路径用于分层数据,如api/version/module/collection/item/property,查询用于非分层数据,如?display-fields="id,name,etc..."?search="brown teddy bear"&offset=125&count=25等等。

您必须记住,您正在使用资源而不是操作。因此,IRI是资源标识符,如DELETE /something,而不是操作标识符,如POST /something/delete。您不必遵循IRI的任何结构,例如,您可以简单地使用POST /dashuif328rgfiwa。服务器会理解,但为这种IRI编写路由器要困难得多,这就是我们使用好的IRI的原因。

单个IRI始终只属于单个资源的重要性。因此,您无法使用GET /cats/123读取cat属性,并使用PUT /cats/123编写dog属性。 ppl通常不理解的是,单个资源可以有多个IRI,例如/cats/123/cats/name:kitty/users/123/cats/kittycats/123?fields="id,name"等等...到相同的资源。或者如果你想给一个东西(活猫,而不是描述它的文件)提供一个IRI,那么你可以使用/cats/123#thing/users/123#kitty等...你通常在RDF中这样做文档。

  

如果我希望能够获取联系人,那么URI结构应该是什么   通过ID或Alias?

它可以是/api/contacts/name:{name},例如/api/contacts/name:John,因为它显然是分层的。或者您可以检查参数是否包含/api/contacts/{param}中的数字或字符串。

您也可以使用该查询,但我不建议这样做。例如,以下IRI可以有两个不同的含义:/api/contacts?name="John"。您希望列出名称为John的每个联系人,或者您想要一个确切的联系人。因此,您必须在服务器端应用程序的路由器中对此类请求做出一些约定。

答案 2 :(得分:1)

当您尝试使用别名解析资源时,我会考虑添加“搜索”资源:

GET /api/contacts/:id

GET /api/contacts?alias=:alias

GET /api/contacts/search?q=:alias

答案 3 :(得分:1)

首先,URL中的“ID”不必是数据库生成的数字ID。您可以使用URL中的任何数据(包括别名),只要它是唯一的。当然,如果您在任何地方都使用数字ID,那么在您的联系人API中执行相同操作会更加一致。但您可以选择使用别名而不是数字ID(只要它们始终是唯一的)。

另一种方法是,如Stromgren建议的那样,允许在URL中同时使用数字ID和别名:

/api/contacts/123
/api/contacts/foobar

但是如果别名可以是数字,这显然会导致问题,因为那样你就无法区分ID和(数字)别名。

最后但并非最不重要的是,您可以实施一种过滤整个集合的方法,如shlomi33已经建议的那样。我不会介绍search资源,因为它不是真正的RESTful,所以我会选择其他解决方案:

/api/contacts?alias=foobar

哪个应该将foobar的所有联系人作为别名返回。由于别名应该是唯一的,因此将返回1或0个结果。