Each API requires comprehensive documentaiton. You can generate it using Swagger for a REST API. Its clients will get standardized and thorough insight while you won’t need to worry about keeping it up to date. Learn how to configure Swagger, generate documentation in JSON and render it with Swagger UI when frontend is supported by Angular.
We are going to use Springfox to produce two versions of the docs:
Our application can be built into a single jar along with the frontend, which is based on Angular 7. Since Spring Boot had to surrender routing control to Angular, we have to allow it to regain command over resources needed to display the web documentation generated with Swagger UI.
The project that was used as the example for this post is available in the GitHub repository – little-pinecone/scrum-ally.
Spring Boot 2.1.2
project with the Web
, JPA
and H2
dependencies. You can read about setting up a similar project with Spring Initializr in How to create a new Spring Boot Project post.Include the Maven dependency for Springfox Swagger2 in the pom.xml
file:
<!--scrum-ally/backend/pom.xml--> … <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> …
In the application we are going to create a new configuration bean:
// scrum-ally/backend/src/main/java/in/keepgrowing/scrumally/config/SwaggerConfig.java … @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket scrumAllyApi() { return new Docket(DocumentationType.SWAGGER_2) .select() .paths(regex("/api.*")) .build() .apiInfo(apiInfo()); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Scrum_ally API") .description("Scrum_ally is a web application designed for project management") .license("MIT License") .licenseUrl("https://opensource.org/licenses/MIT") .build(); } }
@EnableSwagger2
@Configuration
annotation (source).public Docket scrumAllyApi()
.paths(regex("/api.*"))
.apis()
RequestHandlerSelector
. You can specify a package that is going to be documented: .apis(RequestHandlerSelectors.basePackage(“in.keepgrowing…”) or you can filter endpoints using withClassAnnotation
or withMethodAnnotation
predicate. In the example application the regex for paths() is sufficient, therefore I didn’t have to override the default predicate – any
. You can specify here to which extent the API should be documented..apiInfo(apiInfo())
You can learn more about configuration options in the Springfox Reference Documentation.
Now, you should be able to test the configuration. Run the application locally and call the http://localhost:8080/v2/api-docs
link in Postman. You can see the JSON generated for scrum_ally API on the picture below:
If you haven’t declared the response type in RequestMapping
in your controllers yet, the schema generated with Swagger will reveal that your API can produce a response of any type. Mind the "*/*"
in the produces
field:
The solution to the problem was described in this issue on GitHub. We have to impose the "application/json"
response content type on the controllers. Below, you can see the example for my ProjectController
:
// scrum-ally/backend/src/main/java/in/keepgrowing/scrumally/projects/ProjectController.java … @RestController @RequestMapping(value = "api/projects", produces = "application/json") public class ProjectController { …
After rerunning the application, we can see the proper response content type in generated documentation:
You can see the work done in this section in the d93912fc2c170b781f3fd53b399f8efea7ac9b5d commit.
Add the Maven dependency for Springfox Swagger UI:
<!--scrum-ally/backend/pom.xml--> … <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> …
Spring Boot auto-configuration takes care of handling the resources by default. If you haven’t overwrite it, you should be able to see the documentation by visiting http://localhost:8080/swagger-ui.html
:
You can see the work done in this section in the 885c41d3b4e15ddf4a85ef4abc58752af72825cc commit.
You have to manually specify the resources required by Swagger UI. See the example below:
// scrum-ally/backend/src/main/java/in/keepgrowing/scrumally/config/MvcConfiguration.java … @Configuration public class MvcConfiguration implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); } }
In our example, we have a Spring Boot API integrated with Angular and all views are rendered by the fronted. So trying to run the rendered documentation results in 'Cannot match any routes. URL Segment: 'swagger-ui.html'
error. To fix this, we are going to add the "swagger-ui.html"
resource handler to the registry in our MvcConfiguration
:
// scrum-ally/backend/src/main/java/in/keepgrowing/scrumally/config/MvcConfiguration.java … @Configuration public class MvcConfiguration implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { … registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); } }
You can verify the generated JSON by pasting it to the Swagger editor. The debugging process will be more straightforward with the aid of the validation. See the example below:
Allow all GET requests to the documentation resources:
// scrum-ally/backend/src/main/java/in/keepgrowing/scrumally/config/SecurityConfig.java … @Configuration public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception { http … .authorizeRequests() … .antMatchers( HttpMethod.GET, "/v2/api-docs", "/swagger-resources/**", "/swagger-ui.html**", "/webjars/**", "favicon.ico" ).permitAll() … .anyRequest().authenticated(); … } } …
In the Springfox Reference Documentation you can find answers to common question and problems gathered in a separate chapter.
Photo by Mariana Vusiatytska on StockSnap
Spring Security allows us to use role-based control to restrict access to API resources. However,…
A custom annotation in Spring Boot tests is an easy and flexible way to provide…
Delegating user management to Keycloak allows us to better focus on meeting the business needs…
Swagger offers various methods to authorize requests to our Keycloak secured API. I'll show you…
Configuring our Spring Boot API to use Keycloak as an authentication and authorization server can…
Keycloak provides simple integration with Spring applications. As a result, we can easily configure our…