为简单起见,假设我有一个资源users。HTTP 调用GET users/返回具体用户的链接列表:
<users>
<link rel='user' href='/users/user/1/'/>
<link rel='user' href='/users/user/2/'/>
<link rel='user' href='/users/user/3/'/>
....
</users>
结果表示在特定的媒体类型中描述:
application/vnd.company.Users+xml
在我们的前端,我们希望显示一个包含所有用户的表格。这意味着我们需要能够获取要显示的用户信息,例如姓名、性别、朋友……我想避免我们需要为每个用户单独请求(GET /users/user/x/)检索此信息。另外,有些前端只会显示名字,而有些前端会显示名字和他/她的朋友。等等。
从本质上讲,我们仍然在返回用户,但根据前端的需求进行扩展。
你会选择哪个选项?为什么?
(1) 通过参数使GET 用户/可定制,以便列出定制。根据自定义,可能会返回不同的媒体类型,因为一个版本/组合的语法可能与另一个版本/组合的语法大不相同:
GET users/ -> application/vnd.company.Users+xml
GET users/?fields=name,gender -> application/vnd.company.Users+xml
GET users/?fields=name,gender,friends -> application/vnd.company.UsersWithFriends+xml
(2)创建不同的资源来区分不同的媒体类型。参数仍用于媒体类型涵盖的基本自定义。这给出了:
GET users?fields=name -> application/vnd.company.Users+xml
GET users?fields=name,gender -> application/vnd.company.Users+xml
GET users_with_friends?fields=gender -> application/vnd.company.UsersWithFriends+xml
(3) 同(1),但不是参数,而是由客户端在Accept头中设置所需的媒体类型。媒体类型涵盖的可自定义字段仍然通过参数设置:
GET users/?fields=name ACCEPT application/vnd.company.Users+xml
GET users/?fields=name,gender ACCEPT application/vnd.company.Users+xml
GET users/?fields=name,gender ACCEPT application/vnd.company.UsersWithFriends+xml
(4) 还有什么?
为了回答我自己的问题,我认为:
- 解决方案(1)是非常非常错误的。媒体类型不能依赖于参数。
- 解决方案 (2) 和 (3) 或多或少相等且取决于偏好。我更喜欢(3),因为这不会引入要引入的资源的爆炸式增长。此外,本质上我们仍然是回访用户。唯一的区别是返回的信息量,由不同的媒体类型反映。因此,有人可能会争辩说,没有真正需要像(2)中所做的那样引入新资源。
你同意吗?你怎么看?