命令服务器的 "Restful" 方法是什么?

What is the "Restful" way to command a server?

我有一个 REST 端点来创建这样的应用程序配置

POST /applications

有了body

{
    "appName" : "my-new-app"
}

我returns一个新建的应用配置:

{
  "appName": "my-new-app",
  "appId": "2ed17ff700664dad9bb32e400d39dc68",
  "apiKey": "a$XVDH9F3Ix4lx2LdxeJ4ZOe7H.bw/Me5qAmaIGF.95lUgkerfTG7NW",
  "masterKey": "a$XVDH9F3Ix4lx2LdxeJ4ZOeSZLR1hVSXk2We/DqQahyOFFY6nOfbHS",
  "dateCreated": "2021-03-28T11:00:07.340+00:00",
  "dateUpdated": "2021-03-28T11:00:07.340+00:00"
}

注意:密钥是auto-generated在服务器端,不是从客户端传递过来的。

我的问题是,命令服务器重置密钥的RESTful方法是什么,例如:

PUT /applications/my-new-app/update_keys 不是 noun-based,因此,不是 restful,也将命令作为查询参数传递似乎也不是 restful,因为这不是GET 方法而不是 PUT(更新)方法。

这是一种发送命令的方法,它是尽可能 RESTful:

端点:

POST /application/:appName/actions

示例负载:

{
    "actions" : [
      {
        "action" : "name_of_command",
        "arguments" : {
          "arg1" : "param1"
        }
      },
      {
        "action" : "reset_keys",
        "arguments" : {
        }
      }
    ]
}

Actions 是作为端点一部分的名词,服务器将处理在端点内提交(或发布)的操作。一系列动作最适合允许发送多个动作。并且每个具有参数的操作对于需要参数的未来操作也是可取的。

what's the RESTful way to command the server to reset the keys for example:

您将如何使用网站来实现?

你会看到像 /www/applications/my-new-app 这样的网页;在数据或元数据中,您会发现 link。接下来 link 将带您进入表格;除了任何“隐藏的”输入之外,该表单将具有输入控件,描述您需要提供哪些字段来发送消息。当您单击提交按钮时,您的用户代理将收集您的输入,从中构建适当的消息正文,然后使用表单元数据来确定要使用的请求方法和 uri。

客户端永远不必猜测要使用什么 URI,因为服务器提供 links 来指引方向。

Hypertext is at the heart of the uniform interface

REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.


因为 服务器 为每个 link 提供 URI,您可以自由选择哪个资源“处理”哪个消息。

解决此问题的一种有趣方法是查看 cache invalidation 的 HTTP 规则。简短的版本是成功的不安全请求(PATCH/POST/PUT)使目标 uri 的表示无效。

换句话说,我们通过向我们尝试更改的资源发送命令来利用缓存失效。

因此,假设检索应用程序的表示是通过如下请求发生的:

GET /applications/my-new-app HTTP/x.y

然后我们会要求服务器通过发送具有相同目标 uri 的请求来更改该资源。类似于:

POST /applications/my-new-app HTTP/x.y
Content-Type: text/plain

Please rotate the keys

Web 上的表单提交通常表示 key/value 对,因此更可能的拼写是:

POST /applications/my-new-app HTTP/x.y
Content-Type: applications/x-www-form-urlencoded

action=Please%20rotate%20the%20keys

描述此请求的表单我有一个“动作”输入控件,它接受来自客户端的文本,或者在这种情况下动作更可能是具有预定义值的隐藏控件。

注意:如果我们有多个操作应该使 /applications/my-new-app 表示无效,我们可能会对所有这些使用 POST,并根据请求主体解决服务器端的歧义(如果我们的路由框架给了我们所需的控制程度,我们可以使用它——但更常见的是为每个内容类型设置一个 POST 处理程序,并“手动”解析请求主体。

POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.” -- Fielding 2009


PUT /applications/my-new-app/update_keys is not noun-based and thus, not restful,

这不是真的:REST 不关心您对资源标识符使用什么拼写约定。例如

这些都很好,就像网络上的所有其他资源一样。

您绝对可以设计您的资源模型,以便编辑 update_keys 文档同时修改 my-new-app 文档。

潜在的困难是通用组件不知道发生了什么。 HTTP PUT 表示“更新目标资源的表示”,每个通用组件都知道这一点;由于对“update-keys”资源的更改,允许源服务器修改其他资源。

但是我们没有一种很好的语言来传达通用组件可能发生的所有副作用。如果没有一些特殊的魔法,以前缓存的 my-new-app 副本,以及原始的、未轮换的密钥,将被留在周围。因此,客户可能会留下描述该应用程序的文档的陈旧副本。

(“一些特殊魔法”的例子是 Linked Cache Invalidation, which affords describing caching relationships between resources using web linking. Unforunately, LCI has not been adopted as a standard, and you won't find the described link relations in the IANA registry。)