In this walkthrough, the instructor will guide through adding API documentation using SwaggerUI.
REST allows us to programmatically utilize (Create, Read, Update, Delete) resources in a datastore. Anyone can make HTTP requests to our RESTful API to interact with our datastore, however how do we let them know which endpoints to access, and which HTTP verbs to use, and when to include query parameters, path variables, or JSON?
Swagger to the rescue!
Swagger is a documentation creation tool. Swagger is going to assist us in creating the documentation for our RESTful API. It will give users a webpage that contains all of the endpoints, which HTTP verbs they accept, if they take any additional information, and finally what happens when that HTTP request is made.
The same Launchcart project and repo you used for the REST studio.
Create and checkout a branch named my-rest-swagger-starter
with this command git checkout -b my-rest-swagger-solution
swagger.yaml
swagger/index.html
to point to our swagger.yaml
fileClone the SwaggerUI repository from Github. Alternatively, download the code as a zip file and unzip it.
Note
We are downloading the SwaggerUI 2.x branch.
To add the SwaggerUI files to your project:
launchcart/src/main/resources/static/swagger
swagger-ui/dist
directory into launchcart/src/main/resources/static/swagger/
directory. The dist/
directory contains all of the HTML, CSS, and JavaScript required to generate a Swagger document.yaml
File¶In the folder launchcart/src/main/resources/static/swagger
, create a swagger.yaml
file. You can do this via IntelliJ, or by running touch swagger.yaml
from the directory.
Open swagger/index.html
and locate the script block, the top of which should look like this:
<script type="text/javascript">
$(function () {
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = "http://petstore.swagger.io/v2/swagger.json";
}
hljs.configure({
highlightSizeThreshold: 5000
});
Edit the var url = ...
line so that it points to our swagger.yaml
file, and delete the conditional immediately following. The top of the script block should look lik this:
<script type="text/javascript">
$(function () {
url = "http://localhost:8080/swagger/swagger.yaml";
hljs.configure({
highlightSizeThreshold: 5000
});
Next we need to begin writing the Swagger YAML file. Copy the following code into your swagger.yaml
.
swagger: '2.0'
info:
description: This is an example RESTful API
version: 1.0.0
title: LaunchCart API
termsOfService: http://swagger.io/terms/
contact:
email: [email protected]
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
tags:
paths:
definitions:
Start up SpringBoot and navigate to the url http://localhost:8080/swagger/index.html. You should see a SwaggerUI page displayed. It will look something like this:
Warning
If your screen reports and error “failed to parse JSON/YAML response”, then check the format of swagger.yaml
to make sure it is correct.
Now we can start adding info about our API endpoints. Let’s start with the /api/carts
path.
Add two entries to the tags
section, one for each collection of resource endpoints that we’ll be working with (carts and items).
tags:
- name: cart
description: Cart provides access to all of the items you are about to buy.
- name: item
description: Items to be added to cart.
Refresh your browser to see the results.
Warning
YAML is white-spaced based. Be very careful with tabs and spaces. You may also find the YAML Reference helpful.
Also, let’s add the GET
endpoint for /api/carts
in the paths
section.
paths:
/api/carts:
get:
tags:
- cart
summary: Returns all carts that exist.
operationId: getAllCarts
produces:
- application/json
responses:
200:
description: successful operation
Now, let’s fill in the schema for the /api/carts
endpoint. In order to do that, let’s get some example output from our API.
Visit http://localhost:8080/api/carts
or load the endpoint in the RESTED plugin. You should receive something that looks like this:
[
{
"uid": 1,
"items": [
{
"uid": 1,
"name": "Chacos",
"price": 100,
"newItem": true,
"description": "I think they're sandals"
}
]
}
]
Using this info, update the /api/carts
definition to this (not the new schema
section):
paths:
/api/carts:
get:
tags:
- cart
summary: Returns all carts that exist..
operationId: getAllCarts
produces:
- application/json
responses:
200:
description: successful operation
schema:
type: object
required:
- uid
- items
properties:
uid:
type: integer
format: int32
example: 34
items:
type: array
items:
$ref: "#/definitions/Item"
Let’s also add a path for our Items resources.
/api/items:
get:
tags:
- item
summary: Returns items
operationId: getItems
produces:
- application/json
responses:
200:
description: successful operation
schema:
type: array
items:
$ref: "#/definitions/Item"
Refresh your browser to see the updated info.
Note
Make sure that your whitespace is correct. There can only be a one tab indent for every map.
We can define types that are returned, to provide examples of sample responses, along with data type info. Add the below yaml
to the defintions
section. Notice that this is referenced in the responses
section of /api/cart
.
definitions:
Item:
type: object
properties:
uid:
type: integer
format: int32
name:
type: string
example: "Chacos"
price:
type: number
format: int64
example: 100
newItem:
type: boolean
example: true
description:
type: string
example: "I think they're a type of sandals"
But wait, /api/items
has two optional query parameters /api/items?price=99&new=true
. Add the following parameters
section within the /api/items
path definition:
parameters:
- in: query
name: price
schema:
type: double
required: false
description: match items by price
- in: query
name: new
schema:
type: boolean
required: false
description: match items by newItem true/false
Again, reload your browser to see the new info displayed in SwaggerUI.
Note
There are two types of parameters: query
and path
. See the Swagger documentation for more info about documenting parameters.
Let’s look at an example that uses path parameters.
/api/items/{id}:
get:
tags:
- item
summary: Returns an individual
operationId: getItem
produces:
- application/json
responses:
200:
description: successful operation
schema:
$ref: "#/definitions/Item"
parameters:
- in: path
name: id
schema:
type: integer
required: true
description: The ID of an item in the system
You can keep going like this to fully document your API. Now that we know how Swagger works, however, we can use a simpler method to automatically create API documentation using Swagger.