我有一个与REST网址设计相关的问题 . 我在这里找到了一些相关的帖子:Different RESTful representations of the same resource和这里:RESTful url to GET resource by different fields但是回答并不十分清楚最佳做法是什么以及为什么 . 这是一个例子 .
我有用于表示“用户”资源的REST URL . 我可以使用id或电子邮件地址获取用户,但两者的URL表示形式保持不变 . 通过大量的博客和书籍,我看到人们已经以不同的方式做到了这一点 . 例如
在书中和stackoverflow上的某个地方阅读这个练习(我似乎无法再找到链接)
GET /users/id={id}
GET /users/email={email}
在很多博客上阅读这种做法
GET /users/{id}
GET /users/email/{email}
查询参数通常用于过滤网址所代表的资源的结果,但我也看到了这种做法
GET /users?id={id}
GET /users?email={email}
我的问题是,在所有这些实践中,对于使用api的开发人员来说哪一个最有意义?为什么?我相信在REST网址设计和命名约定方面没有任何规则,但我只是想知道应采取哪条路线来帮助开发人员更好地理解apis .
所有帮助赞赏!
3 回答
根据我的经验,
GET /users/{id} GET /users/email/{email}
是最常用的方法 . 如果用户不存在提供的id
或email
,我还希望这些方法返回404 Not Found . 我也不会惊讶地看到GET /users/id/{id}
(虽然在我看来,这是多余的) .关于其他方法的评论
GET /users/id={id} GET /users/email={email}
我没有看到这个,如果我确实看到了它,那将是非常令人困惑的 . 它's almost like it'试图用路径参数模仿查询参数 .
GET /users?id={id} GET /users?email={email}
当你提到使用查询参数进行过滤时,我认为你在头上钉了一针 .
用
id
和email
(例如GET /users?id={id}&email={email}
)调用此资源是否有意义?如果没有,我不会使用这样的单一资源方法 .我希望这种方法可以检索具有可选查询参数的用户列表进行过滤,但我不希望
id
,email
或任何唯一标识符在参数中 . 例如:GET /users?status=BANNED
可能会返回禁用用户列表 .从相关问题中查看此答案 .
从实用的角度来看,你有一组用户:
每个用户都有一个专用的资源位置:
您还可以通过多种方式搜索用户:
由于这些都是/ users的查询参数,因此它们都应该返回列表..即使它是1的列表 .
我写了一篇关于实用的RESTful API设计的博客文章,其中讨论了这一点,其中包括:http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
关于用户资源
在路径
/users
上,您将始终获得返回的集合资源 .在路径
/users/[user_id]
上,您将获得表示具有其id [user_id]的用户的单例资源,或者如果没有用户存在所请求的[user_id]则获得404响应(或者如果不允许您访问所请求的用户则禁止(401)资源等) . 每个资源路径只有一个标识符,您可以使用它来查找/标识资源 . 在同一资源路径上不可能对同一资源使用多个标识符 . 如果您在响应中返回了一个资源,那么标识符作为自我HREF包含在响应中以定位/标识资源 .您可以使用
GET
/查询参数查询路径/users
. 这将返回符合所请求条件的用户的集合 . 返回的集合包含用户资源,所有用户资源都标识自己的HREF .关于电子邮件资源
如果我看一下您对电子邮件的建议,我宁愿考虑以下事项:
来自用户的电子邮件也是资源 . 所以我认为
/users/[user_id]/emails
会为id为user_id
的用户返回一组电子邮件地址 ./users/[user_id]/emails/[email_id]
使用user_id和['email_id']返回用户的电子邮件 . 你用作标识符的是你自己,但我会坚持一个整数 . 您可以通过向标识要删除的电子邮件的路径发送DELETE
请求来删除用户的电子邮件 . 因此,例如DELETE
on/users/[user_id]/emails/[email_id]
将删除具有user_id所拥有的email_id的电子邮件 . 很可能只允许该用户执行此删除操作 . 其他用户将获得401响应 .如果用户只能拥有一个电子邮件地址,则可以使用
/users/[user_id]/email
这将返回单个资源 . 用户可以通过PUT
ting更新他的电子邮件地址,或者通过该网址的POST
更新新的电子邮件地址 . 如果在您的应用程序中您不允许没有电子邮件的用户,如果他向该URL发送了DELETE
请求,则应回复401 .