【问题标题】:Spring Boot - Different model representations / Multiple APIsSpring Boot - 不同的模型表示/多个 API
【发布时间】:2017-04-28 23:43:21
【问题描述】:

我的后端必须提供两种不同的 API——分别对相同模型的不同访问、相同的实现和相同的数据库映射。模型以 JSON 形式发送,后端以同样的方式使用它们。

但每个 API 都需要不同的 JSON 表示形式。 F.e.我想以不同的方式命名一些字段(w/@JsonProperty f.e.)或者想省略一些。

如前所述,控制器应该像生产它们一样使用它们。

由于只有表示不同:是否有一种简单且符合 DRY 的方法来完成此操作?

示例:

打电话

ProductsController.java

    sym/products/1

应该返回

{
  "id": 1,
  "title": "stuff",
  "label": "junk"
}

打电话

ProductsController.java

    frontend/products/1

应该返回

{
  "id": 1,
  "label": "junk",
  "description": "oxmox",
  "even-more": "text"
}

非常感谢!

提姆

【问题讨论】:

  • 您可能需要使用不同的 DTO 并将您的域对象映射到它们(无论如何这是最佳实践)。

标签: java json spring rest api


【解决方案1】:

单独的 DTO 可能是最佳解决方案。

另一种方法(假设您使用的是 Jackson)是拥有一个包含所有不同字段的 DTO,然后使用 MixIns 来控制 DTO 的序列化方式。

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {

    public static void main(String[] args) throws Exception  {

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.addMixIn(SomeDTOWithLabel.class, IgnoreLabelMixin.class);

        SomeDTOWithLabel dto = new SomeDTOWithLabel();
        dto.setLabel("Hello World");
        dto.setOtherProperty("Other property");
        String json = objectMapper.writeValueAsString(dto);
        System.out.println("json = " + json);
    }

    public static class SomeDTOWithLabel {
        private String label;
        private String otherProperty;

        public String getOtherProperty() {
            return otherProperty;
        }

        public void setOtherProperty(String otherProperty) {
            this.otherProperty = otherProperty;
        }

        public String getLabel() {
            return label;
        }
        public void setLabel(String label) {
            this.label = label;
        }
    }

    public abstract class IgnoreLabelMixin {
        @JsonIgnore
        public abstract String getLabel();

    }
}

例如,我们有旧客户端可能仍然依赖的带有已弃用属性的 DTO,但我们不想将它们发送给新客户端,因此我们使用 MixIns 来抑制它们。

【讨论】:

  • 感谢您描述 MixIn 方法!我将使用单独的 DTO。您是否建议在单独的类文件中实现它们,例如 VendorSymDTO / VendorFrontendDTO ...?
【解决方案2】:

如果这只是根据您调用的路径返回轻量级有效负载的情况,您可以配置您的 json 序列化程序 (ObjectMapper) 以省略空字段。然后在您的服务中仅选择并填充您希望返回的字段子集。

    objectMapper.setSerializationInclusion(Include.NON_NULL); // omits null fields

但是,如果您希望返回不同名称的字段,请使用不同的 API 模型。

【讨论】:

  • 很高兴知道。谢谢!在这种情况下,省略空字段将无法完全完成这项工作。
猜你喜欢
  • 2019-05-14
  • 1970-01-01
  • 2017-12-30
  • 2017-09-02
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
  • 2017-06-20
  • 1970-01-01
相关资源
最近更新 更多