所以我正在构建一个REST API,需要制作一些网址。问题是,我遇到了一些相互冲突的道路。例如:
GET <type>/<id>
获取给定类型和id GET <type>/summary
获取给定类型对象的摘要此简化示例显示了对象具有id“summary”时出现的问题。解决这个问题的最佳方法是什么?从REST清教徒的角度来看,解决方案应该是什么?
以下是我的一些想法:
<id>
放入查询参数中。据我所知,这是违反标准的答案 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;”等开头的书籍,因为这会使资源变得越来越复杂和难以维护。
根据您想要实现的目标,我认为有两种解决方案:
创建一个管理图书集的新资源。例如:
GET / bookcase
这将为您提供有关该集合的信息,例如:
{
"count": 1234,
"most_read": "<isbn>",
// etc. - any information that might be needed about the book collection
}
或搜索引擎。您可以创建以下资源:
GET / book_search_engine /?query =
将返回搜索结果,例如:
{
"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
...