我在 REST 命名约定和后端端点放置方面遇到了问题。假设我们有一个系统,其中包含域对象,例如:产品和调查。每个产品都附有一些调查。调查是一种表格,其中包含用户在对产品进行评分时填写的问题。我想进行诸如"获取具有具体ID的产品调查"之类的操作。在我看来,可能的终点是:
- /
- survey/product/{idProduct} /
- product/{idProduct}/survey
更合乎逻辑和自然是第二种选择。但现在问题出在控制器上。我们有产品控制器和调查控制器。ProductController 由根 URI/product 映射,SurveyController 使用/survey URI 映射。因此,每个以/product 开头的方法都应该放在 ProductController 中,与/survey 相同。如果我们选择第二个选项,那么我们应该在产品控制器中放置对产品进行调查的具体方法。但是,ProductController 服务于调查可能会令人困惑。它应该在产品上运行。对于开发人员来说,更自然的方式是 SurveyController 返回 Survey。产品控制器使用SurveyService并不重要,例如获取具体产品的调查。我们总是可以在 SurveyController 中使用映射,我们在其中放置返回具体产品调查的方法,并由 URI/product/{id}/survey 映射,但这也可能使开发人员找到方法声明变得混乱和耗时,并且我们不能用一些根 URI 路径注释控制器。
什么更好?为了使用严格的约定,以/product 开头的 URI 总是与 ProductController 一起分配,开发人员可以通过 URI 快速找到方法,但方法可以为不同的域对象提供服务,而不仅仅是产品或在不同的控制器上使用具有一些根路径的不同 URI?
如果我们的控制器和域对象很少,问题看起来很简单。但是,当我们考虑具有大约 100 个域对象的系统时呢?
对于 100 个域对象,通常具有某种定向结构。这意味着一个依赖关系图,它在某种程度上决定了如何拆分域,甚至拆分为单独的项目或单独的可运行应用程序(微服务)。因此,顺便说一下,更大的模型实际上"更容易"。
我可能会考虑哪种资源是我的模型的核心。例如,如果一个Product
可能在没有调查的情况下存在,但一个Survey
没有Product
就没有意义,我可能会media-type
Survey
链接到一个Product
,而不是相反。这可能看起来像:
/survey/123 <-- contains link to /product/456
在实践中,这意味着您不必像您提议的那样实际提供"子资源"。