Forum Discussion

zur's avatar
zur
New Contributor
3 years ago

Swagger OpenAPI Code Gen "oneOf" : How to generate correct class file?

TLDR:

Swagger offers a feature named 'oneOf'. The resulting java classes created do not seem to be correct.

 

Details:

I am creating the spring/java server side rest api code. And when I send a request. The request object is not parsed correctly. The following error is printed in the console.

 

 

JSON parse error: Could not resolve subtype of [simple type, class com.model.Issuer]: missing type id property 'type' (for POJO property 'issuer'); nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, class com.Issuer]: missing type id property 'type' (for POJO property 'issuer')\n at [Source: (PushbackInputStream); line: 3, column: 15] (through reference chain: com.IssueCredentialRequest[\"credential\"]->com.Credential[\"issuer\"])

 


The reason seem to be that the generated class does not have subtypes:

 

 

package com.sphereon.vdp.vc.service.model;


import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
})
public interface OneOfIssuer {

}

 

 

There is another class which is generated correctly

 

 

package com.sphereon.vdp.vc.service.model;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = VerifyPresentationRequest.class, name = "VerifyPresentationRequest"),
@JsonSubTypes.Type(value = ProoflessVerifyPresentationRequest.class, name = "ProoflessVerifyPresentationRequest")
})
public interface OneOfpresentationsVerifyBody {

}

 

 

Can someone point to what am I missing?

 

 

<plugin>
   <groupId>io.swagger.codegen.v3</groupId>
   <artifactId>swagger-codegen-maven-plugin</artifactId>
   <version>3.0.33</version>
   <dependencies>
      <dependency>
         <groupId>com.github.jknack</groupId>
         <artifactId>handlebars</artifactId>
         <version>4.3.0</version>
      </dependency>
   </dependencies>
   <executions>
      <execution>
         <id>vc-rest-api-issuer-source-generation</id>
         <goals>
            <goal>generate</goal>
         </goals>
         <phase>generate-sources</phase>
         <configuration>
            <inputSpec>${pom.basedir}/specifications/issuer.yml</inputSpec>
            <language>spring</language>
            <apiPackage>com.company.vdp.vc.service.api</apiPackage>
            <modelPackage>com.company.vdp.vc.service.model</modelPackage>
            <artifactVersion>${project.version}</artifactVersion>
            <generateModels>true</generateModels>
            <generateApis>true</generateApis>
            <generateModelDocumentation>true</generateModelDocumentation>
            <generateSupportingFiles>true</generateSupportingFiles>
            <verbose>${openapi-codegen-verbose}</verbose>
            <output>${project.basedir}/target/generated-sources/java/api</output>
            <ignoreFileOverride>${project.basedir}/target/generated-sources/java/api/.swagger-codegen-ignore</ignoreFileOverride>
            <configOptions>
               <delegatePattern>true</delegatePattern>
               <dateLibrary>java8</dateLibrary>
               <useTags>true</useTags>
            </configOptions>
         </configuration>
      </execution>
      <execution>
         <id>vc-rest-api-verifier-source-generation</id>
         <goals>
            <goal>generate</goal>
         </goals>
         <phase>generate-sources</phase>
         <configuration>
            <inputSpec>${pom.basedir}/specifications/verifier.yml</inputSpec>
            <language>spring</language>
            <apiPackage>com.company.vdp.vc.service.api</apiPackage>
            <modelPackage>com.company.vdp.vc.service.model</modelPackage>
            <artifactVersion>${project.version}</artifactVersion>
            <generateModels>true</generateModels>
            <generateApis>true</generateApis>
            <generateModelDocumentation>true</generateModelDocumentation>
            <generateSupportingFiles>true</generateSupportingFiles>
            <verbose>${openapi-codegen-verbose}</verbose>
            <output>${project.basedir}/target/generated-sources/java/api</output>
            <ignoreFileOverride>${project.basedir}/target/generated-sources/java/api/.swagger-codegen-ignore</ignoreFileOverride>
            <configOptions>
               <delegatePattern>true</delegatePattern>
               <dateLibrary>java8</dateLibrary>
               <useTags>true</useTags>
            </configOptions>
         </configuration>
      </execution>
   </executions>
</plugin>

 

 

Following is the spec file that I am using without editing.

 

  • Karen_bg's avatar
    Karen_bg
    New Contributor

    Awesome and interesting article. Great things you’ve always shared with us. Thanks. Just continue composing this kind of post.

     

     

     

    NJMCDirect Ticket

    • zur's avatar
      zur
      New Contributor

      Thanks for the comment. The post was a question. Not a general article. I am not sure how your response helps me solve the question. Thanks anyway.

  • dsinghvi77's avatar
    dsinghvi77
    Occasional Contributor

    Hey zur  -- 

    I have hit similar issues and couple of things you can try: 

    1. Changing the generator and possibly using OpenAPI (I have heard the Native Generator: https://openapi-generator.tech/docs/generators/java works the best) 

    2. My team has been working on a Swagger alternative that really focuses on codegen (as Swagger was initially built for docs) and we are calling it Fern. Check it out here.  
    In Fern you can represent the issuer like this: 

    Issuer: 
      union: 
        stringIssuer: string
        objectIssuer: ObjectIssuer
    ObjectIssuer: 
      fields: 
        id: string

    and it will codegen the classes you want. Demo video here. Apologies if this wasn't the answer you are looking for but I have run into many issues with codegen in the Swagger ecosystem and using an alternative feels like the best solution.

    • zur's avatar
      zur
      New Contributor

      Thank you for the response. I will suggest evaluation of the framework. But it may not be adopted currently. Thank you for your help.