1

我在处理系统的 REST API 时提出了以下映射,用户可以在该系统中创建和管理不同类型的资源。

// READ OPERATIONS
GET /objects               => read collection meta
GET /objects/[id]          => read single element
GET /objects/?[query]      => read a number of elements
GET /objects/?all          => read all elements

// CREATE / UPDATE OPERATIONS
PUT /objects               => possibly create the collection and update its meta
PUT /objects/[id]          => possibly create and update a single element
PUT /objects/?all          => update the entire content of the collection
POST /objects              => create new objects or update existing objects
PATCH /objects             => partially update the collection meta
PATCH /objects/[id]        => partially update a single element
PATCH /objects/?all        => partially update all the elements
PATCH /objects/?[query]    => partially update a number of elements

// DELETE OPERATIONS
DELETE /objects            => delete the collection
DELETE /objects/[id]       => delete a single element
DELETE /objects/?all       => empty the collection
DELETE /objects/?[query]   => delete a number of elements

以下是有关系统的更多信息:

  • 每个资源可以是简单的资源,也可以是类似集合的资源;
  • 每个资源,不管是否是集合,都有自己的属性需要访问和操作;
  • API 必须支持批量(不是批处理)操作。

我还研究了以下替代方案:

  1. 用于/collection访问集合的元素集并/collection?meta访问集合自己的数据;
  2. 使用全新的资源来访问集合自己的数据,例如/collections/path/to/collection.

我不喜欢替代 n。1)因为在我看来,它在语义上很差。相比之下,当我提到一个盒子时,我实际上指的是盒子本身,而不是它的内容。

我不喜欢替代 n。2) 因为一个资源最终将自己的数据暴露给另一个资源,复制 url 并使“我应该使用哪个 url”的问题不像我希望的那样微不足道。

因此,我的问题:

  1. 我为 REST API 提出的映射是否有效、正确?是否尊重 REST 原则?我不是在问它是否是最好的映射。我在问它的​​有效性。
  2. 如果不是,哪一种替代方案更好,为什么?

请原谅我的英语,我不是该语言的母语人士。

4

2 回答 2

1

我认为 API 设计看起来不错,但后来我在开始时重新阅读了您的评论:

用户可以在其中创建和管理不同类型的资源。

如果你系统的资源是不同类型的,你为什么要用一个中性的、无类型的 API 来公开它们,只适用于泛型objects?

RESTful API 设计的第一部分是识别系统中的名词,这些名词应被强烈考虑作为 URI 公开的候选者。我强烈建议您尝试object使用更清晰的 URI 来更具体地模拟系统的业务功能。

而且你的英语很好!

于 2014-01-24T16:56:34.687 回答
1

首先,URI 的语义与 REST 无关。“RESTful URI”几乎是一个矛盾的说法。URI 必须遵循的唯一约束是 RESTful 是它引用一个且只有一个资源。

显然,这并不意味着 REST URI 会变得晦涩难懂。它们应该尽可能清晰、直观和具有描述性,但是您决定使用的任何方案都可以,只要其一致即可。如果您对此如此担心,则意味着您可能没有使用 HATEOAS,应该看看它。

其次,您没有考虑媒体类型,这就是为什么您最终会遇到使用 URI 来指定不同媒体类型的问题。假设检索集合的所有元素应该很简单:

GET /objects

检索集合的单个元素应该是:

GET /objects/[id]

现在,如果客户端只需要资源的元数据,无论是集合还是单个元素,它应该通过Accept标头指定,而不是通过转到文档中指向的单独 URI,或者更糟糕的是,通过添加查询字符串参数。

因此,例如,如果您的对象的媒体类型是application/vnd.mycompany.myobject+json,则您的客户端在标头中使用该媒体类型时会获得完整的对象表示Accept,并通过使用类似application/vnd.mycompany.myobjectmetadata+json.

我想这可能不是您所期望的,但这就是 REST。您的文档和设计工作应该专注于您的媒体类型,而不是您的 URI。当您使用 HATEOAS 时,URI 设计是无关紧要的,如果您不使用 HATEOAS,那么您就没有使用 REST。

于 2014-01-24T22:46:26.003 回答