Header-85.jpg

Swagger - Cataloging With the World's Most Popular Framework for APIs

As a developer in today's tech industry, it's almost guaranteed you will be developing and maintaining an API in your application. The simplistic nature of RESTful web services has driven the exponential growth of APIs. Despite this simplicity, developers often face a significant challenge once someone tries to consume the API. Take some time to think about how you develop your APIs. Are you documenting what your API actually does? And if so, is it up to date and does it cover all the details your consumer needs? Probably not. Why? Because writing a full API specification is REALLY boring and VERY tedious work, especially when APIs are added or change frequently. Next, what if your consumer wants to test your API? Do you send them a URL and say, "here, figure it out!" As a frequent consumer of APIs, that is often the response I get from consumers. Finally, is there nothing more annoying than a consumer that wants to know what type of error codes your API will respond with? Come on people! Just test the service and you can figure out the answers for yourself!

swagger

Now, what if a product existed that could help you auto-generate a significant amount of your API documentation? What if it followed a standard specification that could describe your API in the details that your consumer needs, including request parameters, response type and error codes? What if it displayed your API in a very readable format and even allowed a consumer to test the API? Well, that product does exist and its called Swagger.

Swagger is a powerful product that includes a standard specification, framework and tool set to support cataloging your APIs. In this blog post, I'll demonstrate just how easy it is to get Swagger up and running in your application. I'll cover the Swagger specification in details. I'll walk through how you can annotate code to easily document an API and generate a Swagger specification. Then, I'll show you how to use the Swagger UI tool to view and test out an API. By the end of this blog post, you'll understand how cataloging an API with Swagger will increase the program-ability, governance and success of your APIs.

The Swagger Specification and Toolset

Swagger is a framework for defining REST APIs in a standard format. It is developed and maintained by SmartBear. Swagger is fully free, open-source technology covered by the Apache 2.0 license. At the foundation of Swagger is a formal specification. The full specification text can be found here: http://swagger.io/specification, with the specification project available on GitHub: https://github.com/swagger-api. The current specification version is 2.0 as of 09/2014. Why is this important? By defining a full standard for your API, you can guarantee that the documentation for your API will cover all the details that your consumer needs for understanding your API. If your environment has multiple systems, using the Swagger standard provides a consistent document template for everyone to follow and understand. Some key aspects of the specification include:

 

  • Format of the specification, which is JSON.
  • File structure, which is often a single file named swagger.json.
  • Primitive data type support, such as integer, long, float, boolean, etc.
  • Schema, which covers the bulk of configurations, including service meta-data, paths, operations, parameters, headers and responses.

 

One of the purposes of this specification is to provide a standard for tools to leverage for documenting your APIs. These tools allow you to quickly integrate Swagger into your project. Unlike some specifications, you will not be required to re-write your API logic to support Swagger. You are simply defining your API in terms of the Swagger specification. While the specification is fairly detailed, tools help ease the curve for entry into usage. These tools also reduce the need for you to write custom code to display your API specification. The core tools are listed below:

  • Swagger Core = the Java implementation of Swagger. Swagger core provides server integrations and examples for generating an API specification. Its key to note that Swagger core supports JAX-RS and plain servlets only at this time.
  • Swagger Codegen = a command-line tool for generating code from a Swagger definition.
  • Swagger UI = a browser-based UI for viewing Swagger defined APIs as well as executing them.
  • Swagger Editor = a browser-based editor for creating and modifying Swagger definitions.

In this blog post, we are going to focus on Swagger Core and Swagger UI. Let's look at the specification and tools in action.

JAX-RS Jersey Swagger Example

I've provided a fully implemented API example project for this blog. You can easily access it from the following GitHub repository: https://github.com/NVISIA/swagger-jaxrs-example. A few things to note about the project:

  • Maven is required for builds.
  • Jersey 2.22.1 is leveraged for the JAX-RS implementation.
  • The example project shows an implementation using a non-web.xml configuration.
  • The example project works off the assumption that you already have a REST API and want to add Swagger to it.

First, I'm going to walk you through the steps I took to introduce Swagger into the project.

Maven POM File

To support Swagger in the application I added the following Maven dependency:

Maven POM Dependency for Swagger

<dependency>
   <groupId>io.swagger</groupId>
    <artifactId>swagger-jersey2-jaxrs</artifactId>
    <version>1.5.4</version>
</dependency>
 
As the artifact ID in line 3 implies, this is Swagger's implementation for JAX-RS Jersey 2. As of the time this blog was written, Swagger supports four implementations out of the box: JAX-RS 1.X, JAX-RS 2.X, RESTEasy 2.X and Mule. Once this dependency is in the POM, Maven will include the Swagger jaxrs library and the Swagger core library. Note, I am using the latest version of Swagger's JAX-RS Jersey 2 dependency, which is 1.5.4. With the dependency added to the project, the next step is to configure Swagger to be available at run-time.

Application Configuration Class

In the application configuration class, I needed to add two sections of code. First, I registered two classes from Swagger: io.swagger.jaxrs.listing.ApiListingResource and io.swagger.jaxrs.listing.SwaggerSerializers. Then, I initialized an instance of io.swagger.jaxrs.config.BeanConfig to define the base configuration for Swagger in the application. I'll go into further explanation after the code snippet below.

SwaggerJaxRsExampleApp.java

package com.nvisia.swagger.jaxrs.config;
 
import javax.ws.rs.*;
 
import org.glassfish.jersey.server.*;
 
/**
 * Defines the components of the application.
 *
 * @author Michael Hoffman, NVISIA
 *
 */
@ApplicationPath("services")
public class SwaggerJaxRsExampleApp extends ResourceConfig {
 
   public SwaggerJaxRsExampleApp() {
      packages("com.nvisia.swagger.jaxrs");
 
      register(io.swagger.jaxrs.listing.ApiListingResource.class);
      register(io.swagger.jaxrs.listing.SwaggerSerializers.class);
 
      io.swagger.jaxrs.config.BeanConfig beanConfig = new io.swagger.jaxrs.config.BeanConfig();
      beanConfig.setSchemes(new String[] { "http" });
      beanConfig.setHost("localhost:8080");
      beanConfig.setBasePath("/swagger-jaxrs-example/services");
      beanConfig.setResourcePackage("com.nvisia.swagger.jaxrs");
      beanConfig.setScan(true);
      beanConfig.setPrettyPrint(true);
 
      io.swagger.models.Info info = new io.swagger.models.Info();
      io.swagger.models.Contact contact = new io.swagger.models.Contact();
      contact.setEmail("user@user.org");
      contact.setName("Michael Hoffman");
      contact.setUrl("http://www.nvisia.com");
      info.setContact(contact);
      info.setDescription("NVISIA Swagger JAX-RS Example");
      info.setTitle("swagger-jaxrs-example");
      info.setVersion("1.0");
      beanConfig.setInfo(info);
   }
}

So what is going on in these blocks of code? Let's first look into lines 19 and 20 where I registered the two Swagger classes.

  • In line19, I registered io.swagger.jaxrs.listing.ApiListingResource.class. This class adds support for Swagger's resource APIs, which return the Swagger specification in either JSON or YAML format as configured for the application.
  • In line 20, I registered io.swagger.jaxrs.listing.SwaggerSerializers.class. This class simply defines how to write out the response of the Swagger specification.

 

These two lines allow any consumer to retrieve the Swagger specification from the project, but how do we create the content for the specification? Creating the content is a two step process. The first step is to initialize the Swagger configuration as we have done in lines 22-39 of the SwaggerJaxRsExampleApp class. I created an instance of io.swagger.jaxrs.config.BeanConfig in the constructor, which registers the bean for run-time. Below is an explanation of each of the setters that I've configured:

  • Schemes = The transfer protocol(s) of the API. There are four options that you can choose from: http, https, ws, wss. Defining schemes is optional and will default to the protocol used when accessing Swagger.
  • Host = The host name or IP and the port where the API is located. Host name and port are both optional and will default to the host name and port used when accessing Swagger.
  • Base Path = The base path relative to the host name where the API is served from. This is required for Swagger to operate correctly.
  • Resource Package = The comma-separated list of packages where resources for the API can be scanned by Swagger.
  • Scan = A flag that tells Swagger whether or not it should build documentation.
  • Pretty Print = A flag that tells Swagger whether or not to return the specification using pretty print.
  • Email = The contact email address.
  • Name = The contact name
  • URL = The URL for the contact
  • Description = The description of the application.
  • Title = The title of the application.
  • Version = A required setting that identifies the version of your application API. Be careful not to confuse this with the version of Swagger or the Swagger specification.

Once I've registered the Swagger resource class, serializer and bean configuration, I can start the application in a container and navigate to the Swagger specification URL: http://localhost:8080/swagger-jaxrs-example/services/swagger.json. It should return the JSON below.

Swagger JSON Specification

{
  "swagger" : "2.0",
  "info" : {
    "description" : "NVISIA Swagger JAX-RS Example",
    "version" : "1.0",
    "title" : "swagger-jaxrs-example",
    "contact" : {
      "name" : "Michael Hoffman",
      "url" : "http://www.nvisia.com",
      "email" : "user@user.org"
    }
  },
  "host" : "localhost:8080",
  "basePath" : "/swagger-jaxrs-example/services",
  "schemes" : [ "http" ]
}

If you see the object above returned, it means that Swagger is correctly configured for the application. The minimal amount of effort to introduce Swagger to an application is one facet of why I think Swagger is so powerful. I wasn't required to dive deep into the API to get a basic specification setup. I am also not required to hand-code or manually update the specification. It just gets generated for me. Below are the details of what the values in the specification mean.

  • The Swagger specification is a schema. The root of the schema is a Swagger object. You can find the full definition of the object here:http://swagger.io/specification/#swaggerObject.
  • There are five values that have been set for this specification.
    • swagger = This is a required field that defines the Swagger specification version used. The application automatically set this value for us.
    • info = This is an object that provides meta-data about the API. The full definition of this object can be found here: http://swagger.io/specification/#infoObject. Note the fields on the info object have been populated with the values configured on the BeanConfig class, including the description, version number, title and contact details.
    • host = This is the host name where the API is served from. This value is set by the BeanConfig value we created at startup.
    • basePath = This is the base path where the API is served from. Again, this value is set by the BeanConfig value we created at startup.
    • schemes = This is the list of protocols supported by the API. Similar to the host and basePath values, this value is set by the BeanConfig value we created at startup.

Now that we have the foundation for our specification, we need to annotate our APIs so that Swagger can include them in the specification.

Annotating Service Classes

With Swagger configured for the application, the next step I needed to take was to annotate my resource service classes so that they would be included in the generated specification. I'm going to focus on the OrderResource class. Let's start with the class definition.

OrderResource.java

package com.nvisia.swagger.jaxrs.order;
 
import java.util.*;
 
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.*;
 
/**
 * Order resource
 *
 * @author Michael Hoffman, NVISIA
 *
 */
@Path("order")
@io.swagger.annotations.Api(value = "order")
public class OrderResource {
 
// CONTENT
 
}

In line 16, you can see that I've annotated the class with the Swagger annotation io.swagger.annotations.Api. This simply marks the class as a Swagger-scanable resource and should be included in the documentation. The value is set to "tag" the resource for documentation grouping purposes. Now that the class will be scanned by Swagger, we need to annotate the individual behaviors of the API. I'm going to start with the method to get an order by ID.

OrderResource.getCustomer

@GET
@Path("{orderId}")
@Produces(MediaType.APPLICATION_JSON)
@io.swagger.annotations.ApiOperation(value = "Find order by ID",
      notes = "Returns one order by ID", response = Order.class)
@io.swagger.annotations.ApiResponses(value = {
      @io.swagger.annotations.ApiResponse(code = 500,
            message = "An internal error occurred"),
      @io.swagger.annotations.ApiResponse(code = 404,
            message = "Order not found for ID") })
public Order getOrder(@io.swagger.annotations.ApiParam(
      value = "Order ID to find by") @PathParam("orderId") int orderId) {
   OrderService orderService = new DefaultOrderService();
   Order order = null;
   try {
      order = orderService.getOrder(orderId);
   } catch (Exception e) {
      throw new WebApplicationException(Response.status(Status.INTERNAL_SERVER_ERROR)
            .type(MediaType.APPLICATION_JSON).build());
   }
   if (order == null) {
      throw new WebApplicationException(Response.status(Status.NOT_FOUND)
            .type(MediaType.APPLICATION_JSON).build());
   }
   return order;
}

In the method definition, I needed to add three annotations:

  • In line 4, I defined an annotation of io.swagger.annotations.ApiOperation on the method. The value refers to a very short summary of what the service does. The notes value refers to key notes about what the service is and its behavior. Finally, I noted the response type that is supported by this API.
  • In line 6, I defined an annotation of io.swagger.annotations.ApiResponses on the method. The annotation defines one or more responses that are possible from this API, including a more detailed message about what the code means.
  • In line 11, I defined an annotation of @io.swagger.annotations.ApiParam on the input parameter. The annotation denotes the input is an API parameter and includes a brief description.

 

The second method I'll show is a post method.

OrderResource.submitOrder

@POST
@Path("submitOrder")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED })
@Produces(MediaType.APPLICATION_JSON)
@io.swagger.annotations.ApiOperation(value = "Submit an order",
      notes = "Submits a new order", response = Order.class)
@io.swagger.annotations.ApiResponses(value = {
      @io.swagger.annotations.ApiResponse(code = 500,
            message = "An internal error occurred"),
      @io.swagger.annotations.ApiResponse(code = 404,
            message = "Order not found for ID"),
      @io.swagger.annotations.ApiResponse(code = 400,
            message = "Invalid order - no order items") })
public Order submitOrder(
      @io.swagger.annotations.ApiParam("Order form with order details") OrderForm orderForm) {
   if (orderForm.getOrderItems() == null || orderForm.getOrderItems().isEmpty()) {
      throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
            .type(MediaType.APPLICATION_JSON).build());
   }
   OrderService orderService = new DefaultOrderService();
   Order order = null;
   try {
      order = orderService.submitOrder(orderForm.getCustomerId(),
            orderForm.getOrderItems(), new Date(System.currentTimeMillis()));
   } catch (Exception e) {
      throw new WebApplicationException(Response.status(Status.INTERNAL_SERVER_ERROR)
            .type(MediaType.APPLICATION_JSON).build());
   }
   if (order == null) {
      throw new WebApplicationException(Response.status(Status.NOT_FOUND)
            .type(MediaType.APPLICATION_JSON).build());
   }
   return order;
}

As you can see, the post method type has the same three annotations added as the get method. Line 5 annotates the method with an ApiOperation annotation, line 7 annotates the method with an ApiResponses annotation and line 15 annotates the input parameter with an ApiParam annotation. A few additional notes on the annotations:

  • While Swagger was able to determine which HTTP method each API used, you can also set the httpMethod value on the ApiOperation annotation to be more explicit.
  • If you need to provide authorization for your APIs, you can set the authorizations value on the ApiOperation annotation.

 

This shows a second facet of the power of Swagger. I can quickly annotate my API without having to change the internals of my methods. The annotations are consistent across different operations and Swagger can intelligently determine the intended format of my API. If you start the server now and look at the specification, you should see the results of adding these annotations. Below is the updated JSON specification.

Swagger Specification with Orders

{
  "swagger" : "2.0",
  "info" : {
    "description" : "NVISIA Swagger JAX-RS Example",
    "version" : "1.0",
    "title" : "swagger-jaxrs-example",
    "contact" : {
      "name" : "Michael Hoffman",
      "url" : "http://www.nvisia.com",
      "email" : "user@user.org"
    }
  },
  "host" : "localhost:8080",
  "basePath" : "/swagger-jaxrs-example/services",
  "tags" : [ {
    "name" : "order"
  } ],
  "schemes" : [ "http" ],
  "paths" : {
    "/order/submitOrder" : {
      "post" : {
        "tags" : [ "order" ],
        "summary" : "Submit an order",
        "description" : "Submits a new order",
        "operationId" : "submitOrder",
        "consumes" : [ "application/json", "application/x-www-form-urlencoded" ],
        "produces" : [ "application/json" ],
        "parameters" : [ {
          "in" : "body",
          "name" : "body",
          "description" : "Order form with order details",
          "required" : false,
          "schema" : {
            "$ref" : "#/definitions/OrderForm"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "successful operation",
            "schema" : {
              "$ref" : "#/definitions/Order"
            }
          },
          "400" : {
            "description" : "Invalid order - no order items"
          },
          "500" : {
            "description" : "An internal error occurred"
          },
          "404" : {
            "description" : "Order not found for ID"
          }
        }
      }
    },
    "/order/{orderId}" : {
      "get" : {
        "tags" : [ "order" ],
        "summary" : "Find order by ID",
        "description" : "Returns one order by ID",
        "operationId" : "getOrder",
        "produces" : [ "application/json" ],
        "parameters" : [ {
          "name" : "orderId",
          "in" : "path",
          "description" : "Order ID to find by",
          "required" : true,
          "type" : "integer",
          "format" : "int32"
        } ],
        "responses" : {
          "200" : {
            "description" : "successful operation",
            "schema" : {
              "$ref" : "#/definitions/Order"
            }
          },
          "500" : {
            "description" : "An internal error occurred"
          },
          "404" : {
            "description" : "Order not found for ID"
          }
        }
      }
    }
  },
  "definitions" : {
    "Order" : {
      "type" : "object",
      "properties" : {
        "orderId" : {
          "type" : "integer",
          "format" : "int32"
        },
        "orderCustomerId" : {
          "type" : "integer",
          "format" : "int32"
        },
        "orderNumber" : {
          "type" : "string"
        },
        "orderItems" : {
          "type" : "array",
          "items" : {
            "$ref" : "#/definitions/OrderItem"
          }
        },
        "timeOrderPlaced" : {
          "type" : "string",
          "format" : "date-time"
        }
      }
    },
    "OrderForm" : {
      "type" : "object",
      "properties" : {
        "customerId" : {
          "type" : "integer",
          "format" : "int32"
        },
        "orderItems" : {
          "type" : "array",
          "items" : {
            "$ref" : "#/definitions/OrderItem"
          }
        }
      }
    },
    "OrderItem" : {
      "type" : "object",
      "properties" : {
        "orderItemId" : {
          "type" : "integer",
          "format" : "int32"
        },
        "orderedProductId" : {
          "type" : "integer",
          "format" : "int32"
        },
        "itemPrice" : {
          "type" : "number",
          "format" : "double"
        },
        "inStock" : {
          "type" : "boolean",
          "default" : false
        }
      }
    }
  }
}

In case its not obvious, Swagger has just added a lot of content to the specification. This is what makes the Swagger tooling so important. If we had to manually configure the specification, it would take longer than the actual coding effort! Let's dive into the new additions that were generated in the specification.

Tags

"tags" : [ {
  "name" : "order"
} ],

The tags object lists the tags that are used by the specification. Note we defined order in the Api annotation on the OrderResource class. The Tag object of the specification is fully detailed here: http://swagger.io/specification/#tagObject.

"paths" : {
  "/order/submitOrder" : {
    "post" : {
      "tags" : [ "order" ],
      "summary" : "Submit an order",
      "description" : "Submits a new order",
      "operationId" : "submitOrder",
      "consumes" : [ "application/json", "application/x-www-form-urlencoded" ],
      "produces" : [ "application/json" ],
      "parameters" : [ {
        "in" : "body",
        "name" : "body",
        "description" : "Order form with order details",
        "required" : false,
        "schema" : {
          "$ref" : "#/definitions/OrderForm"
        }
      } ],
      "responses" : {
        "200" : {
          "description" : "successful operation",
          "schema" : {
            "$ref" : "#/definitions/Order"
          }
        },
        "400" : {
          "description" : "Invalid order - no order items"
        },
        "500" : {
          "description" : "An internal error occurred"
        },
        "404" : {
          "description" : "Order not found for ID"
        }
      }
    }
  },
  "/order/{orderId}" : {
    "get" : {
      "tags" : [ "order" ],
      "summary" : "Find order by ID",
      "description" : "Returns one order by ID",
      "operationId" : "getOrder",
      "produces" : [ "application/json" ],
      "parameters" : [ {
        "name" : "orderId",
        "in" : "path",
        "description" : "Order ID to find by",
        "required" : true,
        "type" : "integer",
        "format" : "int32"
      } ],
      "responses" : {
        "200" : {
          "description" : "successful operation",
          "schema" : {
            "$ref" : "#/definitions/Order"
          }
        },
        "500" : {
          "description" : "An internal error occurred"
        },
        "404" : {
          "description" : "Order not found for ID"
        }
      }
    }
  }
},

The paths object defines the paths for the endpoints available in the API.

  • There are two paths that we have defined: /order/submitOrder and /order/{orderId}.
  • The path object for the specification is detailed here: http://swagger.io/specification/#pathsObject. Under the path is a path item object, which corresponds to the http operation type.We have a get operation and a post operation.
  • Under the path object, we see many of the values we set in the annotations, including the tag, description, summary, parameters and responses.
  • Note that Swagger generated a lot of the path details for me. For example, lines 8 and 9 define what the API produces and consumes. Swagger also defaulted the 200 successful response that could be returned from the API methods.

Definition

"definitions" : {
  "Order" : {
    "type" : "object",
    "properties" : {
      "orderId" : {
        "type" : "integer",
        "format" : "int32"
      },
      "orderCustomerId" : {
        "type" : "integer",
        "format" : "int32"
      },
      "orderNumber" : {
        "type" : "string"
      },
      "orderItems" : {
        "type" : "array",
        "items" : {
          "$ref" : "#/definitions/OrderItem"
        }
      },
      "timeOrderPlaced" : {
        "type" : "string",
        "format" : "date-time"
      }
    }
  },
  "OrderForm" : {
    "type" : "object",
    "properties" : {
      "customerId" : {
        "type" : "integer",
        "format" : "int32"
      },
      "orderItems" : {
        "type" : "array",
        "items" : {
          "$ref" : "#/definitions/OrderItem"
        }
      }
    }
  },
  "OrderItem" : {
    "type" : "object",
    "properties" : {
      "orderItemId" : {
        "type" : "integer",
        "format" : "int32"
      },
      "orderedProductId" : {
        "type" : "integer",
        "format" : "int32"
      },
      "itemPrice" : {
        "type" : "number",
        "format" : "double"
      },
      "inStock" : {
        "type" : "boolean",
        "default" : false
      }
    }
  }
}

The last section of the specification are the type definitions. You can find the full details of the definition specification object type here:http://swagger.io/specification/#definitionsObject. Note again that Swagger was able to determine the object and object property types for you.

Now that I have a complete specification object, I want to do something with it. I want to view it in a browser and be able to actually execute the APIs. This is where the Swagger UI tool is useful.

Swagger UI

With a full Swagger specification defined for my API, I was ready to use Swagger UI. There are several options for leveraging this tool, but I chose to include it directly into my example project. To do this, you simply need to clone the project from the following GItHub Repository: https://github.com/swagger-api/swagger-ui, and then add the contents of the dist folder to the project's web content folder. Once this is complete, you should be able to navigate to the Swagger UI using the URL: http://localhost:8080/swagger-jaxrs-example/swaggerui/index.htm. Below is the initial page that should load with the Swagger Petstore example loaded.

swagger-ui-initial-page.png

In the top bar of the page, you will see a text box that allows you to enter a specification URL. I'm going to enter the URL for the Swagger specification that we created earlier:http://localhost:8080/swagger-jaxrs-example/services/swagger.json.

swagger-ui-jaxrs-example.png

Once I click explore, the main page for the Swagger specification is displayed. At the top, we see the meta-information about the API, including the title of the project, description of the project and contact details. The two paths are listed for the order tag. Finally, the meta-data about the API is shown, including the base URL and the API version number. If I expand the Get order/{orderId} path, I see the following:

 

swagger-ui-jaxrs-get.png

I'll detail each part of this definition:

  • At the top are the implementation notes. This maps to the note value we set on the ApiOperation annotation.
  • Next, the response class is listed. This displays the full object type that is returned by the method. The response content type is also listed and defaulted to application/json.
  • Next, the parameter for this call is listed. The parameter has a text box that allows you to enter an order ID and test out the actual service. The description, parameter type and data type are also listed. The description came from the ApiParam annotation that we added.
  • Finally, the response messages are listed. These response messages were defined by the ApiResponses annotation on the service method.

 

If I enter a value for the orderId parameter and click the button Try it out!, I can actually hit the web service.

swagger-ui-jaxrs-get-response.png

The page has been updated to show four new sections:

  • The request URL for the service call.
  • The response body with the full response details of the order.
  • The response code, which returned a status of 200.
  • The response headers.

 

This is the final display of Swagger's power that I am going to cover, and is the feature that I see the most benefit in. Swagger UI allows me to see a visually appeasing representation of my API. This makes it much easier to explain to and distribute to API consumers. They know exactly what my API capabilities are, including what types of error codes that can be returned. I can also execute direct tests against the API, allowing either me as the API developer or the consumer to verify my calls quickly and accurately without having to go through a web UI and/or web form. Finally, I can easily regenerate this API view if and when the Swagger specification for the API changes.

Conclusion

In this blog post, I've covered a full example of the power that Swagger can provide to you for cataloging your APIs. I showed you how quickly you can introduce the Swagger dependency to your JAX-RS web application. I demonstrated how easy it is to build the base JSON Swagger specification using the Swagger library. I explained how you can consistently annotate your API classes for Swagger to generate a specification from, including Swagger's ability to determine many of the details of your API for you. Finally, I covered how you can use the Swagger UI tool to consume the Swagger specification and test execution of your services, again with minimal effort. Thank you for reading this post and I look forward to any feedback or questions you may have.

 

Some final notes:

Topics: Software Development, Microservice, swagger api

Written by Michael Hoffman

Michael is a Technical Architect at NVISIA and a Pluralsight author. He is an experienced consultant and entrepreneur who is dedicated to the success and quality of the solutions he provides. As a team player he believes in cultivating strong bonds across all members of his teams with a goal of learning and working with a shared purpose.

In the technical arena, Michael specializes in software architecture with a foundation on flexible, component-based views, and in back-end architecture, with a focus on service-based APIs. While he has no allegiance to any specific technologies, his most recent focus has been on Java solutions leveraging the Spring Framework. Having implemented features on IBM platforms, including WebSphere Commerce and WebSphere Portal, Michael continues to add to his list of frameworks he regularly uses include AngularJS, jQuery, Spring Framework, Apache Camel and Java.

Leave a Comment