[Jackson]kotlin/springbootでSwaggerのjsonファイルとyamlファイルを出力する方法

[前回の記事](https://qiita.com/dddEn/items/c28c25a71a7672d11de2)でSwaggerを使ってAPIドキュメントをコードから自動生成するようにしました。
今回はそこからJacksonを使ってjsonファイルとyamlファイルを出力してみます。

# jsonファイルの取得元の確認
今回は[localohost:8080/v2/api-docs](localohost:8080/v2/api-docs)からjsonファイルを取得します。

`Configuration.kt`で`.groupName`を指定している場合は[localohost:8080/v2/api-docs?group=グループネーム](localohost:8080/v2/api-docs?group=グループネーム)というようにクエリーを設定してください。
[前回の記事](https://qiita.com/dddEn/items/c28c25a71a7672d11de2)だと`.groupName("Qiita")`としているので[localohost:8080/v2/api-docs?group=Qiita](localohost:8080/v2/api-docs?group=Qiita)となります。

# jsonファイルの作成
今回はSpringBootTestを使用して自動でファイルが作成されるようにします。

まずはjsonの変換にJacksonを使用するので`build.gradle.kts`に以下のように追加しましょう。

```gradle:build.gradle.kts
dependencies {
	compile("com.fasterxml.jackson.module:jackson-module-kotlin")
	compile("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.9.8")
}
```

バージョンによって`dataformat`が`module`内に入ってたり入ってなかったりするので、そこは導入時に確認してください。

次に`sample_qiita/src/test/kotlin/com.example.sample_qiita`に`swagger`パッケージを作成して、その中に`SwaggerDocsGenerateTest.kt`を作成します。

```kotlin:SwaggerDocsGenerateTest.kt
package com.example.sample_qiita.swagger

import ...

@RunWith(SpringRunner::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFAULT_PORT)
class SwaggerDocsGenerateTest {

    @Autowired
    lateinit var testRestTemplate: TestRestTemplate

    companion object {
        private const val OUTPUT_DIR = "./swagger-docs"
        private const val V2_API_DOCS = "/v2/api-docs?group=Qiita"
    }

    @Test
    @Throws(Exception::class)
    fun generateSwaggerDocs() {
        // json
        val swaggerJson = testRestTemplate.getForObject(V2_API_DOCS, String::class.java)
        File("$OUTPUT_DIR/swagger.json").bufferedWriter().use { it.write(swaggerJson) }
}
```

ではルート直下に`swagger-docs`というディレクトリを作成して、早速テストを実行してみましょう。
`swagger.json`というファイルが作成され、[localohost:8080/v2/api-docs?group=Qiita](localohost:8080/v2/api-docs?group=Qiita)と同じjsonが保存されれば成功です。


## jsonファイルの編集
今回はSpringBootTestアノテーションで`webEnvironment = SpringBootTest.WebEnvironment.DEFAULT_PORT`と指定しており`localhost:8080`でテストするようにしているので、作成された`swagger.json`ファイルを確認すると以下のような形になっていると思います。
（ちなみにRANDOM_PORTと指定するとその時で空いているランダムなポートが入力されます。）

```json:swagger.json
{"swagger":"2.0","info":   ...   ,"host":"localhost:8080",   ...   }
```

もしこれを変更したい場合は以下のようにします。

```kotlin:SwaggerDocsGenerateTest.kt
    @Test
    @Throws(Exception::class)
    fun generateSwaggerDocs() {
        // json
        val swaggerJson = testRestTemplate.getForObject(V2_API_DOCS, String::class.java)

        // jsonファイルの編集
        var onode = ObjectMapper().readTree(swaggerJson).deepCopy<ObjectNode>()
        onode.put("host", "172.16.240.10:8080")
        val FixSwaggerJson = ObjectMapper().writeValueAsString(onode)

        File("$OUTPUT_DIR/swagger.json").bufferedWriter().use { it.write(FixSwaggerJson) }

```

```json:swagger.json
{"swagger":"2.0","info":   ...   ,"host":"172.16.240.10:8080",   ...   }
```

これでjsonファイルを編集することができました。
他のステータスを変更したい場合も同じようにしましょう。
（基本的には`Configuration.kt`で編集するようにして、どうしても変更できない部分を編集したい場合にこの方法を使用するようにしてください。）

# yamlファイルの作成。
取得したjsonファイルをもとに今度はyamlファイルを作成します。
`SwaggerDocsGenerateTest.kt`に次のように追記しましょう。

```kotlin:SwaggerDocsGenerateTest.kt
    @Test
    @Throws(Exception::class)
    fun generateSwaggerDocs() {
        // json
        val swaggerJson = testRestTemplate.getForObject(V2_API_DOCS, String::class.java)
        File("$OUTPUT_DIR/swagger.json").bufferedWriter().use { it.write(swaggerJson) }

        // yaml
        val swaggerYaml = YAMLMapper().writeValueAsString(ObjectMapper().readTree(swaggerJson))
        File("$OUTPUT_DIR/swagger.yaml").bufferedWriter().use { it.write(swaggerYaml) }
    }
```

これでテストを実行すると、`swagger.yaml`というファイルが作成されるようになりました。

# 最後に
基本的には[localhost:8080/swagger-ui.html](localhost:8080/swagger-ui.html)を使用することを推奨します。
どうしてもSwagerのjsonやyamlファイルが欲しい場合や[次の記事](https://qiita.com/dddEn/items/7359672ace2bf6080c1d)のようにこれを元にSwagger用のDockerコンテナを立てたりする時に使用するようにしてください。

# 参考文献
[FasterXML/jackson](https://github.com/FasterXML/jackson)
[Class YAMLMapper](http://fasterxml.github.io/jackson-dataformat-yaml/javadoc/2.7/com/fasterxml/jackson/dataformat/yaml/YAMLMapper.html)
[Java 向け JSON ライブラリ Jackson でデータを読み込む](https://blog.kymmt.com/entry/jackson)
[Jackson でオブジェクトを JSON に変換](http://k-7016.hatenablog.com/entry/2013/09/17/232241)
[Jackson使い方メモ](https://qiita.com/opengl-8080/items/b613b9b3bc5d796c840c)
[Kotlin で JSON を利用](https://qiita.com/Livenga/items/57bd38795a68bd077431)
[JavaでJSONを楽々読み書きしよう! Jacksonの基本を解説](https://engineer-club.jp/java-json)
[Annotation Type SpringBootTest](https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/api/org/springframework/boot/test/context/SpringBootTest.html)
[Spring BootでTestRestTemplateを試す](http://pppurple.hatenablog.com/entry/2016/10/24/031642)
[SpringのRestTemplateが便利すぎて鼻血でた](https://qiita.com/yoshidasts/items/fd4e1f4434e3b6f40880)