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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34990971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 23:37:13  来源:igfitidea点击:

Same/different DTO object in create, update and get rest end points?

javarestspring-mvcdtocontent-negotiation

提问by Bhushan Bhangale

Consider following UserDTO class and UserController exposing endpoints to create, update and get User.

考虑遵循 UserDTO 类和 UserController 公开端点以创建、更新和获取用户。

Having the id property in the UserDTO class does not make sense for create and update. If I use swagger or another auto generated API documentation then it shows that the id can be passed in create end point. But the system does not use it as ids are generated internally.

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

If I look at get then probably I can get rid of the id property but it is certainly required in a list user end point.

如果我查看 get ,那么可能我可以摆脱 id 属性,但在列表用户端点中肯定需要它。

I was thinking of returning internal User domain object in get/list end points. This way I can then get rid of id property form UserDTO class.

我想在获取/列表端点中返回内部用户域对象。这样我就可以摆脱 UserDTO 类的 id 属性。

Is there any better option I can employ for this?

我可以为此采用什么更好的选择吗?

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) {
    }
}

This question may have been asked but I could not find. So excuse me for duplicate question.

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

回答by cassiomolin

Data Transfer Object(DTO) is a pattern that was created with a very well defined purpose: transfer data to remote interfaces, just like web services. This pattern fits very well in REST APIs and DTOs will give you more flexibilityin the long run.

dATA Ť转让(BOT)øbject(DTO)是一种具有非常良好限定的目的而创建的模式:将数据传送到远程接口,就像web服务。这种模式非常适合 REST API,从长远来看,DTO 将为您提供更大的灵活性

I would recommend using tailored classes for your endpoints, once REST resource representations don't need to have the same attributes as the persistence objects.

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

To avoid boilerplate code, you can use mapping frameworks such as MapStructto map your REST API DTOs from/to your persistence objects.

为避免样板代码,您可以使用映射框架(例如MapStruct)将 REST API DTO 从持久性对象映射到/映射到持久性对象。

For details on the benefits of using DTOs in REST APIs, check the following answers:

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

To give your DTOs better names, check the following answer:

为了给你的 DTO 起更好的名字,请检查以下答案:

回答by Wael Sakhri

What's about creating two different interfaces :

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

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 {

}

and then use the Interface in your controller instead of the DTO class :

然后在控制器中使用接口而不是 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) {
    }
}