Generating a Swagger Spec


This guide focuses on creating a Swagger Spec by use of swagger-core which is one of the popular Java libraries for consuming and generating swagger specifications. However the typical means for generating the spec is by use of annotations. But the focus here is to create a spec directly by using the Java API provided by the library itself.

For a maven based project you’d add this in your pom.xml.

<dependency>
   <groupId>io.swagger</groupId>
   <artifactId>swagger-core</artifactId>
   <version>1.5.13</version>
</dependency>

swagger-core got set of model classes for representing different parts of the swagger spec. The class io.swagger.models.Swagger is the base class, that holds references to all other sub models.

public class Swagger {
    protected String swagger = "2.0";
    protected Info info;
    protected String host;
    protected String basePath;
    ...
    protected Map<String, Path> paths;
    protected Map<String, SecuritySchemeDefinition> securityDefinitions;
    protected Map<String, Model> definitions;

Once object of this class is being constructed and its members are initialized, one could simply serialize it to retrieve a JSON string which will be compliant with Open API Specification.

Json.pretty(swagger);

The method static Json.pretty(Object) is from the package io.swagger.util. You may use whatever object serializer you prefer.

The basic structure of a generated Swagger in YAML format is as follows:

swagger: "2.0"
info:
  title: OpenMRS API Docs
  description: API description
  version: 2.0.0

host: openmrs.org
paths:
  /drug:
    get:
      summary: 
definitions:

Declaring and Initializing Swagger

final io.swagger.models.Info info = new io.swagger.models.Info()
	.title("OpenMRS API Docs")
	.description("OpenMRS RESTful API specification")
	.contact(new io.swagger.models.Contact().url("http://openmrs.org"))
	.license(new io.swagger.models.License().name("MPL-2.0 w/ HD");
		

final io.swagger.models.Swagger swagger = new io.swagger.models.Swagger()
	.info(info)
	.host(baseUrl)
	.scheme(Scheme.HTTP)
	.securityDefinition("basic_auth", new BasicAuthDefinition())
	.security(new SecurityRequirement().requirement("basic_auth"))
	.consumes("application/json")
        .produces("application/json");

Adding paths
In a Swagger spec, information that relates to API endpoints goes under the global paths section as shown below.

paths:
  /drug:
    get:
    post:
    ...
  /drug/{id}:
    get:
    post:
    delete:

And a Path could hold different types of operations such as get, post and delete.

This is how you’d construct a Path model object.

io.swagger.models.Path path = new io.swagger.models.Path();

So for us to add operations to the path defined, first we’d need a Operation object.

io.swagger.models.Operation operation = new io.swagger.models.Operation()
	.consumes("application/json")
	.produces("application/json")
	...;

Then we’d add that Operation to our Path object.

Path.set(String method, Operation op)

In case it’s a GET operation, one could use simply either:
path.setGet(operation) or path.set("get", operation) or just path.get(operation)

Call appropriate getters and setters on those bean object models to append with further information as necessary and repeat. Once done you’ll add this Path to your base Swagger model. So for example:

swagger.path("drug", path)
swagger.path("drug/{uuid}", path)

Operations may return responses:

paths:
  /drug:
    get:
      responses:
        200:
          description: OK
          schema:
            $ref: '#/definitions/DrugGet'

Response’s include a property called schema, to define the schema of the object returned. Those definitions are defined under the global section definitions:

definitions:
  DrugGet:
    properties:
      name:
        type: string
      minimumDailyDose:
        type: number
        format: double
      combination:
        type: boolean
        default: false

Let’s write code for the above representation.

Model drugGet = new ModelImpl()
	.property("name", new StringProperty())
	.property("minimumDailyDose", new DoubleProperty())
	.property("combination", new BooleanProperty()._default(false));

swagger.addDefinition("DrugGet", drugGet)

Other property types include:
IntegerProperty, LongProperty, DateProperty, DateTimeProperty, MapProperty, ArrayProperty, RefProperty..

Examples:

  • RefProperty
  • modelImpl.property("category", new RefProperty("#/definitions/Category"));

  • ArrayProperty
  • modelImpl.property("categories", new ArrayProperty(new RefProperty("#/definitions/Category")));

    This will produce an output in the form:

    definitions:
      DrugGet:
        properties:
          categories:
            type: array
            items:
              $ref: #/definitions/Category
    

Leave a comment

Your email address will not be published. Required fields are marked *