泽西岛:处理 restful HTTP PUT(更新)请求的最佳实践

Jersey: Best practice handling restful HTTP PUT (update) request

假设我有非常简单的 User class:

@JsonIgnoreProperties({"password", "created", "lastModified"})
public class User {
    public String id;
    public String name;
    public String password
    public Long created;
    public Long lastModified;
}

当我们将 User 实体序列化为 JSON 字符串时,我们会过滤掉 passwordcreatedlastModified。然后前端的user会更新用户名,把用户放回我们的Restful服务。

我的伪控制器方法处理 PUT 请求:

@Path("/user/{id}")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void saveUpdate(@PathParam("id")String id, User user) {
    userService.save(user);
}

在上面的方法中,我希望Jackson将前端发送的JSON字符串反序列化到POJOuser实例,然后调用我们的服务来保存实例。

到目前为止一切看起来都很酷。然而,当我们将 user POJO 传递给 userService 以保存它时,问题就出现了。请记住,当我们将 user 序列化为 JSON 时,我们忽略了三个属性:passwordcreatedlastModified,我们必须获取这些缺失的值来自数据库的属性,然后与从前端发送的数据合并。

进行合并操作对于编码人员来说是一项非常简单但乏味的任务。我想知道是否有任何好的做法可以以简单而优雅的方式处理这种情况

我想用户对象是将要保存到数据库中的实体对象,所以最佳做法是不要将实体对象暴露给 FE,而是使用仅包含 FE 需要知道的字段的 DTO 对象(考虑隐藏 id以及使用 UUID 代替,因为 id 值是可预测的)。稍后您可以使用 ModelMapper 将此类 DTO 对象映射到实体,这样您就可以轻松地在 userDTO 和用户实体对象之间进行合并,然后只保留实体而不用担心丢失字段的状态

此外,如今许多 Web 服务禁用对其应用程序的 PUT 请求,而是使用 POST。我不太了解原因,但这是我们将应用程序传递给安全检查时的安全问题之一

我认为更多的是关注您的服务而不是 REST API。我的意思是,如果用户的 3 个属性 "password"、"created" 和 "lastModified" 不应该对表示层可见,那么服务应该能够在没有它们的情况下处理保存。

在持久层中,您绝对可以更新 User 而无需填充所有属性。或者更好的设计,让我们把 UserLogin("id", "password", "created", "lastModified") 和 User("id", "name") 分开到同一个数据库 table。然后 User 的更新根本不需要其他不必要的属性。