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


前回の記事でSwaggerを使ってAPIドキュメントをコードから自動生成するようにしました。
今回はそこからJacksonを使ってjsonファイルとyamlファイルを出力してみます。

jsonファイルの取得元の確認

今回はlocalohost:8080/v2/api-docsからjsonファイルを取得します。

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

jsonファイルの作成

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

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

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

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

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

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と同じjsonが保存されれば成功です。

jsonファイルの編集

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

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

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

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) }

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

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

yamlファイルの作成。

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

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を使用することを推奨します。
どうしてもSwagerのjsonやyamlファイルが欲しい場合や次の記事のようにこれを元にSwagger用のDockerコンテナを立てたりする時に使用するようにしてください。

参考文献

FasterXML/jackson
Class YAMLMapper
Java 向け JSON ライブラリ Jackson でデータを読み込む
Jackson でオブジェクトを JSON に変換
Jackson使い方メモ
Kotlin で JSON を利用
JavaでJSONを楽々読み書きしよう! Jacksonの基本を解説
Annotation Type SpringBootTest
Spring BootでTestRestTemplateを試す
SpringのRestTemplateが便利すぎて鼻血でた