当我用java中的restapi构建crud应用程序时,我一直在重新设计轮子,我正在寻找某种标准来应用。
让我们举个例子。假设我有一个“用户”表和这些rest端点:
GET /users/{user_id} // returns a user
POST /users // creates a user
PUT /users/{user_id} // updates a user
在每个方法中,我必须选择、插入或更新数据库中的用户。
对于这六个操作中的每一个(3个用于rest,3个用于数据库),我需要为“user”pojo提供一组不同的属性,这些属性通过rest传入或发送到数据库。
例如,在rest端,当创建一个用户时,我不需要用户id(因为它是由数据库创建的),但我需要一个密码。当获得一个用户时,我确实需要用户id,但我从不想将密码返回给客户端。当更新用户时,我可能想省略一些字段,因为它们是只读的(比如用户名或创建日期)。
在数据库方面,我可能需要在restapi中无法传回的不同字段,如“is\u approved”或“some\u secret”。我经常需要创建派生字段,比如“password\u hash”。
所以,就像我说的,同一事物的六种不同的表现形式。在java中,我通过创建六个不同的pojo类来实现。它并不总是需要那么多独特的类,但有时确实需要。
在restapi中,我不想对所有端点使用同一个类,而只是忽略一些字段,因为这个类被传递到api文档工具,并且它的属性被发布。
这六个类有没有标准的命名约定?
对于其余部分,在过去,我使用了createuser、getuser和updateuser。我不喜欢这些名字,因为它们是动词,应该是名词。
userforcreation和userforupdate都很笨拙。newuser和modifieduser可能不错,但我不知道如何调用一个用户。
我还需要一整套数据库的名字。
这类事情肯定有一个标准或惯例。有人知道是什么吗?
2条答案
按热度按时间qmb5sa221#
我认为你的想法是正确的,每个请求和响应都有特定的对象;但是,根据api的设计,您只需要一个
User
班级。您可以使用构建器抽象出创建逻辑(例如生成用户id),并将请求对象传递到位于rest端和数据库之间的dao中。dao只需接受请求,检索用户数据,构建并返回User
对象。一旦用户对象被创建,它就可以用来创建响应对象,这些对象将被序列化并放入响应数据中。在这里编写两个用户类(类似
User
以及InternalUser
)更明确地说明将向客户机公开哪些数据,特别是当客户机与api在同一个库中编写时。你不能实现额外的InternalUser
在响应对象生成器、工厂或构造函数中处理字段过滤;但是,如果客户机是在同一个库中编写的,则可能会泄漏敏感或必要的信息。你可能想看看招摇文件。该标准提供了一个很好的restapi规范,它非常简单,并且提供了一个很好的方法来模板化api结构,即使它们最终看起来像json或xml的墙。
热释光;dr(根据@turing85的建议
createuser[请求|响应]
getuser[请求|响应]
更新用户[请求|响应]
用户
内部用户
x8diyxa72#
这种方法是借用/受六边形体系结构/干净体系结构/端口和适配器的启发。因为我们已经将dto和业务对象完全分离了,所以我们非常接近前面提到的体系结构。在clean架构中,bob叔叔谈到了“用例”。每个用例都有一些输入和一些输出。我们可以将输入想象为对用例的请求,将输出想象为对给定请求的响应。因此,对于企业实体
User
和用例create
,get
,update
, ... 其中一个实体,我建议使用以下命名模式:对于给定的示例,这意味着我们要创建类
CreateUserRequest
,CreateUserResponse
GetUserRequest
,GetUserResponse
UpdateUserRequest
,UpdateUserResponse
更重要的是:对于复杂的操作,如Create
以及Update
,我们可以提取公共字段并将它们放在一个超类中(如果只有java有多重继承,我们可以使用mixin…),而实际的用例请求只剩下我们真正需要的数据来定义。在许多情况下,响应是相同的,因此有一个共同点是有意义的UserResponse
-而不是许多不同的React。这为一致的api响应提供了额外的好处,例如,如果要返回用户列表,可以返回List<UserResponse>
(可能还有一些分页信息)。