Swagger 2 Integration with Spring REST

This is the continuation of my earlier posting,  Swagger For the REST of Us. Here,  I will cover Springfox integration with my REST Hello World project. Though Springfox supports both 1.2 and 2.0 versions of the Swagger specification, I will stick to Swagger 2.0 specification.

Swagger generates metadata including server host name, endpoint URL, mime-types that the API can consume or produce, data types produced and consumed by operations, etc. Swagger exposes API documentation in JSON format by scanning the source code. Swagger UI is part of the Swagger project and consists of a collection of HTML, Javascript, and CSS resources. Swagger UI takes Swagger compliant JSON API documents as input and dynamically generates an interactive UI of the REST services.

I will continue with the ongoing REST Hello World example. You can find the last version of the example in REST API and Error Handling posting. The example source code mentioned in this posting can be found here.

Changes to Maven Dependencies

  • Add springfox-swagger2 dependency to integrate Swagger Springfox with Spring REST service example.
  • Add springfox-swagger-ui dependency to enable Swagger UI.

Configure Docket Configuration Bean

Create a new Docket bean to configure Swagger. A Docket bean is a POJO enabled by @Configuration, @EnableSwagger2, and @Bean annotations. For Swagger 2.0, use @EnableSwagger2 annotation. Here is the example Docket bean:

Import the bean by adding the package name (if it’s missing) in the component-scan tag of the existing rest-dispatcher-servlet.xml.

Verification of Swagger

Once you have the example running, Swagger documentation in JSON format can be viewed at localhost:8080/rest-swag-simple/api-docs.

0

Enable Swagger UI

Other than the addition of new springfox-swagger-ui dependency in the pom.xml, changes need to be made to the rest-dispatcher-servlet.xml to serve the static UI content of Swagger UI. Here are the changes to rest-dispatcher-servlet.xml:

Verification of Swagger UI

Once you deploy the example in Tomcat, the Swagger UI can be viewed by visiting http://localhost:8080/rest-springfox/swagger-ui.html in any browser. In my experience, the behavior of Swagger in Internet Explorer is flaky.

swag-1

Once you have access to Swagger UI, you can view all the operations by clicking Show/Hide.

swag-2.png

You can play around with any of the operations by clicking the operation link. Once the operation is expanded, you can retrieve data by clicking Try it out! button. In this example, try out getCustomers operation. It should fetch a list of customers.

swag-3

Further Customization of Controller (Optional)

Use Swagger annotation to make the API more descriptive and hide some of the internal information, e.g., a controller’s method names, etc. Here are some of the Swagger annotations commonly used to document a controller:

  • @Api describes the general responsibility of the controller.
  • @ApiOperation describes the responsibility of a specific method.
  • @ApiParam describes a  method parameter. It also describes whether a parameter is mandatory or not.

Swagger UI should look more descriptive if you now visit http://localhost:8080/rest-springfox/swagger-ui.html in your browser.

swag-4

Advertisements

48 comments

  1. Good post. Followed step by step and its working, but the problem is that i am not able to change the request URL in the swagger ui .it’s always pointing to the localhost:8080. I have hosted it in the server which has public IP. so finally it should fetch the public ip but it is fetching the localhost ip which makes it difficult to check the services. Help needed.

    Like

      1. Can you please try the latest version of springfox – 2.6.1? I don’t see any problem with one of my other deployments which has a different host name than localhost.

        Like

  2. It’s kind of a hack but try this.

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

    Like

      1. I want know how can we hide the Controller name ex (custom-service-controller) to (Custom Controller). Is there any annotation to rename that. @Api with value and description but it did not reflect).

        Like

      2. When you type ‘hostname’ on your computer terminal, what do you get in return? If it’s ‘localhost’, you need to modify your DNS. How to modify, depends on your OS.

        Like

    1. You need to change the value in ‘tags’ parameter in @Api annotation. Here is an example:

      @Api(value = "Customers API",
      description = "Customer Service",
      produces = "application/json", tags = {"Customer Controller"})

      It should appear in the UI as:

      Api Documentation
      Api Documentation
      Apache 2.0

      Customer Controller: Customer Service Show/Hide| List Operations| Expand Operations

      Liked by 1 person

  3. I have service which takes a requestbody of some model class ex(Users). In this model class i have like 10 attributes. Fo the service i am using only 4 attributes. How can i show only the 4 attributes in swagger UI example value for that service.

    class Users{
    private String userName;
    private String password;
    private String firstName;
    private String lastName;
    private String middleName;
    private String address;
    private String gender;
    private String dob;
    }

    Swagger Ui Exampl Value

    {
    “firstName”: “string”,
    “middleName”: “string”,
    “lastName”: “string”
    }

    Like

    1. You can take advantage of the hidden parameter in @ApiModelProperty annotation. Here is an example:

      @ApiModel
      public class Users{
          private String userName;
          private String firstName;
          private String lastName;
          private String middleName;
      
          @ApiModelProperty(hidden = true)
          public String getUserName() {
              ....
          }
      
          public String getFirstName() {
              ....
          }
      
          public String getLastName() {
              ....
          }
      
          public String getMiddleName() {
              ....
          }
      }
      

      Swagger Ui model should appear like this:

      {
          “firstName”: “string”,
          “middleName”: “string”,
          “lastName”: “string”
      }
      

      Like

      1. Thanks for the reply.

        If the same model class is input for two services and these two require different attributes of the same class

        /getUser accepts json (users object as requestbody)
        {
        “firstName”: “string”,
        “userName”: “string”,
        “lastName”: “string”
        }

        /addUser accepts json (users object as requestbody)
        {
        “firstName”: “string”,
        “middleName”: “string”,
        “lastName”: “string”
        }

        in this scenario how can i display the example value.

        Like

  4. Hi,

    I have multiple rest API’s in a project, r if every api i need to configure swagger separately . So how to make swagger globally for the project and how i use for every api .

    Like

    1. If all your REST controllers are in the same package, only thing you have to do is specify the package during the creation of the Docket. Here is an example of Java configuration:

      Like

  5. Hi,

    So if my project have different modules and the RestControllers are placed in different packages, so is there any way scan multiple packages ..for ex : apis(exactPackage(“com.basaki.example.controller”). here we are scan only one package level insted of this want to scan multiple package from single swagger and make it as global for api documentation.

    Like

      1. Hi,

        it’s working fine. But If I integrate with multiple resources are there in project (when integration time of multiple projects) it won’t scan the other resources packages. why because exactPackage() method fetching classes packages from only one resource. Could you please tell me how to scan project specified path level with single swagger configuration.

        Like

      2. it’s working fine. But If I integrate with multiple resources are there in project (when integration time of multiple resources are in projects) it won’t scan the other resources packages. why because exactPackage() method fetching classes packages from only one resource. Could you please tell me how to scan project specified path level with single swagger configuration.

        Like

  6. is there a way to have a single consolidated UI for different spring boot modules? For ex. i have a Parent project which has like 5 microservices, i want to have a single context where i can show all the apis in a single place.

    Like

    1. Yes, it’s very simple. Just create a Swagger configuration specifying all the controllers. The controller may reside in different modules. In this example, it list all the controllers marked with annotation Api.class.

      Like

  7. hey there..good article..could you show an example when the request body or the response body are of Map type using springfox 2.7

    Like

    1. It shouldn’t be any different from other service methods. Please pay attention to method ‘readMap’ in the ‘TigerController’ example:

      Used springfox 2.7.0 version. Here is the response body.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s