DEV Community

Jonas Brømsø
Jonas Brømsø

Posted on

Hosting Swagger-UI using GitHub Pages

At my workplace we are using Swagger-UI to document and manually test our REST APIs.

That means that we have set up some hosts so serve this. I have for some time been pondering whether it would be possible to serve this via GitHub, GitHub Pages in particular - I was thinking about even writing up my own variation, believing this would be the path ahead.

Investigating something different I fell over the following section in the documentation:

Plain old HTML/CSS/JS (Standalone)

The folder /dist includes all the HTML, CSS and JS files needed to > run SwaggerUI on a static website or CMS, without requiring NPM.

  1. Download the latest release.
  2. Copy the contents of the /dist folder to your server.
  3. Open swagger-initializer.js in your text editor and replace "https://petstore.swagger.io/v2/swagger.json" with the URL for your OpenAPI 3.0 spec.

Now I was convinced, it would be doable to get the Swagger stuff served using GitHub Pages.

In order to do the experiment, I set up the following GitHub repository:

I am going to echo the contents of the README from the repository here.

The repository ended up being structured as follows:

  • api-docs/ - directory containing the Swagger-UI
  • swagger.json - the OpenAPI/Swagger definition
  • README.md - this file (documentation describing the experiment)

When the repository was set up the following steps were taken:

First a directory for the Swagger-UI was created:

mkdir api-docs
Enter fullscreen mode Exit fullscreen mode

The Swagger-UI was downloaded and the relevant files where extracted into the api-docs/ directory:

curl -X GET https://github.com/swagger-api/swagger-ui/releases/tag/v5.17.14
Enter fullscreen mode Exit fullscreen mode

Do note the version number was the one available at the time of the experiment, do fetch the newest version available.

The files were unpacked:

tar xvzf swagger-ui-5.17.14.tar.gz
Enter fullscreen mode Exit fullscreen mode

The files was copied to the api-docs/ directory created above:

cd swagger-ui-5.17.14
cd dist # navigate to the dist directory
cp -r . ../../api-docs # copy the files to the api-docs directory recursively
cd ../../ # skip back to the root of the repository
Enter fullscreen mode Exit fullscreen mode

You can call the directory what you want. The name api-docs/ is just a suggestion.

The dist/ directory contains the Swagger-UI files, which can be used to serve the Swagger documentation as a static site.

From the documentation (see: "Plain old HTML/CSS/JS (Standalone)" section):

Open swagger-initializer.js in your text editor and replace "https://petstore.swagger.io/v2/swagger.json" with the URL for your OpenAPI 3.0 spec.

Since I did not have anything sharable at the time of the expirment, only work related definitiosn, I choose to use the Swagger Petstore example:

To demonstrate that it is possible to use a local file, I used the swagger.json file in the repository.

First I dowmloaded the referenced file:

curl -X GET -o swagger.json https://petstore.swagger.io/v2/swagger.json
Enter fullscreen mode Exit fullscreen mode

I edited the swagger-initializer.js file and added the path to the swagger.json file:

url: "../swagger.json",
Enter fullscreen mode Exit fullscreen mode

Since we can serve multiple API definitions, I added multiple URLs to the urls array in the swagger-ui-bundle.js file:

    urls: [
      {
        url: "../swagger.json",
        name: "The local file from the repository"
      },
      {
        url: "https://jonasbn.github.io/gh-pages-swagger-ui-experiment/swagger.json",
        name: "The local Swagger Petstore"
      },
      {
        url: "https://petstore.swagger.io/v2/swagger.json",
        name: "The original Swagger Petstore"
      },
    ],
Enter fullscreen mode Exit fullscreen mode

The file with the definition is also served from GitHub pages as: https://jonasbn.github.io/gh-pages-swagger-ui-experiment/swagger.json, so it is easy to consume for clients etc.

When the changes was committed and pushed and the GitHub Pages was deployed, the Swagger-UI can be accessed using the following URL:

The Swagger-UI was now served as a static site using GitHub Pages.

Do note GitHub Pages should be enabled for the repository.

It worked as expected and fetching the swagger.json file from the repository in addition to the remote file (https://petstore.swagger.io/v2/swagger.json) and the file we service our selves (https://jonasbn.github.io/gh-pages-swagger-ui-experiment/swagger.json).

I tested calling a few API endpoints directly from the page and it works as expected - the setup does make it much easier to have both the specification under version control and to serve it with the Swagger-UI, without having to set up a separate server or a service to serve the Swagger-UI, like: swagger-ui-express - which is a fine piece of software, but it is not necessary as demonstrated.

Extras

Finally I added a GitHub Action to validate the Swagger definition file using the swagger-validator action:

on: push
name: Validate API swagger definition file
jobs:
  validate:

    runs-on: ubuntu-latest

    steps:
    - name: Get OpenAPI/Swagger definition file
      uses: actions/checkout@v4
    - name: Validate OpenAPI/Swagger definition file
      uses: mbowman100/swagger-validator-action@master
      with:
        files: swagger.json
Enter fullscreen mode Exit fullscreen mode

REF: .github/workflows/swagger-validator.yml

Do note that the action is based on [swagger-cli][SWAGGERCLI which is deprecated, so I am looking for an alternative.

At some point I need to work out the process of updating the contents of the api-docs/ directory in the repository from the Swagger-UI dist/ directory, so I can keep the Swagger-UI up-to-date.

For now I have signed for notifications on releases and security announcements with the repository.

Finally, a caveat GitHub pages are public.

If you have a public Swagger definition and want to serve it easily GitHub Pages are an option.

Have fun...

Resources and References

Top comments (0)