14 min read

In the earlier days, many software solution providers did not really pay attention to documenting their RESTful web APIs. However, many API vendors soon realized the need for a good API documentation solution. Today, you will find a variety of approaches to documenting RESTful web APIs. There are some popular solutions available today for describing, producing, consuming, and visualizing RESTful web services.

In this tutorial, we will explore Swagger which offers a specification and a complete framework implementation for describing, producing, consuming, and visualizing RESTful web services. The Swagger framework works with many popular programming languages, such as Java, Scala, Clojure, Groovy, JavaScript, and .NET.

This tutorial is an extract taken from the book RESTFul Java Web Services – Third Edition, written by Bogunuva Mohanram Balachandar. This book will help you master core REST concepts and create RESTful web services in Java.

A glance at the market adoption of Swagger

The greatest strength of Swagger is its powerful API platform, which satisfies the client, documentation, and server needs. The Swagger UI framework serves as the documentation and testing utility. Its support for different languages and its matured tooling support have really grabbed the attention of many API vendors, and it seems to be the one with the most traction in the community today.

Swagger is built using Scala. This means that when you package your application, you need to have the entire Scala runtime into your build, which may considerably increase the size of your deployable artifact (the EAR or WAR file). That said, Swagger is however improving with each release. For example, the Swagger 2.0 release allows you to use YAML for describing APIs. So, keep a watch on this framework.

The Swagger framework has the following three major components:

  • Server: This component hosts the RESTful web API descriptions for the services that the clients want to use
  • Client: This component uses the RESTful web API descriptions from the server to provide an automated interfacing mechanism to invoke the REST APIs
  • User interface: This part of the framework reads a description of the APIs from the server, renders it as a web page, and provides an interactive sandbox to test the APIs

A quick overview of the Swagger structure

Let’s take a quick look at the Swagger file structure before moving further. The Swagger 1.x file contents that describe the RESTful APIs are represented as the JSON objects. With Swagger 2.0 release onwards, you can also use the YAML format to describe the RESTful web APIs.

This section discusses the Swagger file contents represented as JSON. The basic constructs that we’ll discuss in this section for JSON are also applicable for the YAML representation of APIs, although the syntax differs.

When using the JSON structure for describing the REST APIs, the Swagger file uses a Swagger object as the root document object for describing the APIs. Here is a quick overview of the various properties that you will find in a Swagger object:

  • The following properties describe the basic information about the RESTful web application:
    • swagger: This property specifies the Swagger version.
    • info: This property provides metadata about the API.
    • host: This property locates the server where the APIs are hosted.
    • basePath: This property is the base path for the API. It is relative to the value set for the host field.
    • schemes: This property transfers the protocol for a RESTful web API, such as HTTP and HTTPS.
  • The following properties allow you to specify the default values at the application level, which can be optionally overridden for each operation:
    • consumes: This property specifies the default internet media types that the APIs consume. It can be overridden at the API level.
    • produces: This property specifies the default internet media types that the APIs produce. It can be overridden at the API level.
    • securityDefinitions: This property globally defines the security schemes for the document. These definitions can be referred to from the security schemes specified for each API.
  • The following properties describe the operations (REST APIs):
    • paths: This property specifies the path to the API or the resources. The path must be appended to the basePath property in order to get the full URI.
    • definitions: This property specifies the input and output entity types for operations on REST resources (APIs).
    • parameters: This property specifies the parameter details for an operation.
    • responses: This property specifies the response type for an operation.
    • security: This property specifies the security schemes in order to execute this operation.
    • externalDocs: This property links to the external documentation.
A complete Swagger 2.0 specification is available at Github.
The Swagger specification was donated to the Open API initiative, which aims to standardize the format of the API specification and bring uniformity in usage. Swagger 2.0 was enhanced as part of the Open API initiative, and a new specification OAS 3.0 (Open API specification 3.0) was released in July 2017. The tools are still being worked on to support OAS3.0. I encourage you to explore the Open API Specification 3.0 available at Github.

Overview of Swagger APIs

The Swagger framework consists of many sub-projects in the Git repository, each built with a specific purpose. Here is a quick summary of the key projects:

  • swagger-spec: This repository contains the Swagger specification and the project in general.
  • swagger-ui: This project is an interactive tool to display and execute the Swagger specification files. It is based on swagger-js (the JavaScript library).
  • swagger-editor: This project allows you to edit the YAML files. It is released as a part of Swagger 2.0.
  • swagger-core: This project provides the scala and java library to generate the Swagger specifications directly from code. It supports JAX-RS, the Servlet APIs, and the Play framework.
  • swagger-codegen: This project provides a tool that can read the Swagger specification files and generate the client and server code that consumes and produces the specifications.

In the next section, you will learn how to use the swagger-core project offerings to generate the Swagger file for a JAX-RS application.

Generating Swagger from JAX-RS

Both the WADL and RAML tools that we discussed in the previous sections use the JAX-RS annotations metadata to generate the documentation for the APIs. The Swagger framework does not fully rely on the JAX-RS annotations but offers a set of proprietary annotations for describing the resources. This helps in the following scenarios:

  • The Swagger core annotations provide more flexibility for generating documentations compliant with the Swagger specifications
  • It allows you to use Swagger for generating documentations for web components that do not use the JAX-RS annotations, such as servlet and the servlet filter

The Swagger annotations are designed to work with JAX-RS, improving the quality of the API documentation generated by the framework. Note that the swagger-core project is currently supported on the Jersey and Restlet implementations. If you are considering any other runtime for your JAX-RS application, check the respective product manual and ensure the support before you start using Swagger for describing APIs.

Some of the commonly used Swagger annotations are as follows:

  • The @com.wordnik.swagger.annotations.Api annotation marks a class as a Swagger resource. Note that only classes that are annotated with @Api will be considered for generating the documentation. The @Api annotation is used along with class-level JAX-RS annotations such as @Produces and @Path.
  • Annotations that declare an operation are as follows:
    • @com.wordnik.swagger.annotations.ApiOperation: This annotation describes a resource method (operation) that is designated to respond to HTTP action methods, such as GETPUTPOST, and DELETE.
    • @com.wordnik.swagger.annotations.ApiParam: This annotation is used for describing parameters used in an operation. This is designed for use in conjunction with the JAX-RS parameters, such as @Path@PathParam@QueryParam@HeaderParam@FormParam, and @BeanParam.
    • @com.wordnik.swagger.annotations.ApiImplicitParam: This annotation allows you to define the operation parameters manually. You can use this to override the @PathParam or @QueryParam values specified on a resource method with custom values. If you have multiple ImplicitParam for an operation, wrap them with @ApiImplicitParams.
    • @com.wordnik.swagger.annotations.ApiResponse: This annotation describes the status codes returned by an operation. If you have multiple responses, wrap them by using @ApiResponses.
    • @com.wordnik.swagger.annotations.ResponseHeader: This annotation describes a header that can be provided as part of the response.
    • @com.wordnik.swagger.annotations.Authorization: This annotation is used within either Api or ApiOperation to describe the authorization scheme used on a resource or an operation.
  • Annotations that declare API models are as follows:
    • @com.wordnik.swagger.annotations.ApiModel: This annotation describes the model objects used in the application.
    • @com.wordnik.swagger.annotations.ApiModelProperty: This annotation describes the properties present in the ApiModel object.
A complete list of the Swagger core annotations is available at Github.

Having learned the basics of Swagger, it is time for us to move on and build a simple example to get a feel of the real-life use of Swagger in a JAX-RS application. As always, this example uses the Jersey implementation of JAX-RS.

Specifying dependency to Swagger

To use Swagger in your Jersey 2 application, specify the dependency to swagger-jersey2-jaxrs jar. If you use Maven for building the source, the dependency to the swagger-core library will look as follows:

com.wordnikswagger-jersey2-jaxrs1.5.1-M1
You should be careful while choosing the swagger-core version for your product. Note that swagger-core 1.3 produces the Swagger 1.2 definitions, whereas swagger-core 1.5 produces the Swagger 2.0 definitions.

The next step is to hook the Swagger provider components into your Jersey application. This is done by configuring the Jersey servlet (org.glassfish.jersey.servlet.ServletContainer) in web.xml, as shown here:

jersey 
        org.glassfish.jersey.servlet.ServletContainer 
    jersey.config.server.provider.packages 
         
            com.wordnik.swagger.jaxrs.json, 
            com.packtpub.rest.ch7.swagger 
        1jersey/webresources/*

To enable the Swagger documentation features, it is necessary to load the Swagger framework provider classes from the com.wordnik.swagger.jaxrs.listing package. The package names of the JAX-RS resource classes and provider components are configured as the value for the jersey.config.server.provider.packages init parameter. The Jersey framework scans through the configured packages for identifying the resource classes and provider components during the deployment of the application. Map the Jersey servlet to a request URI so that it responds to the REST resource calls that match the URI.

If you prefer not to use web.xml, you can also use the custom application subclass for (programmatically) specifying all the configuration entries discussed here. To try this option, refer to Github.

Configuring the Swagger definition

After specifying the Swagger provider components, the next step is to configure and initialize the Swagger definition. This is done by configuring the com.wordnik.swagger.jersey.config.JerseyJaxrsConfig servlet in web.xml, as follows:

Jersey2Config 
        com.wordnik.swagger.jersey.config.JerseyJaxrsConfig 
    api.version1.0.0swagger.api.basepath 
            http://localhost:8080/hrapp/webresources 
        1

Here is a brief overview of the initialization parameters used for JerseyJaxrsConfig:

  • api.version: This parameter specifies the API version for your application
  • swagger.api.basepath: This parameter specifies the base path for your application

With this step, we have finished all the configuration entries for using Swagger in a JAX-RS (Jersey 2 implementation) application. In the next section, we will see how to use the Swagger metadata annotation on a JAX-RS resource class for describing the resources and operations.

Adding a Swagger annotation on a JAX-RS resource class

Let’s revisit the DepartmentResource class used in the previous sections. In this example, we will enhance the DepartmentResource class by adding the Swagger annotations discussed earlier. We use @Api to mark DepartmentResource as the Swagger resource. The @ApiOperation annotation describes the operation exposed by the DepartmentResource class:

import com.wordnik.swagger.annotations.Api; 
import com.wordnik.swagger.annotations.ApiOperation; 
import com.wordnik.swagger.annotations.ApiParam; 
import com.wordnik.swagger.annotations.ApiResponse; 
import com.wordnik.swagger.annotations.ApiResponses; 
//Other imports are removed for brevity 
 
@Stateless 
@Path("departments") 
@Api(value = "/departments", description = "Get departments 
     details") 
public class DepartmentResource  { 
 
    @ApiOperation(value = "Find department by id", 
        notes = "Specify a valid department id", 
        response = Department.class) 
    @ApiResponses(value = { 
        @ApiResponse(code = 400, message =  
        "Invalid department id supplied"), 
        @ApiResponse(code = 404, message = "Department not found") 
    }) 
    @GET 
    @Path("{id}") 
    @Produces("application/json") 
    public Department findDepartment( 
        @ApiParam(value = "The department id", required = true)  
        @PathParam("id") Integer id){ 
            return findDepartmentEntity(id); 
        } 
 
    //Rest of the codes are removed for brevity 
 
}

To view the Swagger documentation, build the source and deploy it to the server. Once the application is deployed, you can navigate to http://:///swagger.json to view the Swagger resource listing in the JSON format. The Swagger URL for this example will look like the following:
http://localhost:8080/hrapp/webresource/swagger.json

The following sample Swagger representation is for the DepartmentResource class discussed in this section:

{ 
  "swagger": "2.0", 
  "info": { 
    "version": "1.0.0", 
    "title": "" 
  }, 
  "host": "localhost:8080", 
  "basePath": "/hrapp/webresources", 
  "tags": [ 
    { 
      "name": "user" 
    } 
  ], 
  "schemes": [ 
    "http" 
  ], 
  "paths": { 
    "/departments/{id}": { 
      "get": { 
        "tags": [ 
          "user" 
        ], 
        "summary": "Find department by id", 
        "description": "", 
        "operationId": "loginUser", 
        "produces": [ 
          "application/json" 
        ], 
        "parameters": [ 
          { 
            "name": "id", 
            "in": "path", 
            "description": "The department id", 
            "required": true, 
            "type": "integer", 
            "format": "int32" 
          } 
        ], 
        "responses": { 
          "200": { 
            "description": "successful operation", 
            "schema": { 
              "$ref": "#/definitions/Department" 
            } 
          }, 
          "400": { 
            "description": "Invalid department id supplied" 
          }, 
          "404": { 
            "description": "Department not found" 
          } 
        } 
      } 
    } 
  }, 
  "definitions": { 
    "Department": { 
      "properties": { 
        "departmentId": { 
          "type": "integer", 
          "format": "int32" 
        }, 
        "departmentName": { 
          "type": "string" 
        }, 
        "_persistence_shouldRefreshFetchGroup": { 
          "type": "boolean" 
        } 
      } 
    } 
  } 
}

As mentioned at the beginning of this section, from the Swagger 2.0 release onward it supports the YAML representation of APIs. You can access the YAML representation by navigating to swagger.yaml. For instance, in the preceding example, the following URI gives you the YAML file:
http://:///swagger.yaml

The complete source code for this example is available at the Packt website. You can download the example from the Packt website link that we mentioned at the beginning of this book, in the Preface section. In the downloaded source code, see the rest-chapter7-service-doctools/rest-chapter7-jaxrs2swagger project.

Generating a Java client from Swagger

The Swagger framework is packaged with the Swagger code generation tool as well (swagger-codegen-cli), which allows you to generate client libraries by parsing the Swagger documentation file. You can download the swagger-codegen-cli.jar file from the Maven central repository by searching for swagger-codegen-cli in search maven. Alternatively, you can clone the Git repository and build the source locally by executing mvn install.

Once you have swagger-codegen-cli.jar locally available, run the following command to generate the Java client for the REST API described in Swagger:

    java -jar swagger-codegen-cli.jar generate 
    -i 
    -l 
    -o 

The following example illustrates the use of this tool:

    java -jar swagger-codegen-cli-2.1.0-M2.jar generate 
    -i http://localhost:8080/hrapp/webresources/swagger.json 
    -l java  
    -o generated-sources/java

When you run this tool, it scans through the RESTful web API description available at http://localhost:8080/hrapp/webresources/swagger.json and generates a Java client source in the generated-sources/java folder.

Note that the Swagger code generation process uses the mustache templates for generating the client source. If you are not happy with the generated source, Swagger lets you specify your own mustache template files. Use the -t flag to specify your template folder. To learn more, refer to the README.md file at Github.

To learn more grab this latest edition of RESTful Java Web Services to build robust, scalable and secure RESTful web services using Java APIs.

Read Next:

Getting started with Django RESTful Web Services

How to develop RESTful web services in Spring

Testing RESTful Web Services with Postman


Also published on Medium.


Subscribe to the weekly Packt Hub newsletter. We'll send you the results of our AI Now Survey, featuring data and insights from across the tech landscape.

* indicates required

LEAVE A REPLY

Please enter your comment!
Please enter your name here