70

因此,假设我们有一些似乎不是最好表示为资源的东西(我们想要暂停的进程状态、我们想要在服务器上执行的无状态计算等)。

如果在 API 设计中我们使用process/123/pause或者calculations/fibonacci——这与 REST 根本不兼容吗?到目前为止,从我阅读的内容来看,它似乎并没有,只要这些 URL 可以使用 HATEOAS 发现并且媒体类型是标准化的。

还是我应该更喜欢按照此处回答的方式在消息中执行操作?

注 1:
我确实理解可以用名词来改写我的一些示例。但是,我觉得在特定情况下,名词的作用不如动词。因此,我试图了解拥有这些动词是否会立即变得不安。如果是,那么为什么该建议如此严格,以及在这些情况下不遵循它可能会错过什么好处。

注 2:
回答“REST 对此没有任何限制”将是一个有效的答案(这意味着这种方法是 RESTful)。回答“这取决于你问谁”“这是一个最佳实践”并没有真正回答这个问题。这个问题假设 REST 的概念作为一个定义明确的通用术语存在,两个人可以用来指代同一组约束。如果假设本身不正确并且对 REST 的正式讨论毫无意义,请务必这样说。

4

4 回答 4

42

这篇文章有一些很好的提示: http: //www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

引用文章:

不适合 CRUD 操作世界的操作怎么办?

这是事情变得模糊的地方。有多种方法:

  1. 重组动作,使其看起来像资源的一个字段。如果操作不带参数,则此方法有效。例如,激活操作可以映射到布尔激活字段并通过 PATCH 更新到资源。

  2. 将其视为具有 RESTful 原则的子资源。例如,GitHub 的 API 允许您使用 PUT /gists/:id/star 为 gist 加星标,并使用 DELETE /gists/:id/star 取消星标。

  3. 有时您真的无法将操作映射到合理的 RESTful 结构。例如,将多资源搜索应用于特定资源的端点并没有真正意义。在这种情况下, /search 最有意义,即使它不是名词。没关系 - 只需从 API 使用者的角度做正确的事情,并确保清楚地记录它以避免混淆。

我个人喜欢建议#2。如果你需要暂停某事,你在暂停什么?如果这是一个有名字的进程,那么试试这个:

/process/{processName}/pause
于 2013-10-29T03:13:35.710 回答
41

这不是严格意义上的名词与动词。这是关于你是否:

  • 识别资源
  • 通过表示来操纵资源

什么是资源?菲尔丁是这样定义的:

REST 中信息的关键抽象是资源。任何可以命名的信息都可以是资源:文档或图像、时间服务(例如“洛杉矶今天的天气”)、其他资源的集合、非虚拟对象(例如人)等等. 换句话说,任何可能成为作者超文本参考目标的概念都必须符合资源的定义。资源是对一组实体的概念映射,而不是在任何特定时间点对应于映射的实体。”

现在,回答你的问题。你不能只看一个 URL 就说,“这样那样的 URL 从根本上与 REST 不兼容吗?” 因为 REST 系统中的 URL 并不是真正重要的部分。更重要的是通过上述定义的 URLprocess/123/pause和标识资源。calculations/fibonacci如果他们这样做,则不存在违反 REST 约束的情况。如果他们不这样做,那么您就违反了 REST 的统一接口约束。您的示例使我相信它不符合资源定义,因此违反此约束。

为了说明该系统中的资源可能是什么,您可以通过将进程发布到paused-processes资源集合来更改进程的状态。尽管这可能是处理流程的一种不同寻常的方式,但它与 REST 架构风格并不完全不兼容。

在计算的情况下,计算本身可能是资源,而该资源可能如下所示:

Request:
GET /calculations/5

Response:
{
  fibonacci: 5,
  prime-number: true,
  square-root: 2.23607
}

不过,这又是一个有点不寻常的资源概念。我想稍微更典型的用法可能如下所示:

Request:
GET /stored-calculations/12381728 (note that URL is a random identifier)

Response:
{
  number: 5,
  fibonacci: 5,
  prime-number: true,
  square-root: 2.23607
}

尽管您可能想要存储有关该资源的其他信息,而不是任何人都可以使用计算器进行的纯粹计算......

Response:
{
  number: 5,
  fibonacci: 5,
  prime-number: true,
  square-root: 2.23607,
  last-accessed-date: 2013-10-28T00:00:00Z,
  number-of-retrievals-of-this-resource: 183
}
于 2013-10-29T05:22:36.067 回答
6

在 REST API 中使用动词被认为是不好的做法。

在SO和其他地方有一些关于为什么以及如何避免使用动词的材料。话虽如此,有很多使用动词的“REST”API。

对于您的processAPI,我会让资源 Process 有一个state字段,可以使用PUT.

假设GET /process/$id当前返回:

{
   state: "PAUSED"
}

然后你PUT这个/process/$id

{
   state: "RUNNING"
}

这使得进程改变状态。

在斐波那契的情况下,只需有一个名为 的资源fibonacci,并在正文中使用POST参数(例如n表示前n 个斐波那契数),或者甚至GET在 URL 中使用查询。

于 2013-10-29T00:08:45.130 回答
3

HTTP 方法动词:GET、PUT、POST 等,而 URL 应始终指代名词(动作的接收者)。可以这样想:一个句子中的两个动词有意义吗?“GET 计算”是无稽之谈,其中“GET 状态”很好,“GET 过程”更好(“状态”是过程的元数据)。

于 2013-10-29T03:22:31.040 回答