在 URL 中使用动词与 REST 根本不兼容吗?

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

如果在 API 设计中我们使用 process/123/pause或者 calculations/fibonacci——这是否与 REST 从根本上不兼容?到目前为止,从我阅读似乎不,只要这些网址是发现使用 HATEOAS 和媒体类型是标准化的。

或者我应该更喜欢把行动的消息,作为回答 给你

注一:
我确实明白,我的一些例子可以用名词来重新组织。但是我觉得 特殊情况的名词不像动词那么好用。因此,我试图理解,如果有这些动词将立即不休息。如果是这样的话,那么为什么这个建议如此严格,在这些情况下我不遵守它可能会错过什么好处。

注二:
答案 “ REST 对此没有任何约束”将是一个有效的答案(这意味着这种方法是 RESTful 的)。答案 “这取决于你问谁”或者 “这是最好的做法”并没有真正回答这个问题。这个问题假定 REST 的概念作为一个定义良好的公共术语存在,两个人可以用它来引用同一组约束。如果假设本身是不正确的,对 REST 的正式讨论是没有意义的,请这样说。

46806 次浏览

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

那么和其他地方有一些关于为什么和如何避免使用动词的材料。也就是说,有很多使用动词的“ REST”API。

对于您的 process API,我将使资源 Process 具有一个 state字段,该字段可以用 PUT修改。

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

{
state: "PAUSED"
}

然后你把这个转到 /process/$id:

{
state: "RUNNING"
}

使流程更改状态。

在 Fibonacci 的例子中,只需要有一个名为 fibonacci的资源,并在主体中使用带有参数的 POST(比如第一个 N Fibonacci 数字的 N) ,或者甚至在 URL 中使用带有查询的 GET

这篇文章有一些不错的提示: 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 命名一个 unstar。

  3. 有时候,您真的没有办法将操作映射到一个合理的 RESTful 结构。例如,多资源搜索实际上并不能 应用于特定资源的端点是有意义的 即使不是名词,/search 也是最有意义的。 这是可以的——只要从 API 的角度做正确的事情就可以了 消费者,并确保它的文件清楚,以避免混淆。

我个人喜欢第二条建议。如果你需要暂停一些东西,你暂停的是什么?如果它是一个带有名称的进程,那么可以尝试这样做:

/process/{processName}/pause

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

这不是严格意义上的名词与动词的对比,而是你是否:

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

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

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

现在,回到你的问题。你不能只是看着一个 URL 然后说,“某某网址从根本上来说与 REST 是不兼容的吗?”因为 REST 系统中的 URL 并不是真正重要的部分。更重要的是,URL process/123/pausecalculations/fibonacci根据上面的定义标识资源。如果有,则不存在 REST 约束冲突。如果它们不这样做,那么您就违反了 REST 的统一接口约束。您的示例使我相信它不符合资源定义,因此 违反了这个约束。

为了说明这个系统中的资源 也许吧是什么,您可以通过将进程 POST 到 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
}