Documenting the Drupal JSON API with Swagger, as explained by our expert Drupal developer, Phil...
I have noticed a recent change when asking for API documentation. It used to be the case that an API either had no documentation at all or had a massive tome that took weeks to write, was out of date before the ink was dry and never really read. In the last couple of years, however, the question has often resulted in the answer "oh, we use Swagger for documentation, I'll send you a link".
I decided to look into Swagger, see what it does, and how it can be used to document the Drupal JSON:API.
What is Swagger?
Swagger is an API documenting tool that allows developers to quickly and easily generate the needed documentation for an API. This involves a specification language (called OpenAPI) and an interface that can be used to document and test the API endpoints (called Swagger UI).
The power of Swagger is that it doesn't require fundamental changes to your API, it only requires that the API returns a specification detailing all the things the API can do. This specification is the OpenAPI part of Swagger and includes things like what methods are available, what parameters those methods require, and details of any authentication that is required to use the API.
Swagger itself consumes this specification (which can be a static file) and presents it as an interactive interface.
This means that when someone says they have Swagger documentation, they mean their API has an OpenAPI compliant interface that is being consumed by Swagger. You can see an example of Swagger in action via their website.
Installing Swagger in Drupal
Getting Swagger UI installed into Drupal's JSON:API takes a few modules, so let's go through each of the modules you'll need.
JSON:API
Maybe an obvious one, but in order to document the core JSON:API in Drupal we first need to install it. This will create a large number of endpoints that allow you to interact with most parts of Drupal and will be the basis of the documentation we create.
OpenAPI
The OpenAPI module allows you to make your RESTful and JSON:API services discoverable using the OpenAPI standard. This can then be used by Swagger to generate the interactive documentation.
Out of the box, this module does nothing on a default install of Drupal. There are a couple of other modules we need to install to get the things we need.
OpenAPI for JSON:API
This module will integrate the JSON:API module with the OpenAPI module so that we can expose the JSON:API as an interface that Swagger can use.
Once the module is installed along with the core JSON:API module it allows access to a page under the path /openapi/jsonapi?_format=json. On a default Drupal site this will show a large file containing all of the points of interaction that exist in the API. This is the file that gets used by Swagger to generate the interface.
As this file shows all of the interactions available on your site it will be of great interest to any attackers out there. This file falls under the same security policy as the JSON:API and as such will be inaccessible to anonymous users by default.
OpenAPI UI
The OpenAPI UI is a generic module that provides a way of interfacing between the OpenAPI interface and any third-party libraries we want to use. Using this module allows the Swagger UI to be viewed within the Drupal site itself and not as a separate interface. This has the added benefit of requiring a Drupal login in order to view the API documentation unless you relax the permissions on the interface.
Swagger UI For OpenAPI UI
Finally, we are now able to install the Swagger UI module. This ties everything together and allows us to view the Swagger interface within our Drupal site. This module has no configuration of it's own as it simply provides the bridge between OpenAPI and Swagger. It does, however, have a composer file that includes the Swagger tool itself and so installing the module by composer is a requirement.
Composer require commands
For ease of integration, I have collected together all of the composer commands you'll need into a single command here.
composer require drupal/openapi drupal/openapi_jsonapi drupal/openapi_ui drupal/openapi_ui_swagger
Once that's done you can install the modules using either Drush or within the Drupal site. Make sure you enable the JSON:API module as well as all of the OpenAPI and Swagger modules.
Including the Swagger UI library
Even with all of these modules installed we still aren't in a position to run Swagger, we first need to tell composer what to do with the Swagger library so that Drupal can use it.
Depending on your Drupal setup you may not have the needed composer libraries in place. To make sure you do you can install the composer/installers and mnsami/composer-custom-directory-installer libraries by requiring them into your project. These packages will move dependencies into the correct parts of Drupal so they can be picked up and used.
composer require composer/installers mnsami/composer-custom-directory-installer
Next, we need to edit the composer.json file to add in a couple of lines of configuration.
"web/libraries/{$name}": [ "type:drupal-library", "swagger-api/swagger-ui" ]
This integrates with settings you should already have in your composer.json file. Just lookout for the installer-paths section in that file and add an additional line to the libraries configuration. The Swagger UI for OpenAPI module includes the swagger-api/swagger-ui library so we don't need to manually include that.
Remember to run 'composer install' once you have added this to update the Drupal site with Swagger.
Adding a small patch
Unfortunately, I had a little bit of trouble getting things working straight away. Even after including all of the needed modules and libraries I couldn't get the Swagger documentation to run correctly. As it turns out there is a small error in the OpenAPI for JSON:API module that requires a little patch at the time of writing. This hasn't made its way into the module as it is causing tests within the module to fail, but it sorted out my immediate issue and allowed the page to work correctly for me.
Add the following to your composer file.
"patches": { "drupal/openapi_jsonapi" : { "3185778: TypeError: Cannot read property 'anyOf' of undefined" : "https://www.drupal.org/files/issues/2020-12-21/add_required_keyword_8.x_2.x-3185778-5.patch" } }
With that patch in place, you can run composer install to update your codebase.
Swagger documented Drupal JSON:API in action
As you can see, it takes a little bit of effort to get everything running correctly, so let's start using Swagger.
Once everything is installed (and patched) you can start to view your JSON:API as a documented Swagger UI interface. If you now visit the path /admin/config/services/openapi you will see the following.
The only item in the list is the JSON:API module interface since that is the only API module we have installed and integrated with OpenAPI. The "View/Download" button here will open the raw OpenAPI definition file (basically a big JSON file). This is the file that OpenAPI for JSON:API module creates and is consumed by Swagger to generate the documentation page.
Visiting the "Explore with Swagger UI" button is where the magic happens and is what I have been building up to for the entire article. This will show the following screen. There is a lot of items on this page as the JSON:API is quite comprehensive so the image below only shows the top of the page containing the heading and the start of the block configuration section.
Clicking on any of the endpoints in the Swagger page will drill down into the detail of that request. For example, clicking on the /block/block JSON:API endpoint will show this in more detail.
This interface is a great way to explore the JSON:API and viewing this page you can probably see the extent of the API available in Drupal. There are lots of different endpoints that allow interaction with blocks, fields, comments, users, pages, media, taxonomy terms, and even parts of the JSON:API itself.
One of the best parts about Swagger is the "Try it out" button on the right-hand side. This will add an "Add item" to each of the parameters and an "Execute" button to the end of the parameters list. Clicking on the execute button will issue a real request to your site and show you the output along with header information. You can add parameters to the request by using the "Add item" buttons.
It's also nice to see the curl command along with the rest of the information.
This is brilliant! It's well worth persevering with the setup of these modules to get this page up and running.
Documenting the Drupal JSON API with Swagger - Conclusion
Whilst some of these modules are still in the pre-release stage, they pretty feature-complete and mostly stable. I did have to install a single patch to get the Swagger page working fully, but after that, the modules worked very well. Seeing the full endpoints of the JSON:API in one place makes finding the right command and using it an easy task. The fact that you can also try the API endpoints out within the tool makes everything worth it. Whilst tools like Postman and Insomnia allow you to test APIs, having this functionality baked into the site is amazing.
Installing Swagger in your Drupal site will give you a lot of information on how to use and interact with the JSON:API. This is useful even if you have used the API and are looking for a handy reference guide.
Whilst this documentation tool is powerful, I wouldn't recommend jumping in and installing Swagger on a production site unless that's what you really want. The JSON:API module will work perfectly fine without Swagger so it might be worth adding the OpenAPI and Swagger modules to your configuration splits so they are only active on your dev and staging sites.
If you are new to the JSON:API I would also highly recommend you install the JSON:API extras module. Out of the box the JSON:API module exposes a lot of the inner workings of Drupal, which you might not want to expose. Using the JSON:API extras module you can restrict the footprint of the API and only expose the parts you need to use. For example, the API allows access to your content filter formats, so it is possible a user could alter a filter format to allow malicious code to be injected into the content. A user could then simply add some content and create a problem for your users.
It should be noted that the OpenAPI standard is just that, a standard. As such, there are different products that integrate with this standard to create API documentation. One of these tools is ReDoc, which creates a documentation page with the same kind of interactivity that exists in the Swagger tool. If you want to give ReDoc a try then you'll be interested to learn there is a ReDoc for OpenAPI UI Drupal module that will integrate ReDoc into Drupal in the same way as I have described above.