1

So I have a spring boot project that I just added OpenAPI Swagger UI to. It auto generates the documentation really well for all of our controllers and models. But I would like to add some additional configuration such as externalDocs as shown here.

externalDocs:
    url: URL
    description: DESC

But since its auto generated I don't have a YAML for swagger. I tried the following to add it through a Bean with no luck.

import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;

public class springShopOpenAPI{

    @Bean
    public OpenAPI springShopOpenAPI() {
           return new OpenAPI()
            .info(new Info().title("SpringShop API")
            .description("Spring shop sample application")
            .version("v0.0.1")
            .license(new License().name("Apache 2.0").url("http://springdoc.org")))
            .externalDocs(new ExternalDocumentation()
            .description("SpringShop Wiki Documentation")
            .url("https://springshop.wiki.github.org/docs"));
    }
}

Below is my Pom.xml if needed.

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.2.28</version>
</dependency>

Thanks for any suggestions.

Debargha Roy
  • 2,320
  • 1
  • 15
  • 34
Dylan
  • 2,161
  • 2
  • 27
  • 51

3 Answers3

3

You'll need to implement the OperationCustomizer interface to add external links. The code should look something like below

@Component
public class EndpointCustomizer implements OperationCustomizer {

    @Override
    public Operation customize(Operation operation, HandlerMethod handlerMethod) {
        // Will add the externalDocs to all the endpoints
        operation.externalDocs(new ExternalDocumentation().url("/resource").description("Link to resource"));
        
        return operation;
    }
}

You can also perform additional logic to add the externalDocs based on certain criteria. Once the class is defined, you'll need to create an API Group in the class where you are defining your OpenAPI Bean (the springShopOpenAPI class in your case).

@Bean
public GroupedOpenApi hideApis(EndpointCustomizer endpointCustomizer) {
    return GroupedOpenApi.builder().group("default") // or use null instead of default
            .addOperationCustomizer(endpointCustomizer)
            .build();
}
Debargha Roy
  • 2,320
  • 1
  • 15
  • 34
  • Where do I a dd the bean if I dont have a class that creates the OpenAPI Bean? Or whaty should the OpenAPI bean classlook like> – Dylan Aug 25 '20 at 16:02
  • 1
    @Dylan in your case that class already exists, i.e. `springShopOpenAPI`. There you have a bean that returns an `OpenAPI` object. That's what I was referring to. – Debargha Roy Aug 25 '20 at 16:08
  • I get an error that group has private access but changing it to setGroup means addOperationCustomizer doesnt exist – Dylan Aug 25 '20 at 16:18
  • You should use `group` and not `setGroup`. If you take a look at the source, you'll know that `setGroup` is deprecated, and `group` should be used instead. And for the private issue, please share a github gist for both the files you made. – Debargha Roy Aug 25 '20 at 17:13
  • For further discussion, we can continue in the following chat room https://chat.stackoverflow.com/rooms/220444/springdoc-clarification – Debargha Roy Aug 25 '20 at 17:59
3

All I needed to do was add @Configuration and update my pom.xml to have the following.

        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.4.4</version>
        </dependency>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-webmvc-core</artifactId>
            <version>1.4.4</version>
        </dependency>

import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class springShopOpenAPI{



    @Bean
    public OpenAPI customOpenAPI(){
        return new OpenAPI()
                .info(new Info().title("SpringShop API")
                        .description("Spring shop sample application")
                        .version("v0.0.1")
                        .license(new License().name("Apache 2.0").url("http://springdoc.org")))
                .externalDocs(new ExternalDocumentation()
                        .description("SpringShop Wiki Documentation")
                        .url("https://springshop.wiki.github.org/docs"));
    }

}
Dylan
  • 2,161
  • 2
  • 27
  • 51
3

If somebody is trying to add a link to a @Tag, for linking to a wiki page for instance, this can also be done with the externalDocs keyword as follows :

@RestController
@Tag(name = "MyController",
     description = "MyController goal is ...",
     externalDocs = @ExternalDocumentation(description = "Wiki page about MyController.", url = "https://confluence.mycorp.com/display/..."))
public class MyController { ...

Pierre C
  • 2,920
  • 1
  • 35
  • 35
  • 1
    This also works on `@Operation`, if you just wanna add links to different endpoints directly - use it w/ `@Operation` – Ali Jul 06 '22 at 19:15