如何从DDD角度设计API端点

问题描述 投票:0回答:2

虽然 DDD 是领域驱动的,但 RESTful API 端点设计规则是资源驱动的,因此它们似乎不适合。

例如,教师资源和学生资源之间是一对多的关系。 在示例中,聚合根是teacher。 (:id部分代表资源的ID。)

我认为可以考虑下面的端点。

  • /teachers/:teacherId/studuents/:studentId
  • /students/:studentId

从DDD的角度来看,我理解数据更改是通过聚合路由进行的。

所以我认为我们需要使用第一个建议的

/teachers/:teacherId/studuents/:studentId
通过聚合路由来修改它,老师。

但是,某些 API 不需要教师 ID。修改学生资源也很麻烦。

正如我之前所说,RESTful API 端点设计规则是围绕资源设计的,而 DDD 是围绕域设计的,因此端点设计可能需要更改。我该怎么办?

domain-driven-design endpoint
2个回答
3
投票

虽然 DDD 是领域驱动的,但 RESTful API 端点设计规则是资源驱动的,因此它们似乎不适合。

是的,没错 - 资源模型和领域模型是不同的东西。

稍微简单一点:资源模型是充当外观的文档的集合——我们使我们的服务接口看起来像一个兼容 HTTP 的 Web 服务器。 人们通过索要我们的文件副本来获取我们信息的副本;人们通过建议更改我们的文档来向我们发送信息。

您的域模型实际上是隐藏在资源模型外观后面的实现细节。

换句话说,你永远不会得到一个聚合;你得到的是一个“网页”,其内部数据源是一个聚合。 同样,您不 PUT/PATCH/POST 聚合,而是 PUT/PATCH/POST 网页。 您所在领域中的有用工作是资源模型操作的“副作用”。

Jim Webber 在 2011 年的演讲

很好地阐述了这些想法。) 是的,如果您收到操作域模型支持的资源的请求,那么您将需要一些东西来允许您接受请求并从中计算域模型的正确入口点。 这可能意味着解析请求正文,也可能只是解析请求目标的资源标识符。

再次强调——这是一个实现细节。 REST 并不关心您的 URI 中是否嵌入了聚合根标识符,或者是否存在其他间接层(请记住:Web 上的 URL 缩短器

work

)。 (作为请求处理程序的实现者,

可能会非常关心;这很好——我们在 URI 设计方面有足够的自由度,我们可以利用它们让我们关心的人的事情变得更容易。) 请注意,重要的 REST 约束之一是表示形式是超文本:客户端不输入 URL,而是按照表示形式中提供的链接进行操作,或者使用表单元数据中的链接提交表单。 URI 不需要很好,因为另一端的客户正在与链接而不是 URI 进行交互。


所以我认为我们需要使用第一个建议的 /teachers/:teacherId/studuents/:studentId 通过聚合路由来修改它,老师。

不,你不需要这样做。 您可以选择这样做 - 但这不是必需的。

如果您试图使处理程序的实现保持简单,那么您可能需要选择一个包含教师和学生标识符的 URI - 假设信息不敏感,那很好。

执行此操作时,您绝对希望选择可以通过

URI 模板方便描述的标识符拼写

- 这意味着模板内将有一个 TeacherId 表达式和一个 StudentId 表达式。 但情况仍然是这些表达式可以位于路径部分或查询部分,并且它们可以被任何其他有意义的结构包围。

您建议的拼写是

一个

可以接受的答案,但不是唯一的答案。 当然,如果仅studentId就足以识别正确的聚合,那么您可以考虑不包含teacherId扩展的URI模板。


0
投票

我将学生资源 API 建模为

/students/:studentId

如果我需要将新学生映射到教师,我会在教师资源上创建一个端点

PATCH /teachers/:teacherId { students:[studentId1,studentId2] //existing studentIds + newStudentId }

	
© www.soinside.com 2019 - 2024. All rights reserved.