【问题标题】:Is it bad to create different classes for REST request and response?为 REST 请求和响应创建不同的类是不是很糟糕?
【发布时间】:2016-09-20 02:01:14
【问题描述】:

我正在一个 Spring Boot 项目中工作,作为我目前的实现,几乎每个 API 我都有 requestresponse 类。

例如:

@RequestMapping(value = "/notice", method = RequestMethod.POST)
public AddNoticeResponse addNotice(@Valid @RequestBody AddNoticeRequest){
    Notice notice = ... // creating new notice from AddNoticeRequest
    noticeRepository.save(notice);
    AddNoticeResponse response = ... // creating new response instance from Notice
    return response;
} 

请求和响应类如下所示:

@Data
@AllArgsConstructor
public class AddNoticeRequest{
    private String subject;
    private String message;
    private Long timeToLive;
}
// Ommiting some annotations for brevity
public class AddNoticeResponse{
    private String subject;
    private String message;
    private Long timeToLive;
    private Date createTime;
    private String creator;
} 

我有两个问题。

  • 创建太多类并命名它们有时让我抓狂。
  • 有些请求和响应有共同的字段。

例如:Notice有两种:EmailNotification

public class Email {
    private String subject;
    private String message;
    private String receiver;
}

那么,我应该使用扩展公共类的内部类还是将所有字段放入一个类中?哪个更好?

public class AddNoticeRequest {

    private String subject;
    private String message;

    class Email extends AddNoticeRequest{
        private String receiver;
    }
}
public class AddNoticeRequest{
    private String subject;
    private String message;
    private Long timeToLive;
    private String receiver;
}

那么当客户端执行添加Email通知的请求时,会不会有些字段为空?

【问题讨论】:

    标签: java rest


    【解决方案1】:

    从长远来看,使用定制的 DTO 进行请求和响应将为您提供更大的灵活性。实际上,没有什么可以阻止您使用继承和内部类,但我会避免使用它。

    我已经回答了一个类似的问题here,强调了使用 DTO 优于 REST API 中的持久性实体的好处。下面您会发现这种方法的一些好处:

    • DTO 可以根据您的需求定制,并且在仅公开持久性实体的一组属性时非常有用。您不需要诸如@XmlTransient@JsonIgnore 之类的注释来避免某些属性的序列化。
    • 通过使用 DTO,您将避免在持久性实体中出现大量注释,也就是说,持久性实体不会因​​非持久性相关的注释而变得臃肿;
    • 您将完全控制在创建或更新资源时收到的属性;
    • 如果您使用Swagger 记录您的REST API,您可以使用@ApiModel@ApiModelProperty 注释记录您的API 模型,而不会弄乱您的持久性实体;
    • 每个版本的 API 可以有不同的 DTO;
    • 映射关系时您将拥有更大的灵活性;
    • 您的 DTO 可以拥有HATEOAS 的链接列表。这种东西不应该添加到持久性对象中。
    • 您可以使用映射框架(例如 MapStruct)将 REST API DTO 从/映射到持久性对象。

    【讨论】:

      【解决方案2】:

      不要子类化 req/resp 对象。

      在您的框架中使用像 Jackson 这样的自动反序列化器将消息有效负载转换为业务对象。

      但是,您最终还是会得到大量业务对象。

      【讨论】:

        【解决方案3】:

        我会建议你使用 JSON 格式,而不是每次都创建类并返回它的实例。但是,如果您仍然需要类层次结构,您可以创建一个类并放置一个存储 JSON 的变量。

        【讨论】:

          猜你喜欢
          • 2017-07-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多