分层式RESTful URL设计

29

我已经阅读了关于这个问题的提问,但仍然没有一个确定的答案。

我有一个应用程序,想建立一个RESTful API来公开一部分信息。我有三个资源:

  1. 用户
  2. 报告
  3. 照片

用户有报告,报告有照片。照片不能存在于报告之外,报告也不能存在于用户之外。

我已经为我的需求设计了以下URL:

用户登录,服务器响应令牌,并将其发送到所有API调用的头文件中

GET example.com/api/

获取用户信息

GET example.com/api/users/{username}

获取所有用户报告

GET example.com/api/users/{username}/reports

获取报告中的所有照片

GET example.com/api/users/{username}/reports/{report_id}/photos

添加照片

POST example.com/api/users/{username}/reports/{report_id}/photos

删除照片

DELETE example.com/api/users/{username}/reports/{report_id}/photos/{photo_id}

修改照片描述

PUT example.com/api/users/{username}/reports/{report_id}/photos/{photo_id}

问题

  1. 将资源 ID 添加到 URL 中,例如 resource/id,是好的实践吗?还是应该将其作为查询参数添加?
  2. 这种链接资源的方法,例如 resource/id/sub-resource/id/等是否可接受和好的做法,或者我应该将所有资源放在顶层,并使用查询参数指定其位置?

我喜欢你的想法,但我很好奇为什么你不把照片和报告视为顶级资源。例如,/reports/{reportid}/authors、/reports/{reportid}/photos、/photos/{photoid}/authors、/photos/{photoid}/reports。我理解你的限制,但只是好奇,为什么你不想从不同的入口点深入数据。如果一份报告有多个作者——如果你有报告ID或标题但没有作者等,怎么办?没有理由不能有多个路径指向同一个资源,但如果确实这样做,我建议告知用户每个规范URI的位置。 - ScottCher
3
注:为了避免将来的API更改与URI冲突,Restful APIs 应始终进行版本控制(例如example.com/api/…example.com/api/1/…)。 - Regexident
3个回答

13

这个设计没有问题。但是会创建较长的URL,有时难以理解,API用户需要知道层次结构。此外,API的使用者需要以略微非标准的方式编写更多的代码(尽管可以完成,但会有点混乱)。从不同角度考虑一下:

你有三个资源,每个都有自己的身份标识。因此,如果我们重构上面的URI,它将如下所示(我只展示GET):

用户资源:

获取用户列表

  GET example.com/api/users

获取特定用户

  GET example.com/api/users/{username}

报告资源:

获取所有报告

 GET example.com/api/reports

获取特定报告

 GET example.com/api/reports/{report_id}

照片资源

全部照片

GET example.com/api/photos

具体照片

GET example.com/api/photos/{photo_id}

用户所有报告

GET example.com/api/reports?username={userName}

用户的具体报告

GET example.com/api/report?username={userName}&report_id={reportId}

所有用户照片

GET example.com/api/photos?username={userName}

根据报告ID获取该用户的所有照片(如果报告ID不受用户影响唯一,则无需用户名称,这将进一步简化URI)

GET example.com/api/photos?username={userName}&report_id={reportId}

所有报告的照片

GET example.com/api/photos?report_id={reportId}

这样做简化了理解,使用这种方法可以在消费者端编写更加标准的代码。


我喜欢你的例子。如果我想添加一张照片,将父级(用户)的ID传递到JSON主体中是否正确?例如POST example.com/api/photos {"id":"user_id_111","photo":"my_photo"} - Diego

6

在我看来,您对其进行了很好的建模。

关于1,我更倾向于使用resource/id而不是查询参数。但在建模时,您必须考虑代理缓存机制等因素。因此请勿忘记头信息。

我会选择查询参数进行筛选等操作。

关于登录,凭据应该在标头中,不需要特定资源,只需对每个资源应用适当的安全性。


1

我认为你的方案没有任何问题。

现在大多数框架都使用类似于 Django 的标准来指定 URL。

个人认为,这使得 URL 更易读,对用户更友好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接