这是REST API的有效映射吗?

时间:2014-01-23 10:15:34

标签: http rest url mapping bulk-operations

我在处理用户能够创建和管理不同类型资源的系统的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
  3. 我不喜欢替代品。 1)因为对我而言,它在语义上很差。相比之下,当我提到一个盒子时,我实际上指的是盒子而不是它的内容。

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

    因此,我的问题:

    1. 我为这个映射提出了一个有效,正确的REST API映射吗?它尊重REST原则吗?我不是在问这是否是最好的映射。我问的是它的有效性。
    2. 如果没有,哪一个替代方案更好,为什么?
    3. 请原谅我的英语,我不是该语言的母语。

2 个答案:

答案 0 :(得分:1)

我认为API设计看起来不错,但后来我重新阅读了你的评论:

  

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

如果您的系统资源属于不同类型,为什么要使用仅适用于通用object s的中性无类型API公开它们?

RESTful API设计的第一部分是识别系统中的名词,这些名词应该被认为是作为URI暴露的候选者。我强烈建议您尝试比object更具体,并使用更清晰的URI为您的系统的业务功能建模。

你的英语很好!

答案 1 :(得分: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。