The new Certification 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 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.6.1</version>
</dependency>

4. Integrating Swagger 2 into the Project

4.1. Java Configuration

The 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 a 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 crucial. 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 know, 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 the 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 particular 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 (original 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.

Go deeper into Spring Security with the course:

>> LEARN SPRING SECURITY

  • 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.

  • metalhead

    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 🙂

  • Antonio José Rodríguez Ríos

    Hi Eugen,

    I have forked your tutorials repository and added the project “spring-security-rest” into my Eclipse triying to see a Swagger + Springfox live demo. When I run the project on Apache Tomcat 8 the default endpoint “http://localhost:8080/spring-security-rest/swagger-ui.html” its empty, only with swagger header but nothing in combobox with swagger endpoint.

    I have uploaded an image at my fork: https://github.com/ajrodriguez/tutorials/blob/master/spring-security-rest/attachments/swagger-error.png

    Thank you for your help.

    • 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.

  • 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.

  • 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?

  • Jean-Sebastien Vachon

    Hi,

    I tried your tutorial into our Spring Rest application and I can’t get Swagger UI to work. The /services.app/v2/api-docs.json page works fine. I can see all my services and their full definition but whenever I go to /services.app/swagger-ui.html all I am seeing is:

    Can’t read swagger JSON from http://xxxx/services.appundefined

    the dropdown found in the top bar shows four entries labeled: undefined (undefined)

    I’ve spent a couple of hours trying to figure out what’s wrong in my setup and could not get it to work.

    Any thoughts?

    • 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.

  • Riky

    Hi Baeldung

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

  • Andree Wormuth

    Hi Eugen,
    thanks for yet another excellent tutorial!
    I have one question, though:
    Do you know of any working example using Swagger and Springfox – quite like yours here – in combination with OAuth2? There are indeed quite a number of sample projects out there, but I have not been able to document my API via Swagger and have it OAuth2 secured…
    Thanks in advance for any hints,
    A.

    • Hey Andree – I’m glad you liked the article.
      The answer is – unfortunately not, but I’m adding it now to the Content Calendar, so it should come out in one-two months.
      Hope that helps. Cheers,
      Eugen.

  • neeraj gupta

    Hi,
    I am facing one issue while generating the swagger documentation. In my case swagger is generating the json data in the v2/api-docs url but it is not rendering all the apis in the swagger-ui. I am not getting what the issue is. Any kind of pointers/help will be highly appreciated.

    • That’s an interesting question, but it’s unfortunately going to be difficult to answer without a lot more detail or looking at the code.
      Generally speaking my suggestion is – try to dig deeper and isolate your problem. A good way to do that is – don’t stop until you have a working code example and a failing test.
      That way when you do ask the question – it’s going to be a lot more concrete and you’ll of course get help a lot faster.
      Hope that helps. Cheers,
      Eugen.

      • harsha udayapriya

        @disqus_jRmyKPMmaD:disqus : Just try with “/swagger-ui.html” on behalf of “v2/api-docs”

  • T Cheng

    Wow, this integration is really simple and straight forward. Thx.

  • T Cheng

    Wonderful article. Just to add a couple of notes here to make it even more complete.

    To customize the summary, notes and return type for an operation, add the following:

    @ApiOperation(value=”The summary goes here.”, notes = “To notes go here.”, response = ReturnType.class)

    before the action method.

    To specify the Response Content Type for an operation, specify it with the produces parameter as this:

    @RequestMapping(value=””, method = RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)

  • sandy

    we are using springfox-swagger2 and have our Rest controllers written in RestEasy. But swagger is not recognizing any of the resources. Basically APIs are not getting listed in the swagger
    UI.

    • Grzegorz Piwowarek

      Sandy, this one is impossible to answer without looking at the code. If you could post your code in GitHub, we could have a look. Before doing this, double check Swagger’s config and if your version supports RestEasy

    • dilipkrish

      As of 2.6.1 only spring based services is supported.

  • szyg

    Hey, what about to make tutorial on how to configure OAuth, Basic Auth with swagger, also with good descirption ?
    = )

  • harsha udayapriya

    Hi, Eugen!
    Very straight forward tutorial!
    I implemented to my existing project it works fine.

    Is there a option to expose two swagger-ui URL’s in the same application.
    I mean one set of REST API under one URL and another set of API’s under different URL

    Thanks

    • Technically, you can simply integrate everything in your main app, yes. I’m using not doing that, but there’s no reason why you wouldn’t be able to. Cheers,
      Eugen.

  • Tom S__o

    Hello, thanks for the tutorial. I believe I have followed this exactly however I have no response on http://localhost:8080/MyApp/api/swagger-ui.html. My starting point for the application in main is SpringApplication.run(MyApp.class, args) I have the required dependencies in my POM file (springfox-swagger-ui v2.6.1 & springfox-swagger2 v2.6.1) I have a class SwaggerConfig into which I copied and pasted the code from the example. I ran my application and tested the URL and nothing returns. I examined which ports are used with netstat and nothing is listening on 8080. One thing to note I added an application.properties file to my configuration to get the Spring controller listening on 8085 as the default port for this Spring app is 8080 which would seemed to conflict with the SwaggerUI. I used the sample project gs-rest-service-complete from Spring as my starting point. I’m sure I’m missing something but I don’t know what that is.