This blog post can be divided into two parts: in the first part I will write a Spring Boot RESTful API and in the second part I'll show how to use JSONDoc to document the created API. Doing the two parts should take a maximum of 15 minutes since creating an API with Spring Boot is very easy and fast, and the same goes with documenting it with the JSONDoc Spring Boot starter and UI webjar. I'll skip tests creation for this example, since the main goal how to document the API rather than writing and testing it.
Write the API
Let's begin with creating the Maven project based on the quickstart archetype
and declaring the needed dependencies for the API:
spring-boot-starter-web
spring-boot-starter-data-jpa
h2
I also added Lombok to let me keep my code cleaner. The resulting pom looks like this:
This application will be a collection of services to manage a simple shelf. There will be two entities:
Book
Author
Create Entities and Controllers
To do this I will create the usual components to manage the persistence and controller layers:
a new package named model that will contain Book and Author
a new package named repository that will contain BookRepository and AuthorRepository
a new package named controller that will contain BookController and AuthorController
For this example I will skip the service layer. I will also create a DatabasePopulator class, implementing CommandLineRunner so that at startup there will be some data in the in memory database. Let's see the entities, repositories and controllers code:
Entities
Repositories
Controllers
Database populator
It's now time to write the main class to run the application. I'll call it Shelf and also in this case, thanks to Spring Boot, it's very simple:
By running this class we can actually verify that the application is responding as expected to requests. You can easily test that the API work by using curl:
Document the API with JSONDoc
Here is the interesting and new part, i.e. using the JSONDoc library to annotate your code and automatically produce its documentation. To do that you have to declare the JSONDoc dependencies and insert a little code in your classes. Let's see how to do that:
Declare JSONDoc dependencies
Just add two more dependencies to the pom file:
Enable JSONDoc in main class
With the JSONDoc starter you can enable documentation generation just by adding @EnableJSONDoc to the Shelf class, which will be like:
Configure JSONDoc
Next thing to do is configure JSONDoc to scan your controllers, objects and flow classes. To do that just add some entries to the application.properties file (create it under src/main/resources if you don't have it)
Document controllers
JSONDoc can grab several information from the Spring annotations to build the documentation. Anyway it is an opt-in process, meaning that JSONDoc will scan classes and methods only if annotated with its own annotations. For example, to properly document the BookController, here is how the JSONDoc annotations should be used:
The same goes for AuthorController.
Document objects
Next thing to do is to put some JSONDoc annotations also on objects that need to be documented, in this case Book and Author. Here is the resulting Book class:
And also in this case, the same goes for Author.
Checkpoint: start up the application
Before going ahead with documenting flows, let's startup the application and see what happens:
If you go to http://localhost:8080/jsondoc you will see a json, that is generated by JSONDoc and represents the documentation based on the annotation put on controllers methods and model objects
If you go to http://localhost:8080/jsondoc-ui.html you will see the JSONDoc UI. Just copy and paste http://localhost:8080/jsondoc in the input field and get the documentation in the clear user interface
This is a good moment to take some time to explore the interface and play with the API in the playground.
Document flows
By flow I mean a subsequential execution of a number of API methods aimed to achieve a goal, that could be purchase a book, or browse the catalog and get the book details. There are cases in which the flows could involve several methods, and API users could need to know which is the correct sequence of methods to call to achieve an objective. In this example I can't think of meaningful flows, but let's assume that I want to document the sequence of methods to browse the shelf and get an author's detail passing through a book I choose, so the resulting flow for this use case would be something like:
Get the list of books
Choose a book and get its details
Get the author of this book
To document this flow you just need to follow these steps:
Create a class that will contain the flows of your application. This class is needed only for documentation purposes, it will not be actually used in your app. Annotate this class with the @ApiFlowSet annotation, which makes JSONDoc understand that this class should be taken into account when building the documentation.
In this class create fake methods, annotated with @ApiFlow. The body of the method, as well as its return type and argument can be void, since the method signature server only as a hook for the @ApiFlow annotation
Decide an ID that identifies each API method within the JSONDoc produced documentation, for example the findAll method of the BookController can have an ID like BOOK_FIND_ALL
Put this ID inside the id property of the @ApiMethod annotation and inside the apimethodid property of the @ApiFlowStep annotation
If you put the flow class in a separate package, remember to update the application.properties file with that value
Let's see how I did it. Here is the class holding the flows of the application:
Here is the class containing the methods IDs to be referenced in the annotations:
Here is the resulting BookController, after having specified the id property:
And finally the application.properties file, with the new package:
It's time to startup the application again, go to http://localhost:8080/jsondoc-ui.html, insert http://localhost:8080/jsondoc in the input box and get the documentation. Enjoy!