Springfox+Swaggerで生成したドキュメントにERRORバッジが含まれてしまう問題

Springで実装したREST APIサーバアプリケーションにSpringfox+Swaggerを導入してWebドキュメントを自動生成したのですが、環境によってデプロイ後の画面で以下のようなErrorバッジが表示されるケースがありました。
 <img src="http://online.swagger.io/validator?url={YOUR_URL}"> 
そこで今回は、その原因と解決策について書いていきたいと思います。
# 環境
- Java 1.8.0_131
- Spring Boot 2.0.1.RELEASE
- springfox-swagger-ui 2.8.0
- springfox-swagger2 2.8.0

# サンプルコード
ControllerクラスのサンプルコードとSwagger用のJavaConfigのサンプルコードを以下に示します。

```java:SampleSwaggerController.java
@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!";
    }
}
```

```java:SwaggerConfiguration.java
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
}
```

# 問題
このアプリケーションをlocalhostで起動して http://localhost:8080/swagger-ui.html にアクセスすると、ドキュメントが表示されます。
(デフォルト設定なので、コードに書いていないパスも含まれています)
![スクリーンショット 2018-04-14 20.57.21.png](https://qiita-image-store.s3.amazonaws.com/0/160829/19eae885-d3d9-9e76-d129-50341fbfa3e9.png)

次にこのアプリケーションをHerokuにデプロイしてアクセスすると、右下にVALIDとかかれたドキュメントが表示されます。
![スクリーンショット 2018-04-14 21.03.55.png](https://qiita-image-store.s3.amazonaws.com/0/160829/128a77ad-40cd-b8a3-e8b6-517cc8cdbffd.png)

次に、「localhost」ではなく、localhostのIPアドレスを直接指定して、http://192.168.11.6:8080/swagger-ui.html にアクセスすると、右下にErrorとかかれたドキュメントが表示されます。
![スクリーンショット 2018-04-14 20.59.53.png](https://qiita-image-store.s3.amazonaws.com/0/160829/9f37b2e9-86e0-16ac-9c98-13b313e3ba91.png)

# 原因
Swaggerには、生成したSwagger Specificationのvalidationをおこなう機能が自動で有効になっています(ただし、localhostというURLの場合はvalidation機能は無効になります)。

Swagger-APIの[GitHub](https://github.com/swagger-api/validator-badge)にも以下のように記されています。
> 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.

これを読むと、問題のエラー表記は以下の2つのどちらかが原因なようです。

- Swagger Specificationの構文が不正
- validationを行う外部ホスト(online.swagger.io)から該当サーバへアクセスできない

今回のケースでは、localhostを指定した場合にはvalidationが無効になります。
また、herokuへデプロイした場合にはonline.swagger.ioからアクセスできるので、ERROR表記はでません。
しかし、localhostのIPアドレスを直接指定してアクセスした場合には、validationが有効になり、さらにonline.swagger.ioからアクセスができないのでERROR表記がでてしまったのだと考えられます。

# 対策
今回のケースでは、そもそも外部ホストからアクセスができない状況なので、このvalidaitonを無効にするようJavaConfigを以下のように修正します。

```java:SwaggerConfiguration.java
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {

    @Bean
    public UiConfiguration uiConfiguration() {
        return UiConfigurationBuilder.builder()
                .validatorUrl("")
                .build();
    }
}
```
注意点として、[公式ドキュメント](http://springfox.github.io/springfox/docs/current/#springfox-spring-mvc-and-spring-boot)のコード例では、`validatorUrl(null)`と表記されていますが、ここは**`validatorUrl(null)`**ではなく**`validatorUrl("")`**と書くようにしてください。
`validatorUrl(null)`と書いてしまうとvalidationを無効にできないので、間違えないようにしましょう。([参考](https://github.com/springfox/springfox/issues/2201))

アプリケーションを再起動して、再びIPアドレス指定でアクセスすると、以下のようにERROR表記が無効になっていることが確認できると思います。
![スクリーンショット 2018-04-14 21.38.16.png](https://qiita-image-store.s3.amazonaws.com/0/160829/a1d17aa8-76e9-2349-1745-e48db20688f0.png)

# まとめ
今回は、Springfox+Swagger+Springで生成したドキュメントの、ERROR表記の原因と対策について書きました。

今回のケースでは、ローカル環境で問題が発生しましたが、開発環境や外部からアクセスできない社内ネットワークなどにデプロイした際にも同じケースが発生すると思います。

SpringfoxでのUIまわりの設定に関する記事が少ないので、ぜひ参考になればと思います。

# 参考
- [Springfox Reference Documentation](http://springfox.github.io/springfox/docs/current/#springfox-spring-mvc-and-spring-boot)
- https://github.com/springfox/springfox/issues/2201
- https://stackoverflow.com/questions/27808804/swagger-ui-shows-error-validation-when-deployed