How can I add a class in sprinddoc that is not referenced from an operation?

Viewed 1072

I am using springdoc with spring-boot configured mostly with annotations.

I would like to expose a particular class schema which is not referenced by any service. Is it possible to do this?

In pseudocode, I am effectively trying to do this:

GroupedOpenAPI.parseAndAddClass(Class<?> clazz);

or

GroupedOpenAPI.scan("my.models.package");

=== Update ===

I managed to parse the Schema using ModelConverters.getInstance().readAll(MyClass.class);

and then tried to add it as an OpenApiCustomiser, however it is still not visible in the UI.

3 Answers

In the SpringDoc, you can add a non-related class to the generated specification using OpenApiCustomiser

@Bean
public OpenApiCustomiser schemaCustomiser() {
    ResolvedSchema resolvedSchema = ModelConverters.getInstance()
            .resolveAsResolvedSchema(new AnnotatedType(MyClass.class));
    return openApi -> openApi
            .schema(resolvedSchema.schema.getName(), resolvedSchema.schema);
}

But need to be careful, because if your additional model is not referenced in any API, by default the SpringDoc automatically removes every broken reference definition.

To disable this default behavior, you need to use the following configuration property:

springdoc.remove-broken-reference-definitions=false

The accepted answer is correct, however this will only add the schema for "MyClass.class". If there are any classes referenced from MyClass.class which are not in the schemas, they won't be added. I managed to add all classes like this:

private OpenApiCustomiser addAdditionalModels() {
    Map<String, Schema> schemasToAdd = ModelConverters.getInstance()
        .resolveAsResolvedSchema(new AnnotatedType(MyClass.class))
        .referencedSchemas;
    return openApi -> {
      var existingSchemas = openApi.getComponents().getSchemas();
      if (!CollectionUtils.isEmpty(existingSchemas)) {
        schemasToAdd.putAll(existingSchemas);
      }
      openApi.getComponents().setSchemas(schemasToAdd);
    };
}

I tested both solutions with following dependencies:

    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-ui</artifactId>
        <version>1.6.6</version>
    </dependency>
    <dependency>
        <groupId>io.swagger.codegen.v3</groupId>
        <artifactId>swagger-codegen-generators</artifactId>
        <version>1.0.32</version>
    </dependency>

@nkocev solution throws an UnsupportedOperationException for putAll() when reloading /v3/api-docs.

java.lang.UnsupportedOperationException: null at java.util.Collections$UnmodifiableMap.putAll(Collections.java:1465)


@VadymVL solution worked fine, the response model was added to the schema.

I just want to provide this information. If you want to add multiple missing schemas, you can create a @Bean for each schema.

@Configuration
public class SampleConfiguration {

    @Bean
    public OpenApiCustomiser schemaCustomiser() {
        ResolvedSchema resolvedSchema = ModelConverters.getInstance()
                .readAllAsResolvedSchema(new AnnotatedType(MyClass.class));
        return openApi -> openApi.schema(resolvedSchema.schema.getName(), resolvedSchema.schema);
    }

    @Bean
    public OpenApiCustomiser schemaCustomiser2() {
        ResolvedSchema resolvedSchema = ModelConverters.getInstance()
                .readAllAsResolvedSchema(new AnnotatedType(MyClass2.class));
        return openApi -> openApi.schema(resolvedSchema.schema.getName(), resolvedSchema.schema);
    }
}

Both are then made available in the schemas. I've just started working with these dependencies, but this seems like a working solution. I look forward to more helpful POCs.

Related