Skip to content

change SwaggerIndexTransformer and SwaggerConfig design to ease customization #745

Closed
@natrem

Description

@natrem

Is your feature request related to a problem? Please describe.
When people want to extend the behavior of Swagger UI transformers (SwaggerIndexTransformer declared in org.springdoc.webmvc.ui.SwaggerConfig and org.springdoc.webflux.ui.SwaggerConfig they have to inherit from your specialized classes instead of just using the provided abstract support class (AbstractSwaggerIndexTransformer).

I think that the design could be improved and the signatures used in SwaggerConfig classes modified to ease work for reuse.

In my case I want to inject css file and js file (used for OIDC) to the document. I created a support class similar to:

public class MySwaggerIndexTransformerSupport extends AbstractSwaggerIndexTransformer {
// other stuff

	public Resource transform(Resource resource, ResourceTransformerChain resourceTransformerChain) {
// I mask the IOException management
// use methods from AbstractSwaggerIndexTransformer 
// execute my own transformation
// return resource
	}
}

And to use it I create a Bean:

/*
 * Keep the parent only to deactivate autoconfiguration from springdoc
 */
public class MySwaggerIndexTransformer extends SwaggerIndexTransformer implements ResourceTransformer {

	private MySwaggerIndexTransformerSupport support;

    public MySwaggerIndexTransformer(SwaggerUiConfigProperties swaggerUiConfig, SwaggerUiOAuthProperties swaggerUiOAuthProperties, ObjectMapper objectMapper) {
        super(swaggerUiConfig, swaggerUiOAuthProperties, objectMapper);
		support = new MySwaggerIndexTransformerSupport(swaggerUiConfig, swaggerUiOAuthProperties, objectMapper);
    }

    @Override
    public Mono<Resource> transform(ServerWebExchange serverWebExchange, Resource resource, ResourceTransformerChain resourceTransformerChain) {
        return Mono.just(support.transform(resource, resourceTransformerChain));
    }

}

Describe the solution you'd like
I have 2 proposals based on this use case.

  1. introduce an interface SwaggerIndexPageTransformer declared in common module and used in SwaggerConfig classes
	@Bean
	@ConditionalOnMissingBean
	SwaggerIndexPageTransformer ...

The inconvenience is that it cannot extend ResourceTransformer since ResourceTransformer exist for servlet and reactive resources. Since transformation only uses the Resource you could declare a reduced signature:
Resource transform(Resource resource);

  1. change AbstractSwaggerIndexTransformer to a support class used by composition instead of inheritance to simplify reuse

With this, the specialized behavior would not have to inherit the current SwaggerIndexTransformer but 'only' need to implement an interface.

Describe alternatives you've considered

  • Instead of introducing a new interface (that would break the current contract of the SwaggerConfig classes you could use a named bean:
@Bean
@ConditionalOnMissingBean(name="swaggerUiIndexPageTransformer")
ResourceTransformer indexPageTransformer(...) {...}

I think this is less readable than the proposed evolution and it also breaks the current contract.

The other possibility I see is to declare the AbstractSwaggerIndexTransformer class in signature (instead of the specialized implementation

Additional context
I'm willing to work on this if you agree on these changes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions