Springで実装したREST APIサーバアプリケーションにSpringfox+Swaggerを導入してWebドキュメントを自動生成したのですが、環境によってデプロイ後の画面でErrorバッジが表示されるケースがありました。
そこで今回は、その原因と解決策について書いていきたいと思います。
サンプルコード
https://github.com/dais39/sample-swagger ControllerクラスのサンプルコードとSwagger用のJavaConfigのサンプルコードを以下に示します。
@RestController public class SampleSwaggerController { @GetMapping("/hello") public String getHello() { return "Hello Swagger!"; } @GetMapping("/hi") public String getHi() { return "Hi Swagger!"; } @GetMapping("/bye") public String getBye() { return "Bye Swagger!"; } }
@Configuration @EnableSwagger2 public class SwaggerConfiguration { }
問題
このアプリケーションをlocalhostで起動して http://localhost:8080/swagger-ui.html にアクセスすると、正常なドキュメントが表示されます。
(デフォルト設定なので、関係ないパスが含まれているのはご容赦ください)
次にこのアプリケーションをHerokuにデプロイしてアクセスすると、右下にVALIDとかかれたドキュメントが表示されます。
次に、「localhost」ではなく、IPアドレスを直接指定して、http://192.168.11.6:8080/swagger-ui.html にアクセスすると、右下にErrorとかかれたドキュメントが表示されます。
原因
Swaggerには、生成したSwagger Specificationのvalidationをおこなう機能が自動で有効になっています(ただし、localhostというURLの場合はvalidation機能は無効になります)。
Swagger-APIのGitHubにも以下のように記されています。
You can validate any OpenAPI specification against the OpenAPI 2.0 Schema as follows:
<img src="http://online.swagger.io/validator?url={YOUR_URL}">
Of course the YOUR_URL needs to be addressable by the validator (i.e. won't find anything on localhost). If it validates, you'll get a nice green VALID logo. Failures will give an INVALID logo, and if there are errors parsing the specification or reaching it, an ugly red ERROR logo.
これを読むと、問題のエラー表記は「Swagger Specificationの構文が不正」、もしくは「validationを行う外部ホスト(online.swagger.io)から該当サーバへアクセスできない」ことが原因なようです。
今回のケースでいうと、localhostを指定した場合にはvalidationが無効になります。 また、herokuへデプロイした場合にはonline.swagger.ioからアクセスできるので、ERROR表記はでません。 しかし、localhostのIPアドレスを直接指定してアクセスした場合には、validationが有効になり、さらにonline.swagger.ioからアクセスができないのでERROR表記がでてしまったのだと考えられます。
対策
今回のケースでは、そもそも外部ホストからアクセスができない状況なので、このvalidaitonを無効にするようJavaConfigを以下のように修正します。
@Configuration @EnableSwagger2 public class SwaggerConfiguration { @Bean public UiConfiguration uiConfiguration() { return UiConfigurationBuilder.builder() .validatorUrl("") .build(); } }
注意点として、公式ドキュメントのコード例では、validatorUrl(null)
と表記されていますが、ここはvalidatorUrl(null)
ではなくvalidatorUrl("")
と書くようにしてください。
validatorUrl(null)
と書いてしまうとvalidationを無効にできないので、間違えないようにしましょう。
アプリケーションを再起動して、再びIPアドレス指定でアクセスすると、以下のようにERROR表記が無効になっていることが確認できると思います。
まとめ
今回は、Springfox+Swagger+Springで生成したドキュメントの、ERROR表記の原因と対策について書きました。
今回のケースでは、ローカル環境で問題が発生しましたが、開発環境や外部からアクセスできない社内ネットワークなどにデプロイした際にも同じケースが発生すると思います。
SpringfoxでのUIまわりの設定に関する記事が少ないので、ぜひ参考になればと思います。