我的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结构应该是什么?
答案 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/kitty
,cats/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个结果。