[小ネタ] Swagger UIでブラウザだけでAPI定義を参照する

API定義をJSとしてロードすることでローカルのSwagger定義ファイルをHTTPサーバなし、ブラウザだけで表示します
2019.05.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Swgger UI を使うとJSONやYAMLで記述したAPI定義をブラウザで表示できます。 通常はインターネット上のHTTPサーバから配信したり、ローカルでHTTPサーバを起動して閲覧することが多いと思います。

でも色々な事情でローカルでHTTPサーバを起動できない時もあります。 そんな時にブラウザだけでAPI定義を表示する方法を試してみました。

配布用のSwagger UIファイル

Swagger UIに必要なものはリポジトリのdist ディレクトリから入手できます。 git cloneするなり、releasesからダウンロードして入手しましょう。

urlプロパティを書き換えてみる

さて、ダウンロードしたファイルの中からindex.htmlをブラウザで表示するとAPI定義が表示されます。

このファイルをエディターで表示してみるとurlプロパティでJSONファイルを指定しているのがわかります。

 <script>
    window.onload = function() {
      // Begin Swagger UI call region
      const ui = SwaggerUIBundle({
        url: "https://petstore.swagger.io/v2/swagger.json", //ここでAPI定義を指定している
        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
    }
  </script>

じゃあ、これを書き換えればいいんでしょってことで、index.htmlのこの辺りを修正してみますが・・・

    <script>
    window.onload = function() {
      // Begin Swagger UI call region
      const ui = SwaggerUIBundle({
        url: "./swagger.json", //ローカルのJSONファイルを指定してみる
        dom_id: '#swagger-ui',
        deepLinking: true,
        presets: [
          SwaggerUIBundle.presets.apis,
          SwaggerUIStandalonePreset
        ],
        plugins: [
          SwaggerUIBundle.plugins.DownloadUrl
        ],
        layout: "StandaloneLayout"
      })

ローカルファイルへのアクセスが許可されずこのようなエラーとなります。

ファイルを少し書き換えてローカルファイルを表示する

そこで次のように工夫してみます。

それぞれ詳しく説明します

API定義をspecプロパティで指定する

まずindex.htmlを下記のように書き換えます。

  <script>
    window.onload = function() {
      // Begin Swagger UI call region
      const ui = SwaggerUIBundle({
        spec: spec, // <---- urlではなくspecで指定する
        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
    }
  </script>

APIが定義されているJSONファイルをJSファイルに変更する

API定義ファイルの先頭を次のように変数宣言に書き換えます。 拡張子もJSに変えておきます。

元ファイル(swagger.json)

{"swagger":"2.0", ....

書き換え後(swagger.js)

const spec={"swagger":"2.0", ....}

そして再度index.htmlを書き換え、JSファイルをロードするようにします。

 <body>
    <div id="swagger-ui"></div>
     <script src="./swagger.js"></script>   <!--  API定義をJSファイルとしてロードする -->
    <script src="./swagger-ui-bundle.js"> </script>
    <script src="./swagger-ui-standalone-preset.js"> </script>
    <script>

上記の変更をした上でindex.htmlを再度ブラウザで表示すると、下記のようにAPI定義が表示されました。

まとめ

API定義をJSとしてロードすることでローカルのAPI定義ファイルをブラウザだけで表示できました。