preloader
心得

Setup and Deploy API Document to Heroku free price plan With Swagger UI Topbar List and Http Basic Auth | 建立與部署簡易帳密認證機制的 Swagger-UI API 文件到 Heroku 免費方案

Setup and Deploy API Document to Heroku free price plan With Swagger UI Topbar List and Http Basic Auth | 建立與部署簡易帳密認證機制的 Swagger-UI API 文件到 Heroku 免費方案

I want to create a static site of backend API document for communication between frontend and backend engineers. Because I don’t want to manage the server and estimate usage of team members is low, I survey two solutions, which are GCP Endpoint and Heroku. I finally choose Heroku free price plan.  

Steps for setup

Step 1

  1. Download standalone version of swagger-ui package on github.com and unzip/decompress source-code file.
  2. Copy dist folder inside decompressed directory to a repo or folder you want to, which is outside from decompressed file. We name this new folder is apidoc-repo here for example.  

Notice 1: If it had been copied to new folder without git init, please type git init under the new one.  

Notice 2: If you don’t login heroku account with commandline/terminal, please login your heroku account via commmandline/terminal following heroku official tutorial. If you don’t have an account of heroku, please get an one and create an app on heroku website first.  

Notice 3: If you just want to try, you can create a branch named nginxBasicAuth in local develop environment. You can name that to what you like.  

Step 2

  1. Please make sure you are under the new folder: apidoc-repo.
  2. Set a buildpacker for this new folder. I use heroku-community-static as the buildpacker for this new folder through command: heroku buildpacker:set heroku-community-static. You can find more information about heroku-community-static on GitHub

 

Step 3

  1. Create a file: static.json under home directory of this new folder: apidoc-repo
  2. Put content to static.json:
{
  "root": ".", // because structure of apidoc-repo is flat and copied directly from dist folder from swagger-ui standalone type.
  "encoding": "utf-8",
  "clean_urls": true,
  "routes": {
    "/*.html": "index.html"
  },
  "https_only": true,
  "basic_auth": true, // enable http basic authentication
  "basic_auth_htpasswd_path": "/app/config/.htpasswd" // this value states path of .htpasswd in heroku execution environment.
}
  1. Create a folder name: config under home directory of apidoc-repo
  2. Create .htpasswd file under config folder using command:
htpasswd -bcB .htpasswd MYUSERNAME MYPASSWORD
  1. If you don’t want it to be indexed by Googlebot, you can create the file: robots.txt under home directory of apidoc-repo with following content:
User-agent: Googlebot
Disallow: /

Notice 1: I have tested htpasswd command on macOS BigSur 11.6.  

Notice 2: Please replace MYUSERNAME and MYPASSWORD to what you want.

   

Steps for deployment

Step 1

Before deployment, you must make sure repo’s remote has contain heroku. You can check whether it exists using command git remote -v.  

Step 2

  • If you use a local branch name: nginxBasicAuth in step1 within section of steps for setup, please use this command:
git push heroku nginxBasicAuth:main

  Notice: You can replace nginxBasicAuth with any name.

Finish for deployment

Congradulation! You can find out what has been deployed.

   

Setup for multiple definitions of API

If I want to multiple API definitions for different products in one site or heroku app, I can modify window.onload content of index.html.  

Original content is

window.onload = function () {
  // Begin Swagger UI call region
  const ui = SwaggerUIBundle({
    url: "https://petstore.swagger.io/v2/swagger.json",
    dom_id: "#swagger-ui",
    deepLinking: true,
    presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
    plugins: [SwaggerUIBundle.plugins.DownloadUrl],
    layout: "StandaloneLayout",
  });
  // End Swagger UI call region

  window.ui = ui;
};

 

Modified content can be

window.onload = function () {
  // Begin Swagger UI call region
  const ui = SwaggerUIBundle({
    /**
     * Remove url and add urls with following format.
     * Value of url attribute inside urls can be full URL address or a path of local file in heroku
     *
     * Notice: Path of a local file can be relative.
     * In this example, you must create apiFiles under home directory of apidoc-repo,
     * and put productBdefinition.json file there.
     */
    urls: [
      { url: "https://petstore.swagger.io/v2/swagger.json", name: "product A" },
      { url: "./apiFiles/productBdefinition.json", name: "product B" },
    ],

    /**
     * Select assigned name after landing this page
     */
    "urls.primaryName": "product B",

    dom_id: "#swagger-ui",
    deepLinking: true,
    presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
    plugins: [SwaggerUIBundle.plugins.DownloadUrl],
    layout: "StandaloneLayout",
  });
  // End Swagger UI call region

  window.ui = ui;
};

Modified results:

topbar select list
Figure 1. list of multiple definitions  

options in topbar list
Figure 2. An option in list of definitions  

Since modifications, backend engineers can focus on creating/editing API definiton files by following conventions and won’t worry about how to maintain visual layout as switching different products. They only need to follow instructions from swagger 2.0 or openapi 3.0 as creating/editing content of definitions. If they want, they even can create server URL of different environments such as dev or production by following server description in swagger 2.0/ openapi 3.0 standards.