Product Engineering

Swagger Specification and Code Generation one-o-one

Swagger Specification and Code Generation one-o-one

In last blog (Introduction to Swagger – Specification for Describing RESTful APIs), we got to know the history behind creation of the OpenAPI specification.

In this article, we will do following:

  • Explore Swagger’s enormous power to speed up your web application development using its code generator (https://github.com/swagger-api/swagger-codegen).
  • Generate Code for a REST application using our own OpenAPI Specification file and swagger-codegen.

There are two ways for developing using Swagger:

  1. API-first approach (Top down approach):

For this, you need to design your REST APIs first, and design model objects that you are going to use for those REST APIs. Then you write down these specifications in form of OpenAPI, and Swagger will create client as well as server for you!

  1. Service first approach (Bottom up approach):

Like the name suggest, you write down your services (and Rest controllers) first. Then you use swagger-core to automatically generate the Swagger definitions. And then you can use swagger-codegen and swagger-ui to generate client APIs and documentations.

In this article we only will talk about Top Down approach or API-first approach of development using Swagger. (We will be exploring other approach in next part of this series).

For auto generation of code using Swagger, steps involved are:

  1. Write Swagger Specification.
  2. Use swagger-codegen to generate client or server code.

Let’s have insight into both of these steps.

Swagger Specification

As we have discussed in our last blog, Swagger uses OpenAPI specification that can be written in form of YAML or JSON.

To understand this specification better, let’s take a very simple example of Doctor Appointment Management application. We will be building a simple application with just two objects: Doctor, and Slot. And we will be generating client and server code with REST specifications as well as CRUD operations for Doctor and Slot objects, just by writing one single YAML file specification.

To start writing a Swagger YAML file, you need to add info object at the start of YAML file.

swagger: "2.0"

info:

  description: "Appointment Management"

  version: "1.0.0"

  title: "Doctor's Appointment"

host: "localhost:8080"

basePath: "/appointmentMgmt"

schemes:

- "http"

Let’s understand important properties of this YAML:

Property Significance Is Required?
swagger Version of Swagger you want to use Yes
host The host (name or IP) serving the API. Optionally, you can add port as well.

 

No. If not provided, it uses the host and port serving the documentation.
basePath This is the context path for the hosted application No. If not included, the API is served directly under the host
schemes The transfer protocol of the API.

Allowed Values are one of these: http, https, ws, wss

No

 

Based on our host, schemes and basePath properties provided in above YAML, Swagger will generate REST API definitions in this format:

http://localhost:8080/appointmentMgmt/

Ok, now let’s expand this YAML by writing our very first REST API definition. We will start with GET operation, as it is very straight forward.

paths:

  /doctors/{doctorId}:

    get:

      tags:

      - "Doctor"

      description: Get Doctos based on Id specified

      summary: Find Doctos by Id

      operationId: getDoctorsById

      produces:

      - "application/json"

      responses:

        200:

          description: Doctor response

          schema:

            type: array

            items:

              $ref: '#/definitions/Doctor'

        400:

          description: "Invalid Id supplied"

        404:

          description: "Doctor not found"

        405:

          description: "Validation exception"

      parameters:

      - name: doctorId

        in: path

        description: Id of Doctor to find

        required: true

        type: array

        items:

          type: string

definitions:        

  Doctor:

    type: "object"

    properties:

      doctorId:

        type: "integer"

        format: "int64"

      doctorName:

        type: "string"

      visitingCharge:

        type: "integer"

        format: "int64"

      availability:

        type: "integer"

        format: "int64"

      speciality:

        type: "string"

Let’s understand important parts of this specification.

paths: We have started writing YAML with paths object. It is specification for all paths and operations that you want to build inside your application.

produces: A list of MIME types the operation can produce. The mime type definitions should be in compliance with RFC 6838.

responses: We can specify all required/possible response types, and what should be returned by our REST API for each response type.

Under response we have:

schema: A definition of the response structure. It can be a primitive, an array or an object. If it is an array, than it must be followed by:

items: Describes the type of items in the array.

parameters: Then we have parameters object, which is used to define parameters that can be used across operations.

in: It defines how the parameter is going to be passed. Possible values are “query”,   “header”, “path”, “formData” or “body”.

required: To specify if parameter is mandatory.

definitionsobject to hold data types produced and consumed by operations. So basically, these are our model objects if we talk in terms of Java. In above specification, we have defined one Doctor object, with 5 properties:   doctorId, doctorName, visitingCharge, availability, speciality.

Now that we have learnt basics of YAML, this YAML specification can be extended by writing more REST operations. This is our complete YAML specification file: https://github.com/XoriantOpenSource/swagger-blog-examples/blob/master/swagger-blog-2/appointment.yml

Swagger provides its own editor to edit and compile YAML specification, as well as preview REST APIs that are generated out of your specification, in real time on browser. We will be covering about different options to set up Swagger editor in next section. For now, let’s see how our YAML specification looks on Swagger editor after compilation:

swagger specification and code generation

Notice on right hand side the way it is showing all the REST APIs, which we have specified through our YAML specification. Pretty impressive, right?

Now that we are done with YAML specification, let’s proceed with the second step to auto generate code.

Swagger code generation

There are 3 ways to generate code from YAML specification

  1. Using Swagger Editor:

After that, you can click on “Generate client” and select desired language. Or click on “Generate server” and select desired language. This will download all code required for client or server.

  1. Using command line tool swagger-codegen:

You can download Swagger jar from http://central.maven.org/maven2/io/swagger/swagger-codegen-cli/2.2.2/swagger-codegen-cli-2.2.2.jar

To generate client:

java -jar swagger-codegen-cli-2.2.2.jar generate  -i swagger.yml    -l java   -o SwaggerClient

To generate server:

java -jar swagger-codegen-cli-2.2.2.jar generate -i swagger.yml -l spring –library spring-mvc -o SwaggerServer

Here,       -i:  yaml file with location

                -l: language

                -o: output folder for generated source

(Note: There is also 3rd party component “swagger-js-codegen”, which can generate angularjs or nodejs sourcecode from OpenAPI specification.)

  1. Using Maven plugin 

You can also use swagger-codegen-maven-plugin within your existing maven project.  So that code generation can become part of your build life cycle. So whenever you do mvn clean compile, code will be auto generated for you.

 

Once your server code is generated, you can import it in our favorite IDE, and start up server at location specified in “host” property of YAML. You are all set to develop your REST application and test it using Swagger-UI!

This auto generated client and server code also generates .md files and provides nice documentation to your application’s REST endpoints. For our YAML specification, it has auto generated nice API endpoints summary for all the entities: https://github.com/XoriantOpenSource/swagger-blog-examples/tree/master/swagger-blog-2/java-client#documentation-for-api-endpoints

You can have a look at this entire example project at: https://github.com/XoriantOpenSource/swagger-blog-examples/tree/master/swagger-blog-2

In next blog of this series, we will explore other exciting features of Swagger. Stay tuned!