Spring and Open API (Swagger)

The Web Application Description Language (WADL) is a machine readable XML description of REST services. In the Java world WADL implementation libraries tend to be JAX-RS specific or constructed using maven plugins.

My current project is using Spring 4.3 and I needed a way to present my REST API in a format that could be consumed by Ready! API and SOAP UI.

Enter Swagger, which has become the reference implementation for OpenAPI. OpenAPI has the backing of companies like IBM (check out Watson’s API), Google and Microsoft.

To get Swagger to work with Spring I used SpringFox‘s library, which had it’s origins in swagger-springmvc.

The first step is to include Springfox’s library in your maven or gradle build. Here is a maven pom.xml example:

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.5.0</version>
</dependency>

The second step is to configure Swagger.

@EnableSwagger2
public class SwaggerAPIConfig {

    private final TypeResolver typeResolver;

    @Inject
    public SwaggerAPIConfig(TypeResolver typeResolver) {
        this.typeResolver = typeResolver;
    }

    @Bean
    public Docket gpcApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                    .apis(RequestHandlerSelectors.any())
                    .paths(PathSelectors.any())
                    .build()
                .pathMapping("/")
                .directModelSubstitute(LocalDate.class, String.class)
                .genericModelSubstitutes(RequestEntity.class)
                .alternateTypeRules(
                        newRule(typeResolver.resolve(DeferredResult.class,
                                typeResolver.resolve(ResponseEntity.class, WildcardType.class)),
                                typeResolver.resolve(WildcardType.class)))
                .useDefaultResponseMessages(false)
                .globalResponseMessage(RequestMethod.GET,
                        newArrayList(new ResponseMessageBuilder()
                        .code(500)
                        .message("500 message")
                        .responseModel(new ModelRef("Error"))
                        .build()))
                .enableUrlTemplating(true)
                .apiInfo(apiInfo())
                .tags(new Tag("My Services", "All APIs related to my service")
        );
    }

    private ApiInfo apiInfo() {
        return new ApiInfo(
                "API Documentation",
                "My REST APIs",
                "0.1",
                "",
                new Contact(
                        "Kyle Ryan",
                        "www.kyleryan.net",
                        "my_email@address"),
                "",
                ""
        );
    }

Finally, update your Spring WebConfig to import your SwaggerAPIConfig. This will tell swagger where your controllers are so that it can generate the API feed.

@Configuration
@EnableWebMvc
@Import(SwaggerAPIConfig.class)
@ComponentScan("net.kyleryan.api.controller")
public class WebConfig extends WebMvcConfigurerAdapter {


    @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");
    }
}

Once you have your application running with these changes, the API will be available to load into Postman, Ready! API, SOAP UI etc at a URL that looks similar to this: http://localhost:8080/v2/api-docs.

Hope this helps!

Kyle

Leave a Reply

Your email address will not be published. Required fields are marked *