Arpit Agrawal
Arpit Agrawal

Reputation: 1180

Springdoc Swagger UI not using swagger-config

need some help with springdoc-openapi-ui!

I am using springdoc-openapi-ui to render my API schema. This is the version details of it.

enter image description here

Now, i have done some configuration in my spring boot application like below enter image description here

Now, i was expecting that when i hit localhost:15041/swagger-ui.html, it should take me to http://localhost:15041/swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config by default this and render my API document but unfortunately it only renders the Petstore. Even if i directly go to http://localhost:15041/swagger-ui.html?configUrl=/v3/api-docs/swagger-config, it doesn't render using the swagger-config. enter image description here

Although if i go to localhost:15041/v3/api-docs i get my json API documentation and localhost:15041/v3/api-docs/swagger-config, i get the swagger-config. Also, if i enter /v3/api-docs in the Explore search area of the petstore page, it shows my API documentation.

I have spent more than 1.5 days to fix it but it just doesn't work. Really appreciate if someone can help.

Upvotes: 9

Views: 40006

Answers (4)

Lacan
Lacan

Reputation: 41

It works for me with this configuration (note also springdoc.swagger-ui.url config)

springdoc.swagger-ui.disable-swagger-default-url=true
springdoc.swagger-ui.configUrl=/openapi/swagger-config
springdoc.swagger-ui.url=/openapi
springdoc.api-docs.path=/openapi

Upvotes: 4

Ron
Ron

Reputation: 983

I find a way to disable default URL on springdoc 1.6.9 with springboot 2.6.6.

I just got the same issue on the latest springdoc version 1.6.9, that it always points to that default petstore swagger URL even the springdoc properties (disable default URL) have been configured. Thanks to Arpit Agrawal, I find that springdoc change this default URL with the Transformer, in other words, it matches the request URL of the SWAGGER_INITIALIZER_JS = "swagger-initializer.js"js file which contains the default petstore URL, and then replace the default URL to empty string as html.replace(Constants.SWAGGER_UI_DEFAULT_URL, StringUtils.EMPTY);in the Transformer.

But on 1.6.9 this snippet code doesn't work since the swagger default URL has been moved into the webjars/swagger-ui/index.html in that swagger-initializer.js file has been merged into index.html, and this js file is removed, then that replacement will never happen.

I have to use 1.6.9 for that it added the feature I need, so I change the code to let the default URL is disabled by overriding the SwaggerIndexTransformer Bean. The config URL better to set due to the original code can't work.

    @Bean
    SwaggerIndexTransformer indexPageTransformer(SwaggerUiConfigProperties swaggerUiConfig, SwaggerUiOAuthProperties swaggerUiOAuthProperties,
            SwaggerUiConfigParameters swaggerUiConfigParameters, SwaggerWelcomeCommon swaggerWelcomeCommon, ObjectMapperProvider objectMapperProvider) {
        return new SwaggerIndexPageTransformer(swaggerUiConfig, swaggerUiOAuthProperties, swaggerUiConfigParameters, swaggerWelcomeCommon, objectMapperProvider){
            @Override   
            public Resource transform(HttpServletRequest request, Resource resource,
            ResourceTransformerChain transformerChain) throws IOException {
        if (swaggerUiConfigParameters.getConfigUrl() == null){
                System.out.println("You should set config url in case geting into this block");
                // swaggerWelcomeCommon.buildFromCurrentContextPath(request);
                //buildFromCurrentContextPath is not allowed to be invoked.
        }
 
        final AntPathMatcher antPathMatcher = new AntPathMatcher();
        boolean isIndexFound = antPathMatcher.match("**/swagger-ui/index.html", resource.getURL().toString());

        if (isIndexFound) {
            String html = defaultTransformations(resource.getInputStream());
            return new TransformedResource(resource, html.getBytes());
        }
        else
            return resource;
    }
            
        };
    }

Put this code in a @Configuration class, it can override that Bean in springdoc jar. And add those properties in application.properties file:

spring.main.allow-bean-definition-overriding=true

springdoc.swagger-ui.disable-swagger-default-url=true

springdoc.swagger-ui.configUrl=/{contextpath}/v3/api-docs/swagger-config

springdoc.swagger-ui.url=/{contextpath}/v3/api-docs

Upvotes: 1

Arpit Agrawal
Arpit Agrawal

Reputation: 1180

Found the issue. The problem is with how the springdoc library uses the swagger-ui. They have written some custom code to patch the index.html file returned by swagger-ui jar on the fly to inject the configUrl query param in the response.

Now when swagger-ui moved from 4.8.1 to 4.9.0, they changed the index.html file format which broke the custom code written in springdoc.

To fix the issue, currently we need to downgrade the org.webjars:swagger-ui to 4.8.1 where index.html file is as per expectation of springdoc which will then honour the configUrl sent in the query params.

Upvotes: 4

Perry45
Perry45

Reputation: 86

Theoretically you shouldn't have to define any options if you use the default stuff, my config tho look like this:

springdoc:
  swagger-ui:
    disable-swagger-default-url: true
    urls[0]:
      name: 'name'
      url: '/v3/api-docs'

For full reference and other useful settings look here: https://springdoc.org/#swagger-ui-properties

Also you mention that it not work if you call http://localhost:15041/swagger-ui.html?configUrl=/v3/api-docs/swagger-config this is the wrong url. The correct one is the url you mentioned first: http://localhost:15041/swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config. But localhost:15041/swagger-ui.html should you route correctly.

If you use spring-security you should also add the following dependcy: springdoc-openapi-security

If it's not working it must have something to do with your deps I think.

Upvotes: 0

Related Questions