创建、更新和获取休息端点中的相同/不同的 DTO 对象?

请考虑遵循 UserDTO 类和 UserController 公开终结点以创建、更新和获取 User。

在 UserDTO 类中具有 id 属性对于创建和更新没有意义。如果我使用swagger或其他自动生成的API文档,那么它表明id可以在创建端点中传递。但系统不会使用它,因为 id 是在内部生成的。

如果我看一下get,那么也许我可以摆脱id属性,但它肯定是列表用户端点所必需的。

我正在考虑在获取/列表端点中返回内部用户域对象。这样,我就可以摆脱 Id 属性形式的 UserDTO 类。

有没有更好的选择,我可以为此雇用?

public class UserDTO {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

@RestController
@RequestMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController {
    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<Void> create(@RequestBody UserDTO user) {
    }

    @RequestMapping(value = "{id}", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<UserDTO> get(@PathVariable("id") int id) {
    }

    @RequestMapping(value = "{id}", method = RequestMethod.PUT)
    @ResponseBody
    public ResponseEntity<Void> update(@PathVariable("id") int id, @RequestBody UserDTO user) {
    }
}

这个问题可能被问过,但我找不到。所以请原谅我重复的问题。


答案 1

Data Transfer Object (DTO) 是一种模式,其创建目的非常明确:将数据传输到远程接口,就像 Web 服务一样。这种模式非常适合 REST API,从长远来看,DTO 将为您提供更大的灵活性

我建议为端点使用定制的类,一旦 REST 资源表示不需要具有与持久性对象相同的属性。

若要避免使用样板代码,可以使用映射框架(如 MapStruct)将 REST API DTO 与持久性对象之间的映射。

有关在 REST API 中使用 DTO 的好处的详细信息,请查看以下答案:

若要为 DTO 提供更好的名称,请检查以下答案:


答案 2

什么是关于创建两个不同的接口:

interface UserDTO {

    public String getName ();

    public void setName (String name);

}

interface IdentifiableUserDTO extends UserDTO {

    public Long getId ();

    public void setId (Long id);

}


class DefaultUserDTO implements IdentifiableUserDTO {

}

然后在控制器中使用接口而不是 DTO 类:

@RestController
@RequestMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController {
    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<Void> create(@RequestBody IdentifiableUserDTO user) {
    }

    @RequestMapping(value = "{id}", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<UserDTO> get(@PathVariable("id") int id) {
    }

    @RequestMapping(value = "{id}", method = RequestMethod.PUT)
    @ResponseBody
    public ResponseEntity<Void> update(@PathVariable("id") int id, @RequestBody UserDTO user) {
    }
}