Hello Friends,
I was working on documenting my APIs when I came across Swagger and the ease and with the minimum configuration it takes to set up documentation of APIs blew my mind.
It has very few prerequisites, which I was able to do in one sitting. Here are few pointers from my side for the configuration of documentation of your APIs.
The initial configuration is pretty simple, which you can get from a simple google search. I will reiterate the same.
First you need to create a Docket Bean
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors
.basePackage("Name of the base package"))
.paths(PathSelectors.regex("/.*"))
.build();
}
For the UI portion, you need to add the below code:
public void addResourceHandlers(final ResourceHandlerRegistry registry)
{
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
I faced a few problems which I will list down below:
1. Some of my methods in my controller weren’t showing up.
Solution: So, I realized that in the controller methods where I was using @PathVariable annotation, the method was not showing up in the Swagger documenation. The reason for that was I using the Spring version 4.3.1. In their documentation I found that the support for controller method having @PathVariable came in the Spring Boot version 4.3.3. Also, Swagger version 3 will also have this curbed. So, as of now, just upgrade the version of Spring and you should not be having those issues.
2. Using different controllers for different business functions
Okay, this one is not an issue, but an advice to make the documentation better. Swagger will list out all the controllers along with their methods separately. So, make different controllers and annotate them with @RestController and Swagger will show them separately. Also, you can use the below annotations to further give more details about the services.
@Api
– This annotation helps you provide detail of the controller. You can describe what all functionalities are offered inside this controller.
Eg:
@Api(value="My Controller", description="Operations pertaining to my first controller")
@ApiOperation
– This annotation helps you describe the methods and the response type
Eg:
@ApiOperation(value = "The method lists the users", response = List.class)
@ApiModel
– This annotation helps you describe the model
Eg:
@ApiModel(description = "User Model")
3. Changing the defaults on the UI Page
The default values on the UI page are also pretty apt. But if you want to customize those, the below options can help you do that.
private ApiInfo apiEndPointsInfo() {
return new ApiInfoBuilder().title("Your customized title")
.description("The description")
.contact(new Contact("Sunny Jaiswal", "www.xyz.com", "sampleemailid@gmail.com"))
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
.version("1.0.0")
.build();
}
Once the above function is built, you can attach this function to the Docket API you built.
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors
.basePackage("Name of the base package"))
.paths(PathSelectors.regex("/.*"))
.build().apiInfo(apiEndPointsInfo());
}
So, you just add the highlighted portion and you are done with customizing the details on the UI page as per your need.
4. Configuring More
I needed to change the base URL as well as the api-doc URL to suit my needs, since I was going to host the APIs on one of my domains and user forwarding with masking. So, it was important for me that the URL that I am going to show in the UI page are masked.
Also, since I was using forwarding with masking, which essentially shows the services page in an iframe, I was having issues in showing up the page. The reason being that by default, the services of Spring deny to show the page in an iframe. It is governed by a header in the Response called X-Frame-Options which is by default in Deny state. So, for me to use the services from my own domain, I had to allow my domain in the response header. To do that, you need to set the below options in the SecurityConfiguration class:
http.headers().frameOptions().disable()
.addHeaderWriter(new StaticHeadersWriter("X-FRAME-OPTIONS", "ALLOW-FROM http://www.xyz.com"))
Make sure to append the above options overrided configure method.
I found the solution for changing the base URL using the following options. So, here is the Docket bean with the new host that I wanted to use.
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.host("http://www.xyz.com")
.select() .apis(RequestHandlerSelectors.basePackage("Name of base package"))
.paths(PathSelectors.any())
.build().apiInfo(apiEndPointsInfo());
}
I am still looking for a way to change the api-doc URL. I will update the article when I am able to do it.
References: