分层RESTful URL设计

时间:2011-10-20 09:07:54

标签: web-services rest

我已经仔细阅读了有关此问题的问题,但我仍然没有明确的答案。

我有一个应用程序,并希望构建一个RESTful API来公开信息的子集。我有三个资源:

  1. 用户
  2. 报告
  3. 照片
  4. 用户有报告和报告都有照片。照片不能存在于报告之外,报告也不能存在于用户之外。

    我为我的要求设计了以下网址

    用户登录,服务器使用令牌进行响应,该令牌在所有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. 在URL中添加资源ID(即资源/ ID)是一种好习惯,还是应该将其添加为查询参数?
    2. 这种链接资源的方法,即资源/ id /子资源/ id /等,是否可以接受,或者我应该将所有资源放在顶层并使用查询参数指定其位置?

3 个答案:

答案 0 :(得分:12)

这个设计没有错。但是这会创建很长的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的所有照片(如果report_id是唯一的,您可能不需要用户名,无论用户如何,这将进一步简化URI)

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

报告的所有照片

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

这简化了理解,使用这种方法可以在消费者方面编写更多标准代码。

答案 1 :(得分:5)

恕我直言,你正在建模它。

关于1我宁愿选择resource/id而不是查询参数。但是在建模时必须考虑的一件事是代理的缓存机制等等。所以不要忘记标题。

我选择查询参数进行过滤和排序。

关于登录,凭据应位于标题中,并且不需要特定资源。只需应用每个资源的安全性。

答案 2 :(得分:1)

我认为你的计划没有任何问题。

现在大多数框架都使用类似的标准来指定url(如Django)。

在我个人看来,它使URL更具可读性,对用户来说更好一些。