The Master Class of "Learn Spring Security" is out:

>> CHECK OUT THE COURSE

1. Overview

When creating a REST API, good documentation is instrumental.

Moreover, every change in the API should be simultaneously described in the reference documentation. Accomplishing this manually is a tedious exercise, so automation of the process was inevitable.

In this tutorial we will look at Swagger 2 for a Spring REST web service. For the purposes of this article, we will use the Springfox implementation of the Swagger 2 specification.

If you are not familiar with Swagger, you should visit its web page to learn more before continuing with this article.

2. Target Project

The creation of the REST service we will use in our examples is not within the scope of this article. If you already have a suitable project, use it. If not, the following links are a good place to start:

3. Adding the Maven Dependency

As mentioned above, we will use the Springfox implementation of the Swagger specification. To add it to our Maven project, we need a dependency in the pom.xml file.

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

4. Integrating Swagger 2 into the Project

4.1. Java Configuration

Configuration of Swagger mainly centers around the Docket bean.

@Configuration
@EnableSwagger2
public class SwaggerConfig {                                    
    @Bean
    public Docket api() { 
        return new Docket(DocumentationType.SWAGGER_2)  
          .select()                                  
          .apis(RequestHandlerSelectors.any())              
          .paths(PathSelectors.any())                          
          .build();                                           
    }
}

Swagger 2 is enabled through the @EnableSwagger2 annotation.

After the Docket bean is defined, its select() method returns an instance of ApiSelectorBuilder, which provides a way to control the endpoints exposed by Swagger.

Predicates for selection of RequestHandlers can be configured with the help of RequestHandlerSelectors and PathSelectors. Using any() for both will make documentation for your entire API available through Swagger.

This configuration is enough to integrate Swagger 2 into existing Spring Boot project. For other Spring projects, some additional tuning is required.

4.2. Configuration Without Spring Boot

Without Spring Boot, you don’t have the luxury of auto-configuration of your resource handlers. Swagger UI adds a set of resources which you must configure as part of a class that extends WebMvcConfigurerAdapter, and is annotated with @EnableWebMvc.

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

4.3. Verification

To verify that Springfox is working, you can visit the following URL in your browser:

http://localhost:8080/spring-security-rest/api/v2/api-docs

The result is a JSON response with large number of key-value pairs, which is not very human-readable. Fortunately, Swagger provides Swagger UI for this purpose.

 

5. Swagger UI

Swagger UI is a built-in solution which makes user interaction with the Swagger-generated API documentation much easier.

5.1. Enabling Springfox’s Swagger UI

To use Swagger UI, one additional Maven dependency is required:

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.4.0</version>
</dependency>

Now you can test it in your browser by visiting http://localhost:8080/your-app-root/swagger-ui.html

In our case by the way, the exact URL will be: http://localhost:8080/spring-security-rest/api/swagger-ui.html

The result should look something like this:

Screenshot_1

5.2. Exploring Swagger Documentation

Within Swagger’s response is a list of all controllers defined in your application. Clicking on any of them will list the valid HTTP methods (DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT).

Expanding each method provides additional useful data, such as response status, content type, and a list of parameters. It is also possible to try each method using the UI.

Swagger’s ability to be synchronized with your code base is very important. To demonstrate this, you can add a new controller to your application.

@RestController
public class CustomController {

    @RequestMapping(value = "/custom", method = RequestMethod.POST)
    public String custom() {
        return "custom";
    }
}

Now, if you refresh the Swagger documentation, you will see custom-controller in the list of controllers. As you can see, there is only one method (POST) shown in Swagger’s response.

6. Advanced Configuration

The Docket bean of your application can be configured to give you more control over the API documentation generation process.

6.1. Filtering API for Swagger’s Response

It is not always desirable to expose the documentation for your entire API. You can restrict Swagger’s response by passing parameters to the apis() and paths() methods of the Docket class.

As seen above, RequestHandlerSelectors allows using the any or none predicates, but can also be used to filter the API according to base package, class annotation, and method annotations.

PathSelectors provides additional filtering with predicates which scan the request paths of your application. You can use any(), none(), regex(), or ant().

In the example below we will instruct Swagger to include only controllers from a specific package, with specific paths, using the ant() predicate.

@Bean
public Docket api() {                
    return new Docket(DocumentationType.SWAGGER_2)          
      .select()                                       
      .apis(RequestHandlerSelectors.basePackage("org.baeldung.web.controller"))
      .paths(PathSelectors.ant("/foos/*"))                     
      .build();
}

6.2. Custom Information

Swagger also provides some default values in its response which you can customize, such as “Api Documentation”, “Created by Contact Email”, “Apache 2.0”.

To change these values, you can use the apiInfo(ApiInfo apiInfo) method. The ApiInfo class that contains custom information about the API.

@Bean
public Docket api() {                
    return new Docket(DocumentationType.SWAGGER_2)          
      .select()
      .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
      .paths(PathSelectors.ant("/foos/*"))
      .build()
      .apiInfo(apiInfo());
}

private ApiInfo apiInfo() {
    ApiInfo apiInfo = new ApiInfo(
      "My REST API",
      "Some custom description of API.",
      "API TOS",
      "Terms of service",
      "[email protected]",
      "License of API",
      "API license URL");
    return apiInfo;
}

6.3. Custom Methods Response Messages

Swagger allows globally overriding response messages of HTTP methods through Docket’s globalResponseMessage() method. First, you must instruct Swagger not to use default response messages.

Suppose you wish to override 500 and 403 response messages for all GET methods. To achieve this, some code must be added to the Docket’s initialization block (initial code is excluded for clarity):

.useDefaultResponseMessages(false)                                   
.globalResponseMessage(RequestMethod.GET,                     
  newArrayList(new ResponseMessageBuilder()   
    .code(500)
    .message("500 message")
    .responseModel(new ModelRef("Error"))
    .build(),
    new ResponseMessageBuilder() 
      .code(403)
      .message("Forbidden!")
      .build()));
Screenshot_2

7. Conclusion

In this tutorial we set up Swagger 2 to generate documentation for a Spring REST API. We also have explored ways to visualize and customize Swagger’s output.

The full implementation of this tutorial can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

The Master Class of "Learn Spring Security" is out:

>> CHECK OUT THE COURSE

  • Muhammad Yousaf Sajjad

    Can you share the code on github?

    • I just added the link at the very end of the article. Cheers,
      Eugen.

      • Daniel Twum

        Tutorial also worked for me.

        Thanks for a nice writeup.

  • nelaturuk

    Hi, I am not using spring boot. I am not able to add the addResourceHandler method. I am using Spring 4.0 and in the websecurityadapter I have added EnableWebSecurity. Even if i make it EnableWebMvc doesnt seem to work for overrriding the method. Any suggestion for this?

    • The addResourceHandler method is not Boot specific. Actually, section 4.2 covers the extra config you’ll need to do when not using Boot.
      And, generally speaking – there’s no reason you should need Boot to set up Swagger. Hope that helps. Cheers,
      Eugen.

      • nelaturuk

        Thanks Eugen. I added the Swagger Config in the WebMVCSecurityAdapater as metioned by you and it worked!

  • J Walls

    Just starting working on integrating Swagger on my current project. This tutorial was super helpful and well put together, I was able to easily work through initial setup and then more refined tweaks using this guide. Bravo.

  • ladyNi

    Hi Eugen,

    Can u possibly explain how to add a header parameter to be passed with every request made.
    I actually have to send a CSRF token for every request other than GET.
    I tried using their APIKey, but not able to get it working.

    • The CSRF token does indeed make some other aspects more difficult to work with, and Swagger can be one of those aspects. I haven’t looked into the option of integrating Swagger with Spring Security so that you can then have the CSRF token available in Swagger.
      It may be possible, I just haven’t looked into it. Cheers,
      Eugen.

  • jothi manickam

    Hi I got the response message for user input request but did not work for parameter..please guide me to achieve this …need to set any annotation for bean class

    • Well Jothy – I’d have to look at code to know what’s happening there. Go ahead and open an issue over on Github with the details and I’d be happy to have a look. Cheers,
      Eugen.

  • Scott Duncan

    Great article. I am using the default Doclet config as shown above. Works great when I run locally but when I deploy to a server swagger-ui.html shows the swagger ui header but the body of the page is blank. Looking at the developer console I see some 404s:

    http://…./configuration/ui Failed to load resource: the server responded with a status of 404 (Not Found)

    http://…./configuration/security Failed to load resource: the server responded with a status of 404 (Not Found)

    http://…./swagger-resources Failed to load resource: the server responded with a status of 404 (Not Found)

    Any idea why this is happening?

    • Hmm – that’s interesting – I’m not sure, I’d have to look at the actual implementation.
      The best way to ask this kind of very specific question is with an example. My suggestion is – create a very simple project that you can run to reproduce it (but does nothing else).
      Then, send me a link to that, or post the question on StackOverflow and send me a link to the question – I’d be happy to have a look. Cheers,
      Eugen.

  • riki

    hi, I have a question. I want to upload a file but swagger ui shows only a textbox. Is it possible to upload files in swagger?

  • Dipesh Rane

    Hi, I am using Oauth2 along with spring-boot. However along with my endpoints Swagger is also listing oauth2 endpoints which I dont want to be part of my Swagger documentation.

    It has

    1. authorization-endpoint which has a bunch of HTTP operations available under the /oauth/authorize path

    2. check-token-endpoint which has a bunch of HTTP operations available under the /oauth/check_token path

    3. whitelabel-approval-endpoint which has a bunch of HTTP operations available under the /oauth/confirm_access path

    4. whitelabel-error-endpoint which has a bunch of HTTP operations available under the /oauth/error path

    How to get rid of these ?? Any help would be appreciable.

    Thaks in Advance

    • That’s an interesting question.
      A simple way to do it would be – if your API has a common path root such as /api – to use the path API in the configuration and make sure you explicitly only include your actual API instead of any().
      Now – that may not be an option or it may not be the most flexible way to do it. I had a look at the docs and there are several discussion threads over on Github talking about the extension points and the ways to hide something.
      All that to say – there may be better, more idiomatic ways to do it, but I would start with the simple way and see if that fits your usecase. If not – take to github.
      Hope it helps and best of luck with the implementation. Cheers,
      Eugen.

  • Kai

    Thanks! Very good structured tutorial!

  • Jmp Jmp

    Excellent Tutorial, every thing is working as per the given explanation.

  • Zoltán

    nice blog about swagger2, the intergalactic web is really messy about the different versions (annotations, how to use, etc…) and not so clean as this site, also the official swagger site is unusable i think

    • Glad you found the writeup valuable Zoltan – I liked the bit about the “intergalactic” web 🙂
      Cheers,
      Eugen.

  • rshibley

    How do you customize the looks of swagger-ui.html ?

    • That’s an interesting question, and it depends a lot on what you’re trying to customize. What are you trying to change exactly?

      • FAtore

        I have similar question. I would like to use the twitter api interface instead of the default swagger look.

  • Preetham Myneni

    This is an excellent implementation. Everything is working fine.
    But Swagger UI is not generating XML in Model for application/xml. Can you let me know any way i can get that

    • Hey Preetham – that’s interesting – but I’ll need a lot more detail that that to figure out exactly what you’re looking for.
      I’m assuming that’s something you can replicate on the reference project. If that’s the case, just open an issue over on Github (with more details) and I’ll have a look. Thanks,
      Eugen.

  • FiMa

    Works super fine just out of the box! Thanks a lot for describing.

  • rasmita

    my application is apache cxf can i configure this? and I am using swagger 1.5.8

    • Well Rasmita – there’s no reason you shouldn’t be able to.

  • Paul

    Great tutorial very helpful, I had swagger up and running in 5 minutes. Do you have to use the Docket class for configuration or is there a possiblity of annotating only the controllers you want to expose publically instead?

    • I haven’t tried to do it without at least a minimal config class – so I’m not sure. It may be an option, but even if it is, you’re of course going to be forced to use the defaults – so using the config class is a quick and easy way to get some control over Swagger.

  • Shiv

    Built spring-security-rest and deployed it in tomcat. Ran http://localhost:8080/spring-security-rest/v2/api-docs. But it is giving 404 error..what I’m missing?

  • Vinicius Martins Rosa

    Hi, Eugen!
    Very good tutorial!
    Is there a way to configure swagger to read specs from different applications?
    I tried to find any solution but without success.

    • That’s definitely an interesting question. I haven’t had that particular need before, so I don’t know. If you do find it’s possible, I’d be curious to know as well.
      Cheers,
      Eugen.

      • Vinicius Martins Rosa

        Hi, i solved the problem declaring a filter that makes a foward from /swagger-resources to /my-swagger-resources and creating a controller with this request mapping.

        In the controller i return a List response entity and in the body i create my own api-docs endpoints pointing to any application i have.

        Not the best soluction,but it works.

        cheers

  • Kalyan Pradhan

    Very nice explanation and good tool for documenting all the apis effortlessly. Saves a lot of time. Thanks!!

  • Rick

    Great tutorial on integrating Swagger with both Spring Boot and the manual Spring configuration. However, I can’t seem to get the context to load with a SpringJUnit4ClassRunner test implementation.

    During testing (just loading the context), the Swagger config file above seems to break because it won’t seem to produce the Swagger UI unless I use the @Configuration annotation to it. Note the annotation’s JavaDoc:

    “This should be applied to a Spring java config and should have an accompanying ‘@Configuration’ annotation.”

    When I do that, unless I don’t test after the build, there’s a bean configuration/inject NoSuchBeanDefinitionException exception for RequestMappingInfoHandlerMapping. If I simply assemble my project and run the Spring Boot “bootRun” task, it’ll run the embedded server and load up my API and Swagger UI as expected.

    If, however, rather than adding an @Configuration annotation, I add an @EnableSwagger annotation, it runs fine, both during a test and the bootRun task, displaying the expected Swagger UI for the respective REST API. In other words, I use both @EnableSwagger and @EnableSwagger2 annotations in my SwaggerConfig class.

    I’m using Swagger-UI, Swagger1 and Swagger2 ver 2.4.0. What are your thoughts?

    • Rick

      My apologies. This was due to me not adding the “@WebAppConfiguration” annotation to my test class.

      Great tutorial!!

  • Anurag

    I m getting CURL and response Header a little unnecessary info
    How I can hide this?

    • Hey Anurag,
      I’m not sure I fully understand your question. If you’re asking how you can hide the header information when using curl – it depends on your exact curl command, but generally speaking make sure you don’t use the -i flag (include) or the -v flag (verbose).
      Hope that helps. Cheers,
      Eugen.

  • Onkar

    Hey, nice and clear Tutorial, everything is working for my application for now.
    I just wanted to know how to add the basic authentication scheme to my existing spring application. I have successfully integrated swagger into my existing application. It would be great if you could guide me into the right direction so that users of my application will only be able to access the endpoints after providing some key or token. Thanks 🙂

  • Narwen Tamang

    How do you provide multiple paths in .paths( ). Suppose for /auth/ and /rest?

    • Hey Narwen,
      You can simply chain multiple paths calls, since the API is fluid.
      Hope that helps. Cheers,
      Eugen.

  • Hey Antonio – that’s interesting, I’ll look into it. Cheers,
    Eugen.

  • Muhammad Bilal
    • Antonio José Rodríguez Ríos

      Thanks Muhammad! I can acces to swagger ui with that url.

      • Muhammad Bilal

        Great!

  • Aditya

    were you able to solve this? I am also getting the same thing. Please let me know.

    • Antonio José Rodríguez Ríos

      Yep, I just put the url that Muhammad indicates below and with default config swagger-ui it shows ok.

  • Eduardo Medeiros Branquinho

    Sweet! Very easy tutorial. I tought it would be difficult use Swagger do create a doc… but man…that was easy! And the ui is very nice. Thanks, dear author. I love you man.

  • shane lee

    great article mate. i currently use swagger for api documentation and swagger ui as test harness. one change i would recommend is to remove swagger ui from microservice. its not recommended to serve up static web content from API. returning the open api spec (as its json) is fine. we found an issue in spring boot with certain requests for (PATCH, PUT, DELETE) not returning the correct response code. this is due to serving up swagger UI. we are currently in the process of removing swagger UI and instead serving up from s3 bucket. that way, it is standalone and the only requirement from the API is to provide the open api spec.

    • Hey Shane,
      Yes, definitely – in a production scenario I would recommend the same thing – deploying the UI separately. This is a good place to start, and a run-down of how to set things up, but you can definitely take it further.
      So that may be a good topic for a new article. Cheers,
      Eugen.

      • shane lee

        Totally agree. i like the filtering that you showed. With spring-boot-actuator we do not want to expose these endpoints as part of our swagger spec.

  • Juan Hernandez

    Amazing tutorial, but I dont understand why the default api-docs url starts with v2? shouldnt v2/api-docs stand for the api version 2.x ? shouldnt this one be just api-docs? am I missing something?

    • Hey Juan,
      This particular URL isn’t about your own API, but about Swagger itself (and we are using v2 here).
      However, I can see how that might be confusing if you also version your API as well. There are of course several solutions to that – from the simplest which would be just leaving it as it is (I assume the URL doesn’t conflict) to changing the Swagger mapping, to maybe prefixing your own API with something like /api. Again – several options.
      Hope that clears things up. Cheers,
      Eugen.

  • Gale dev

    Nice Article. We are trying to reorder our Endpoints. We found that the only way to do this is to make sure tag of your endpoints has to be alpha sorted. Position attribute was gone and we are out of ides. Any other idea?

  • Riky

    Hi Baeldung

    It was really a superb article. I was struct here since few days. you solve my problem. Great thanks buddy.

  • Hey Jean,
    That’s interesting – I’d love to have a look, but we need to first see if the problem happens on the example project. Once we go beyond that, the number of potential causes goes way up, so it’s of course harder to pinpoint without looking at the code.
    So, let me know if you’re able to replicate the issue on the project in the Github repo.
    Thanks,
    Eugen.