Swagger

Limberest comes with the ability to auto-generate API documentation based on JAX-RS and Swagger annotations. Here’s an example from the limberest-demo MovieService put() method that shows what Swagger annotations look like:

    @ApiOperation(value="Update a movie.", response=StatusResponse.class)
    @ApiImplicitParams({
        @ApiImplicitParam(name="{id}", paramType="path", dataType="string", required=true),
        @ApiImplicitParam(name="Movie", paramType="body", dataType="io.limberest.demo.model.Movie", required=true)})
    public Response<JSONObject> put(Request<JSONObject> request) throws ServiceException {

And here are a few snippets from the Swagger JSON output this yields:

{
  "swagger" : "2.0",
  "info" : {
    "version" : "1.0",
    "title" : "Movies API",
    "license" : {
      "name" : "Apache 2.0"
    }
  },
  "host" : "limberest.io",
  ...
  "paths" : {
  ...
    "/movies/{id}" : {
  ...
      "put" : {
        "tags" : [
          "limberest demo movie"
        ],
        "summary" : "Update a movie.",
        "parameters" : [
          {
            "name" : "{id}",
            "in" : "path",
            "required" : true,
            "type" : "string"
          },
          {
            "in" : "body",
            "name" : "Movie",
            "required" : true,
            "schema" : {
              "$ref" : "#/definitions/Movie"
            }
          }
        ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "schema" : {
              "$ref" : "#/definitions/StatusResponse"
            }
          }
        }
      }
    }
  }
  ...
}

Note how the @ApiImplicitParam annotations are reflected in the generated API docs. The #/definitions/Movie reference syntax points to a JSON Schema representation of our model object:

{
  ...
  "definitions" : {
  ...
    "Movie": {
      "type": "object",
      "required": [
        "title",
        "year"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "category": {
          "type": "string"
        },
        "year": {
          "type": "integer",
          "format": "int32",
          "minimum": 1900
        },
        "credits": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Credit"
          }
        },
        "poster": {
          "type": "string"
        },
        "rating": {
          "type": "number",
          "format": "float",
          "description": "Must be a multiple of 0.5",
          "minimum": 0,
          "maximum": 5
        },
        "description": {
          "type": "string",
          "minLength": 0,
          "maxLength": 2048
        },
        "webRef": {
          "$ref": "#/definitions/WebRef"
        },
        "owned": {
          "type": "boolean"
        }
      }
    }
  }
}

Swagger reflects on model objects like Movie to identify their properties. You can control how this translates using Swagger annotations like @ApiModel, but if the default output is okay, then model annotations are not required. For the year property, we use the @ApiModelProperty annotation to identify this field as required and to constrain its value:

    @ApiModelProperty(required=true, allowableValues="range[1900, infinity]")    
    private int year;
    public int getYear() { return year; }
    public void setYear(int year) { this.year = year; }

…and this is reflected in the generated api-docs output:

{
  ...
      "required": [
        "title",
        "year"
      ],
      "properties": {
        ...
        "year": {
          "type": "integer",
          "format": "int32",
          "minimum": 1900
        }
        ...
      }
  ...
}

The value of API constraints like this is further illustrated in the Validation topic.

The Limberest engine serves up either JSON or YAML formatted API docs at a path like:

Using API annotations to describe your services means that the docs are always up-to-date because they’re maintained with your code. Not only that, the same annotations that produce the API docs can also be used to automatically validate requests. This bottom-up or prove-first approach is the best way to ensure that your docs stay in sync with your code.

Note: The default root path for limberest Swagger output is /api-docs/. See the Configuration topic for details on how to override this default.

Next Topic: Validation