简体   繁体   English

如何使用Openapi Generator从Swagger yaml生成SpringBoot模型

[英]How to generate SpringBoot models from Swagger yaml with Openapi Generator

we are using an API first approach and the API for our services is defined in swagger yamls. 我们正在使用API​​第一种方法,我们服务的API在swagger yamls中定义。 We then use Openapi generator to generate the interfaces that have to be implemented by the microservices. 然后,我们使用Openapi生成器生成必须由微服务实现的接口。 Also, the models are generated from the schemas. 此外,模型是从模式生成的。

This is where the question comes in. In one of the REST endpoints, I consume an XML let it be parsed by Spring-boot into a model and then save it to the database. 这就是问题所在。在一个REST端点中,我使用了一个XML,让它被Spring-boot解析为模型,然后将其保存到数据库中。 At the moment I use a model that looks something like this: 目前我使用的模型看起来像这样:

@Data
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Document("MyModel")
public class Model {

  @Id 
  @XmlTransient
  private String id;

  @XmlAttribute
  private String someAttribute;

  @XmlElement("childName")
  private List<OtherModel> children;

  @XmlElement("otherChildName")
  private List<OtherModel2> children2; 

}

With the other models being pretty similar. 与其他模型非常相似。 I like this because Spring-boot can use this to automatically parse the incoming XML and I can save this model directly to the database and return it as JSON. 我喜欢这个,因为Spring-boot可以使用它来自动解析传入的XML,我可以将这个模型直接保存到数据库并将其作为JSON返回。

The Models that are generated by Openapi Generator are missing the annotation, therefore, cannot be used to parse the XML and cannot be saved to the database. Openapi Generator生成的模型缺少注释,因此不能用于解析XML,也不能保存到数据库中。 Are there any way in the yaml to tell it to add the @Id , @Document and some @Xml... annotations? 是否有在YAML任何方式来告诉它添加@Id@Document有的@Xml...注解?

The main reason I'm trying to do this (use autogenerated models form swagger) is because this is a larger architecture where it would be nice if someone changes the API definition in the yaml, and for example adds fields the microservice(s) would also be build again and the models would be updated without manual updating java classes. 我尝试这样做的主要原因(使用自动生成的模型形成swagger)是因为这是一个更大的架构,如果有人更改了yaml中的API定义,那将是很好的,例如,添加字段微服务将也可以再次构建,并且无需手动更新java类即可更新模型。 Another way I thought about was generating the models the way Openapi does, then extending them with own classes and somehow add annotations afterward,... but I cannot think of any way how to do this so that you do not have to change the derived class if a field in the definition changes. 我想到的另一种方式是以Openapi的方式生成模型,然后使用自己的类扩展它们,然后以某种方式添加注释,......但我想不出怎么做才能让你不必更改派生class,如果定义中的字段发生更改。

Example: 例:

//class generated by openapigenerator
public class Model {
  private String field;
  private List<Submodel> children

  //autogenerated getters/setters
}

//model in my code
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Document("MyModel")
public class MyModel extends Model {

  @Id 
  @XmlTransient
  @Getter
  @Setter
  private String id;

}

This would be ok but would be missing is the @Xml... annotations on some of the fields. 这可以,但是缺少的是某些字段上的@Xml...注释。 I have seen that it generates @JsonProperty("somename") name just fine in case of json naming, but it seems using the XML: name/attribute properties in the yaml doesn't have any influence on the java code generated (or I'm doing something wrong, trying this: Documentation ) 我已经看到它在json命名的情况下生成@JsonProperty("somename")名称就好了,但似乎使用XML: name/attribute yaml中的XML: name/attribute属性对生成的java代码没有任何影响(或者我做错了,试试这个: 文档

The only thing I could think of would be @Override -ing the getter/setters and annotating them with the attributes, but that would mean I have to touch every microservice that uses a derivate of the model defined by the API. 我唯一能想到的就是@Override -ing getter / setters并使用属性注释它们,但这意味着我必须触及每个使用API​​定义的模型派生的微服务。 I cannot move the derived class into the API project since the contexts (in this case XML/mongo) could vary much from microservice to microservice. 我无法将派生类移动到API项目中,因为上下文(在本例中为XML / mongo)可能因微服务到微服务而有很大差异。

Any ideas on a good approach for this? 关于这个好方法的任何想法?

Cheers 干杯

----- EDIT ------ -----编辑------

After digging in deeper I'm getting more sure that probably the right approach is to add the XML mappings ( @XmlAttribute / @XmlElement ) annotations in the swagger yaml the way it is mentioned in the documentation, and then extending it in the microservice code to add the database annotations. 在深入挖掘之后,我越来越确定可能正确的方法是在文档中提到的方式在swagger yaml中添加XML映射( @XmlAttribute / @XmlElement )注释,然后在微服务代码中扩展它添加数据库注释。 Basically like the second example only that in the base class the XML annotations would already be generated by swagger codegen. 基本上与第二个示例类似,只是在基类中,swagger codegen已经生成了XML注释。 However I have not yet managed to make swagger codegen generate any XML annotation when building the schemas/models. 但是,在构建模式/模型时,我还没有设法使swagger codegen生成任何XML注释。

So first thing for openapi to generate XML annotations you need to have the withXml flag set to true in your configuration. 首先,openapi要生成XML注释,您需要在配置withXml标志设置为true

I went with the approach of using the XML specification in the openapi yaml file to generate a model with XML annotations that is used by Spring Boot to parse the incoming XML file. 我采用在openapi yaml文件中使用XML规范的方法生成一个带有XML注释的模型,Spring Boot使用它来解析传入的XML文件。

Then I derived like in my second example another class and added the id and database annotations. 然后我在我的第二个例子中得到了另一个类,并添加了id和数据库注释。

I believe this is a good approach for two reasons: 我认为这是一个很好的方法有两个原因:

  1. If the openapi yaml is changed eg new fields are added to the XML or something similar, the code of the microservice does not have to be changed to reflect the new fields, only rebuild/redeployed. 如果更改openapi yaml,例如将新字段添加到XML或类似内容,则不必更改微服务的代码以反映新字段,仅重建/重新部署。
  2. It reflects the differentiation of layers, the generated model reflects what is happening on the Http layer while the derived model reflects what is needed on the database layer. 它反映了层的区别,生成的模型反映了Http层上发生的事情,而派生模型反映了数据库层所需的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM