14

I have a controller that I have to keep generic by having it accept a String as @RequestBody and return a String, i.e., String processRequest(@RequestBody String json) {...}

I don't have control over the source code of that controller, but I can get to it programmatically.

The real objects that are going to be passed in and returned are defined elsewhere in a series of request messages: RequestMessage1.java, RequestMessage2.java, etc. Responses are likewise: Response1.java, Response2.java1.

The controller also hands off the processing of these requests to a Processor that looks something like this (Request1Processor.java): Response1 process(RequestMessage1 message).

My question is this.

Is there a way to configure swagger such that it exposes the REST controller class's endpoint, i.e, processRequest, but shows all these Processor classes with their inputs and outputs as the documentation for that controller?

I saw as part of documentation the ability to add models that are not "reachable". I tried the method that's in documentation like this:

@Autowired
private TypeResolver typeResolver;

@Bean
public Docket api() {
  return new Docket(DocumentationType.SWAGGER_2)
      .select()
      .apis(RequestHandlerSelectors.any())
      .paths(PathSelectors.any())
      .build()
      .additionalModels(typeResolver.resolve(Date.class));
}

However, the additional Date model did not show up in swagger-ui.html.

What am I doing wrong here?

Also, is there a way to somehow show that RequestMessage1 type will have a response with Response1?

Vladas Maier
  • 2,054
  • 2
  • 22
  • 34
user1902183
  • 3,203
  • 9
  • 31
  • 48

2 Answers2

12

Date class was an unfavourable example to test because it is treated as a string.

Data Types

...

  • string (this includes dates and files)

Try it again with real models you want to document additionally:

@Bean
public Docket api(TypeResolver typeResolver) {
    return new Docket(DocumentationType.SWAGGER_2)
          .select()
          .apis(RequestHandlerSelectors.any())
          .paths(PathSelectors.any())
          .build()
          .additionalModels(typeResolver.resolve(RequestMessage1.class, Response1.class)));
}
rzymek
  • 9,064
  • 2
  • 45
  • 59
Vladas Maier
  • 2,054
  • 2
  • 22
  • 34
-1

An alternative solution is to extend the already existing docket object instead of creating a new one.

Here is a solution:


import com.fasterxml.classmate.TypeResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.spring.web.plugins.Docket;

@Configuration
public class SwaggerConfiguration {

    private final TypeResolver typeResolver;

    @Autowired
    public SwaggerConfiguration(TypeResolver typeResolver) {
        this.typeResolver = typeResolver;
    }

    @Autowireda
    public void createAdditionalModelDocumentation(Docket docket) {
        docket.additionalModels(typeResolver.resolve(RequestMessage1.class),
                                typeResolver.resolve(Response1.class));
    }

}
Hakan54
  • 3,121
  • 1
  • 23
  • 37