我负责为一个相对较小的应用设计路由系统(以及 URL 结构)。应用本身应提供添加“根”级实体的功能以及从父级上下文添加子(嵌套)实体的能力。
考虑以下示例设置:
- 根实体:
Dogs
。 - 子实体:
Vaccinations
我有以下 UI 路由(BE 路由很容易,因为它总是平坦的,而且我可以利用 VERB 来发挥我的优势):
注意:获得超过 1 级嵌套的机会非常小,但如果它们实现,则可能会成为一个问题......
根级别:
- 得到:
/dogs?param1=value1&...
- 邮政:
/dogs/add
- 放:
/dogs/10/update
- 删除
/dogs/10/delete
- 风俗
/dogs/10/custom
嵌套级别:
- 得到:
/dogs/10/vaccinations?param1=value1&...
- 邮政:
/dogs/10/vaccinations/add
- 放:
/dogs/10/vaccinations/25/update
- 删除:
/dogs/10/vaccinations/25/delete
- 风俗:
/dogs/10/vaccinations/25/custom
虽然这对我来说有效,但我可以看到另一种可行的方法,即:
/dogs/10/vaccinations/25/add
人们会使用:
/dogs/10/addvaccination/25
这会导致 URL 稍微变短,但会产生与脱离资源符号相关的处理开销 - 即addvaccination
需要收敛到vaccinations
+ add
。
我知道 REST 只是一套建议,所以我想看看人们对我最初的方法有何看法,并可能收集任何其他关注/建议。
REST 并不关心你为资源标识符选择什么拼写。只要你遵守RFC 3986中的生产规则,你的资源标识符就可以了。具体来说,对于 HTTP,约束要严格一些;请参阅RFC 9110。如果你选择能够支持 URI 模板的拼写,人们的生活就会轻松很多;请参阅RFC 6570
您的资源模型不是您的域模型或数据模型。想想“关于狗 10 的文档”而不是“狗 10”。
每种 HTTP 方法都有不同的资源,这使得通用缓存更加困难。如果 HTTP 请求的目的是修改关于狗 10 的文档,那么您确实希望 URI 的拼写与用于获取关于狗 10 的文档副本的拼写相同。
有关不安全方法和缓存的影响的详细信息,请参阅RFC 9111 。
就 REST/HTTP 而言,这是两种不同的资源,它们不需要以任何方式相互关联。
REST 和 HTTP 都为我们设计 URI 提供了很大的自由;我们可以利用其中的一些自由来选择易于人类映射到资源本身的语义的拼写,但机器并不关心。
机器确实知道引用解析和点段(请参阅RFC 3986),因此考虑简化对相关文档的相对引用的 URI 拼写约定是合理的。例如,比较:
/vaccinations/dogs/10
很好,机器会做正确的事情,但所提供的选项/dogs/10/vaccinations
可能更有用。