首页 > 解决方案 > 设计 REST api 关系的良好实践

问题描述

我们目前正在尝试为我们的 web 服务设计一些 REST api。我们有两个资源,“记录”和“远征”。据我们所知,一条记录可以关联多条实境,而一条实境可以关联一条记录(但不一定)。

当我们创建一个探险,并且我们想将它“附加”到一个记录上时,我们有两个解决方案:

  1. POST /expeditions?recordId=xxx
  2. POST /records/xxx/expeditions 和一个POST /expeditions独立创建探险的 WS。

我的同事建议了第一种方法,但我发现第二种方法是最常用的方法。我没有在网上找到将第一种方法介绍为好的或坏的设计的文章。

那么,哪种解决方案适合您?什么样的考虑可以帮助我们选择?

谢谢你。

标签: apirest

解决方案


什么样的考虑可以帮助我们选择?

想想cache-invalidation

HTTP 是关于文件传输的。我们通过索取文件副本从服务器获取信息;该请求可能由服务器本身处理,也可能由具有有效文档副本的缓存处理。

我们通过提议对文档进行编辑来将信息发送到服务器——POST 是最常用的方法(通过 HTML 表单)。

当编辑成功时,之前缓存的文档副本已经过期,我们真的希望它们被更新的副本替换。

通用缓存失效是有限的;特别是,它不支持文档的任意失效。只有 target-uri、Location 和 Content-Location 无效。

因此,当我们设计资源交互时,我们要考虑这个限制。

这通常意味着我们用来更改文档的请求应该与读取同一文档的请求具有相同的 target-uri。

(是的,这意味着如果我们要对文档进行不同类型的编辑,所有不同的编辑共享相同的目标 uri,并且我们通过查看请求的其他部分来消除编辑的歧义——例如通过解析身体。)


POST /records/xxx/expeditions 和一个 POST /expeditions WS 来独立创建探险。

这不是必需的——允许服务器对多个文档应用更改;HTTP 限制了请求的含义,但不限制效果。

也就是说,通用缓存不会神奇地知道两个文档都已被编辑。在某种程度上,您在设计中选择的部分内容是现在需要刷新哪个文档,以及哪些文档可能会过时一段时间(通常直到缓存的表示达到其最大年龄)。


对于您对成功编辑的响应将是资源更新表示的副本的特殊情况,您有更多的自由,因为使用可以使用Content-Location标头来识别我们返回的文档响应,并且该标头自动失效。

POST /foo/bar

...
200 OK
Content-Location: /foo

在此序列中,通用标头将使其缓存的/foo和副本无效/foo/bar

(当然,仍然存在一些问题,因为我们没有一种机制可以在单个响应中同时返回更新的副本/foo 更新的副本。因此,我们需要研究其他想法,例如服务器推送/bar)。


推荐阅读