REST 和数据库的对象命名约定

ccl*_*eve 4 java api rest design-patterns

在使用 Java 中的 REST API 构建 CRUD 应用程序时,我一直在重新发明轮子,并且我正在寻找某种可以应用的标准。

让我们通过示例来完成此操作。假设我有一个“用户”表和这些 REST 端点:

GET  /users/{user_id} // returns a user
POST /users           // creates a user
PUT  /users/{user_id} // updates a user
Run Code Online (Sandbox Code Playgroud)

在每种方法中,我必须在数据库中选择、插入或更新用户。

对于六个操作中的每一个(3 个用于 REST,3 个用于数据库),我需要为通过 REST 传入或发送到数据库的“用户”POJO 提供一组不同的属性。

例如,在 REST 端,创建用户时,我不需要 user_id (因为它是由数据库创建的),但我确实需要密码。当获取用户时,我确实想要 user_id,但我不想将密码返回给客户端。更新用户时,我可能想省略一些字段,因为它们是只读的(例如用户名或创建日期)。

在数据库方面,我可能需要不会在 REST API 中传回的不同字段,例如“is_approved”或“some_secret”。我经常需要创建派生字段,例如“password_hash”。

所以,正如我所说,同一件事有六种不同的表现形式。在 Java 中,我通过创建六个不同的 POJO 类来做到这一点。它并不总是需要那么多独特的课程,但有时确实如此。

在 REST API 中,我不想对所有端点使用相同的类,而只是忽略某些字段,因为此类会传递到我们的 API 文档工具,并且其属性会被发布。

这六个类有什么标准的命名约定吗?

对于 REST,过去我使用过 CreateUser、GetUser 和 UpdateUser。我不喜欢这些名字,因为它们是动词,应该是名词。

UserForCreation 和 UserForUpdate 很尴尬。NewUser 和 ModifiedUser 可能不错,但我不知道如何调用用户进行 GET。

我需要数据库端的另一整套名称。

对于这种事情肯定有一个标准或约定。有人知道这是什么吗?

Tur*_*g85 5

这种方法是借用/启发自HexagonalArchitecture / Clean Architecture / Ports and Adapters的。由于我们已经将 DTO 和业务对象完全分离,因此我们非常接近上述架构。在《Clean Architecture》中,Uncle Bob 谈到了“用例”。每个用例都有一些输入和一些输出。我们可以将输入想象为对用例的请求,将输出想象为对给定请求的响应。因此,对于业务实体和、、 、 ... 此类实体之一的User用例,我建议采用以下命名模式:creategetupdate

<use-case><Business-entity>[Request|Response]
Run Code Online (Sandbox Code Playgroud)

对于给定的示例,这意味着我们创建类

  • CreateUserRequest,CreateUserResponse
  • GetUserRequest,GetUserResponse
  • UpdateUserRequest,UpdateUserResponse

更重要的是:对于像Createand这样的复杂操作Update,我们可以提取公共字段并将它们放在超类中(如果只有 Java 具有多重继承,我们可以使用 mixins...),只留下数据来处理实际的用例请求来定义我们真正需要的。UserResponse在许多情况下,响应是相同的,因此使用公共类而不是许多不同的响应是有意义的。这带来了一致的 API 响应的额外好处,例如,如果想要返回用户列表,可以返回 a List<UserResponse>(也许还有一些分页信息)。