【问题标题】:URIs in REST API endpoints according to Restful practices根据 Restful 实践,REST API 端点中的 URI
【发布时间】:2021-08-04 22:50:59
【问题描述】:

我计划为我们的 REST API 提供这些端点。

  1. PUT /tenant/:tenantId/users/save/:username

  2. POST /tenant/:tenantId/users/invite

  3. GET /tenant/:tenantId/users/fetch

  4. GET /tenant/:tenantId/users/fetch/:用户名

  5. PATCH /tenant/:tenantId/users/activate/:username

  6. POST /tenant/:tenantId/groups/save/

save/fetch/activate 等动词是从一致性的角度来看的。这些 RESTFul 是否符合 REST 原则?如果有的话,应该如何改变这些?有什么建议吗?

【问题讨论】:

    标签: api rest microservices multi-tenant endpoint


    【解决方案1】:

    据此REST Resource Naming Guide

    RESTful URI 应该引用作为事物(名词)的资源,而不是引用动作(动词),因为名词具有动词没有的属性——类似于资源具有属性。

    还有

    不应使用 URI 来指示执行 CRUD 功能。 URI 应该用于唯一标识资源,而不是对它们进行任何操作。应该使用 HTTP 请求方法来指示执行了哪个 CRUD 函数。

    让我们以你的第一个 URI 为例

    PUT /tenant/:tenantId/users/save/:username

    您在这里使用动词保存。如前所述,不应该在 URI 中指示 CRUD 操作,在这种情况下使用 POST 会更合适。Here 是每个 HTTP 动词用途的指南。知道了这一点,我认为对于这种情况更合适的 URI 应该是这样的

    POST /tenants/:tenantId/users/:username

    在这种情况下:

    GET /tenant/:tenantId/users/fetch

    GET /tenant/:tenantId/users/fetch/:username

    您应该删除 fetch,因为您已经通过 GET 动词告诉您正在获取数据。第 6 个例子也是如此。

    但是,这并不意味着您不能在 URI 中使用动词,实际上有一个特定的类别,称为 controller,正如同一指南中所述:

    控制器资源对程序概念进行建模。控制器资源就像可执行函数,有参数和返回值;输入和输出。 使用“动词”来表示控制器原型。

    这个控制器资源可能会很好(我假设),例如你的

    GET /tenant/:tenantId/users/activate/:username.

    但我认为动词 activate 应该放在最后:

    GET /tenant/:tenantId/users/:username/activate

    【讨论】:

    • 谢谢。我已将这些更新如下: 1. PUT /tenant/:tenantId/users/:username 2. POST /tenant/:tenantId/users/invite 3. GET /tenant/:tenantId/users 4. GET /tenant/:tenantId /users/:username 5. PATCH /tenant/:tenantId/users/:username/activate 6. POST /tenant/:tenantId/groups/
    • 如果第一个是更新,我认为一切正常。另一个重要的事情是一致性是关键在你的资源命名中保持一致
    • 另外,如果我必须有一个端点来返回用户所在的组,它应该是 /tenant/tenantId/users/userId/groups 还是 /tenant/tenantId/groups/users/:userId ?从技术上讲,组在层次结构中高于用户,但在 users/:userId 之前有组听起来有点奇怪。什么是正确的方法?
    • 是的,您应该为此使用查询组件。例如:GET /tenant/:tenantId/groups?user=username。而且,如果租户是一个集合,它应该被命名为 tenants
    • 完美!谢谢!!
    【解决方案2】:

    第一个注意事项:REST 不关心您为资源标识符使用的拼写约定。一旦确定了正确的资源,您就可以为它们选择任何您喜欢的标识符(只要这些标识符与RFC 3986 中定义的生产规则一致)。

    “任何可以命名的信息都可以是资源”(Fielding, 2000),但将资源视为文档的抽象可能最有用。我们使用HTTP作为应用协议,其应用域为transfer of documents over a network

    • 获取

    这是我们用来检索文档的方法

    • 补丁
    • 发布

    这些方法都表示编辑文档的请求(具体来说,编辑请求目标)。

    PUT 和 PATCH 都要求服务器使其文档副本看起来像客户端的本地副本。想象一下将网页加载到编辑器中,进行更改,然后将这些更改“保存”回服务器。

    POST 不太具体; “这是我们通过填写网络表单创建的文档,请自行编辑”。 It is okay to use POST:毕竟,网络取得了巨大的成功,我们仍然在表单提交中使用 POST。

    有用的工作是这些编辑的side effect


    这些是否符合 REST 原则?

    它们像网站一样工作吗?如果它们像网站一样工作:意味着您跟随链接,并通过提交表单或编辑网页并将更改提交到服务器来将信息发送到服务器,那么它就是 REST。

    一个技巧:在 REST 中正常单个方法 + 请求 uri 可能有不同有用的副作用。我们可以有几个不同的 HTML 表单,它们都共享相同的 Form.action。如果对送货地址的编辑与对帐单信息或订单项目的编辑,上传对订单文档的更改可能会产生非常不同的效果。

    正常并不意味着强制 - 如果您更喜欢每个表单请求都转到特定资源的资源模型,那也可以。您可以获得更简单的语义,但您支持更多资源,这会使缓存变得更加棘手。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2011-01-05
      • 1970-01-01
      • 2014-12-26
      • 2016-07-02
      • 2016-07-23
      • 1970-01-01
      相关资源
      最近更新 更多