用于搜索资源的 RESTFul 平面层次结构与动态层次结构
Posted
技术标签:
【中文标题】用于搜索资源的 RESTFul 平面层次结构与动态层次结构【英文标题】:RESTFul Flat Hierarchy vs. Dynamic Hierarchy for Search Resource 【发布时间】:2014-11-10 10:09:23 【问题描述】:我们正在创建一个 REST API,我们目前有两种方法来定义资源。
基本上我们有Patients
、Studies
和Images
,其中Patient
有nStudies
和Study
有n@987654328 @。
分层方法
/webapi/patients/0/studies/12/images
层次结构在 URI 中可见
要搜索所有图像,我们需要一个搜索资源
/webapi/search?q=imageName:mountain
平面方法
/webapi/patients/0
/webapi/studies/12
/webapi/images/
层次结构由属性完成(例如,study 12
的 patientId
为 0)。
要搜索所有图片,我们可以搜索资源本身:
/webapi/images?q=imageName:mountain
是否有最佳实践方法或是否有人遇到过类似情况?是搜索资源 REST,还是在平面方法中看不到来自图像的关系是否很糟糕。
我们还需要考虑移动和修改。
【问题讨论】:
我认为两个 anweser 都会收到已解决的标志。所以我认为我的问题是放松。我希望这仍然可以帮助一些人。感谢 Aurélien 和 inf3mo。 另见***.com/questions/20951419/… 【参考方案1】:平面和分层 URI 都可以是 RESTful。问题在别处。 RESTful 假设 URI 是 resources 的 identifiers。
/wepapi/patients/0/studies/12/images
标识的是什么资源?研究的图像 12.
它真的是一个糟糕的标识符吗?不是真的。
会更好吗?绝对:
wepapi
(获取资源表示的方式)与抽象资源无关。最 RESTful 的方法是为同一抽象资源的不同具体“表示”使用相同的 URI(有关详细信息,请参阅 HTTP Accept
标头)。
patients/0
不需要识别这些图像。您可能认为客户端软件通过解析 URI 来获取此数据会很酷,但是......他们不应该这样做。 URI 被称为“不透明”。
/search?q=imageName:mountain
标识的资源是什么?名为“山”的图像。
它真的是一个糟糕的标识符吗?并不真地。 会不会更好?绝对:
search
看起来像一个动词,应该会在 RESTful 设计者的头脑中引起很多警告。在某种程度上,我们可以说 URI 标识“搜索”或“搜索结果”(名词而不是动词),但认为它标识“图像”更安全。
最后但同样重要的是,在/studies/12/images
和/images/?studies=12
之间进行选择以便与/studies/12
或/images/?name=mountain
保持“一致”纯粹是一种软件设计选择。采用对您的应用程序更优雅的解决方案。它与 REST 无关,因为 URI 不应该被黑客入侵(请记住,它们应该是“不透明的”)。 URI 之间的链接是在它们的表示形式(JSON、XML、html...)中,而不是在它们的结构中。
【讨论】:
好主意。 :-) 我的意思是 SEARCH 真的应该是一个 HTTP 动词,其正文包含标准查询语言上的查询。像resources?q="URL serialized query"
或resources?reinvent=""&query=""&languages=""
这样的当前方法并不是那么好。【参考方案2】:
正如 Aurélien 指出的那样,设计 URI 结构不是 REST 问题。您应该遵循非常宽松的 URI 标准。例如,它声明路径是分层的,而查询是 URI 的非分层部分。 REST 的统一接口约束是关于使用标准解决方案,并且没有像 nice URI 这样的标准,所以从 REST 的角度来看,你如何构造你的 URI 并不重要,因为它们不会被客户端解析(除非您将 URI 模板用于模板目的)。
根据 HATEOAS 约束,您的客户端必须遵循服务发送的超链接。这些超链接必须用关于它们语义的元数据进行注释。该元数据可以是任何类型的链接数据。目前 IANA 链接关系是最典型的(通过非 RDF 格式),但您也可以使用 schema.org 操作等……(通过 RDF 格式)。所以客户端会检查链接的元数据,而不关心 URI 结构。
良好的 URI 结构仅对服务开发人员很重要。这很重要,因为有两件事:
它使路由更容易:如果 URI 可读,您可以更轻松地将端点映射到控制器。 您可以检查是否将 URI 映射到资源而不是操作。如果您无法清除 URI 中的每一个动词,那么就有问题了。例如,POST /users/123?update=true&partial=true body
不能删除 update
。所以可能 HTTP 方法是错误的,因为动词去那里:PATCH /users/123 body
解决了问题。大多数动词都可以简化为标准 HTTP 方法,例如 GET, POST, PUT, DELETE, PATCH, etc...
,因此实际上您(几乎)不需要新方法。
在我看来,扁平化方法更好,因为它更容易解析。通过查找东西,您通常依赖于单个 id,而不是多个 id。
/wepapi/patients/0/studies/12/images
- 这是有道理的,因为您正在寻找来自第 0 位患者的第 12 次研究的图像。另一种方法是/images?patient=0&study=12
,或者如果研究有唯一的 id,那么/images?study=0_12
。顺便提一句。设计即席搜索查询并不是 REST 最详尽的部分。通过简单的查询,您可以使用 URI 的查询部分对其进行管理。
REST 不是您目前可以从实践中学习的东西。大多数人从不阅读或理解理论,所以那里有很多有缺陷的教程。您可能必须从Fielding dissertation 和一些其他论文开始,例如this one。有许多有趣且可能有用的项目仍在开发中,例如 Hydra、RESTdesc 等。因此,REST 实现远非一项精心设计的技术。我们可能还需要 15 年或更长时间......
【讨论】:
以上是关于用于搜索资源的 RESTFul 平面层次结构与动态层次结构的主要内容,如果未能解决你的问题,请参考以下文章