0

我在问自己一个关于清洁架构的问题。

让我们想象一个小 api,它允许我们使用该类型的 archi 创建和获取用户。此应用程序有两个端点并将数据存储在数据库中。假设我们有一个看起来像的 db 模型

class User:
    id: int
    firstname: str
    lastname: str

首先,GET 端点将使用用例GetUser并使用User实体。该实体将如下所示:

class User:
    id: int
    firstname: str
    lastname: str

我的问题涉及 POST 端点。显然,在此端点中传递的数据只是字段firstname和。lastname我必须在下面做另一个像这样的实体吗?

class UserRequest:
    firstname: str
    lastname: str

我发现这并不令人满意,因为将这样的实体想象为业务观点是没有意义的。然而,使实体“复合”似乎有点不稳定,例如:

class User:
    id: Optional[int]
    firstname: str
    lastname: str

第三种选择是在用例文件中使用一个类,该类仅用于对来自 POST 请求的过去进行建模。IE

class UserRequest:
    firstname: str
    lastname: str

class CreateUserUseCase:
    def __init__():
        ...
    def execute(request: UserRequest):
        ...

所以问题是:根据干净的架构原则,对来自非业务实体的 POST 请求的数据进行建模的最佳方法是什么?

非常感谢您的帮助,如果我的示例不够清楚,请随时提出问题。

史蒂夫。

4

1 回答 1

0

在与该实体的生命周期相同的实体的上下文中查看多个端点(用例)会很有帮助,例如:

  1. 创建(POST)一个新用户'xyz'(写入数据库)
  2. 变异(POST/PUT/PATCH)用户'xyz'(写入数据库)
  3. 查询(GET)用户'xyz'(从数据库中读取)

上述每一项行动都应涉及相同的业务实体User

  1. 创建:User实体在用例(应用程序层)内部使用UserRequestDTO 构建(您实际上已经证明了这一点),然后传递给存储库对象以进行持久性。
  2. 变异:User从数据库(存储库对象)中检索实体,然后修改(应用程序)最终传递给存储库对象以进行持久性。
  3. 查询:User从数据库(存储库对象)中检索实体,然后传递回表示层,最终转换为响应 DTO。

CA 的原则之一是让表示层内的 DTO 映射到输入/输出端口/从输入/输出端口映射。CA 的核心是域实体,由输入(表示请求 DTO)或数据库构建。

于 2021-11-14T21:55:18.283 回答