冲突的REST网址

时间:2017-02-01 10:42:41

标签: rest architecture

所以我正在构建一个REST API,需要制作一些网址。问题是,我遇到了一些相互冲突的道路。例如:

  • GET <type>/<id>获取给定类型和id
  • 的对象的详细信息
  • GET <type>/summary获取给定类型对象的摘要

此简化示例显示了对象具有id“summary”时出现的问题。解决这个问题的最佳方法是什么?从REST清教徒的角度来看,解决方案应该是什么?

以下是我的一些想法:

  • <id>放入查询参数中。据我所知,这是违反标准的
  • 在网址的开头添加关键字。还违反标准?
  • 禁止某些ID值。这不是我想要为我的所有用户和用例以及我的系统的不同入口强制执行的内容

3 个答案:

答案 0 :(得分:3)

网址结构不太合适,所以很难以干净的方式解决它。

为了便于讨论,我们假设<type>books资源。所以第一个网址很好 - 你得到一本给定ID的书:

GET /books/<id>

然而,这不是:

GET /books/summary

因为它是一个定制的网址,我猜这个网址在您的应用程序中有用,但并不安静。 GET调用应该返回一个或多个资源。然而,&#34;摘要&#34;不是资源,它是资源的属性,这就是为什么你最终会遇到ID与书籍属性混淆的情况。

因此,您最好的选择是将此网址更改为以下内容:

GET /books?fields=summary

默认情况下,GET /books会返回所有资源,而GET /books?fields=<list_of_fields>会返回图书,但只返回所选属性。

这与您之前的网址类似,但没有ID /属性冲突,稍后您还可以使用特定字段检索资源(无需创建新的自定义网址)。

修改

关于书籍数量,从资源方面来说,它仍然有用。 /books为您提供了一本或多本书,但可用于收集的元信息,例如计数,还包括&#34;大多数读书和#34 ;或者&#34;以字母“A&#39;&#34;”等开头的书籍,因为这会使资源变得越来越复杂和难以维护。

根据您想要实现的目标,我认为有两种解决方案:

  1. 创建一个管理图书集的新资源。例如:

    GET / bookcase

  2. 这将为您提供有关该集合的信息,例如:

    {
        "count": 1234,
        "most_read": "<isbn>",
        // etc. - any information that might be needed about the book collection
    }
    
    1. 或搜索引擎。您可以创建以下资源:

      GET / book_search_engine /?query =

    2. 将返回搜索结果,例如:

      {
          "count": 123,
          "books": [
              // Books that match the query
          ]
      }
      

      然后像这样的查询会给你一个计数:

      // Search all the books, but provide only the "count" field
      GET /book_search/?query=*&fields=count
      

      显然,这是一个更复杂的解决方案,对于一个简单的REST API可能不是必需的,但它可能很有用,因为它可以更容易地创建特定于客户端的查询。

答案 1 :(得分:2)

我可以替代这个。如果我们同时拥有多本书和多本书,该怎么办?然后你可以:

/book/{id}

/books/summary

/books/count

答案 2 :(得分:1)

  

此简化示例显示了对象具有id“summary”时出现的问题。解决这个问题的最佳方法是什么?从REST清教徒的角度来看,解决方案应该是什么?

REST 而言,URI是不透明的。拼写绝对无关紧要。你可以使用像

这样的URI
/a575cc90-2878-41fe-9eec-f420a509e1f0
/f871fff6-4c4e-48f7-83a4-26858fdb3096

就REST而言,那就是现场。请参阅Stefan Tilkov的演讲REST: I Don't Think It Means What You Think It Does

您要问的是 URI设计,如何使约定/最佳实践适应您的特定设置。

有一点可以帮助我们认识到摘要是一个资源,在REST / HTTP意义上 - 它是一个可以表示为字节序列的文档。您需要做的就是找出该资源所属的位置(根据您当地的拼写约定)。

继续借用他人使用的“书籍”示例

# Here's the familiar "URI that identifies a member of the books collection"
/books/<id>

# Here's the summary of the /books collection
/summaries/books
  

放入查询参数。据我所知,这是违反标准的

没有你想象的那么多。 REST并不关心。 URI spec表达了关于分层数据与非分层数据的一些视图。 HTTP支持重定向的概念,其中一个资源可以引用另一个资源。

GET /books?id=12345

302 Found
Location: /books/12345

您还可以选择跳过往返,通过返回您想要的表示,利用Content-Location

GET /books?summary

200 OK
Content-Location: /summaries/books

...