why
前回は Driver で DB や API などから取ってこられる DB テーブルの世界のエンティティを返し、
Gateway でエンティティを業務の世界のオブジェクトを表すデータクラスである Domain に詰め直した。
今回は Usecase を介して渡された Domain オブジェクトを API として JSON で出力するための新しいデータクラスに Rest で変換する。
これは DomainName.toJson と名付け、Domain の拡張だが、Rest に定義する。
Django で Serializer が行っていた役割と似ているが、こちらは型をつける必要が有る。
REST のどこに書くのか
@RestController class PersonHandler { @GetMapping("/persons") fun getPersons(): String { // ..... }
この HTTP リクエストの対応を書くクラスの外に JSON のためのデータクラスを作る。
Json にするための ObjectJson のデータクラスを作る
data class PersonsJson(val persons: List<PersonJson>) data class PersonJson( val name: String, val age: Int, )
JSON レスポンスのためのデータクラス。
JSON には型はないので、JSON にした瞬間に型は消滅し
val で入っている key と中身が残る。
{ "persons": [ { "name": "text", "age": 12345 } ]
よって、val persons とその中の配列の
val name, val age, これらがこうやって返される。
Domain から ObjectJson にするための Object.toJson 関数を作る
Domain のデータクラス、Persons を拡張する。
こちらも REST に書く。
toJson といいつつ、これを実行したところで JSON にはならない。
JSON に変換する事前準備のための型という意味。
fun Persons.toJson() = PersonsJson(this.list.map { (it.toJson())}) fun Person.toJson(): PersonJson { val personJson = PersonJson( this.name.value, this.age.value,) return personJson }
Person*s*.toJson では
ドメインの Persons を map して
中身の各 Person に Person.toJson を実行させる。
Persons.toJson では this で参照して
name と age の value を出して PersonJson の中にいれて return する。
Domain のデータクラスの中に入っていたものを
Json 用のデータクラスの中に詰め替えている。
Kotlin オブジェクトを JSON に変換するための gson ライブラリを入れる
bulid.grade.kts を開き
dependencies { //... implementation ("com.google.code.gson:gson:2.9.1") }
gson の依存を書いて Gradle をリロードする。
すると gson ライブラリがインストールされる。
REST で gson を呼び出す
import com.google.gson.Gson // ... val persons = personsUsecase.getAllPersons() val gson = Gson() val personsJson = persons.toJson() val json2 = gson.toJson(personsJson)
Gson はこのように使える。
UseCase などのインスタンスを作る時と同じように
一度クラスからインスタンスを作り、
そのインスタンスからメンバー関数を呼び出す。
Usecase から呼び出された Domain に入った persons を toJson 型に詰め直して、その後 gson で変換する。
web で確認する
Springbooot で起動したサーバーにアクセスすると
このようにレスポンスが綺麗にみえた。これで使える。
// 20220908225236 // http://localhost:8080/persons { "persons": [ { "name": "taro", "age": 3 }, { "name": "hana", "age": 5 } ] }
まとめ
DB テーブルの都合のエンティティ
オブジェクト指向の都合のドメイン
JSON の都合のtoJson
これらの 3 つのデータクラスを使い分けるのが、クリーンアーキテクチャ。
Kotlin クリーンアーキテクチャで REST で API に適した JSON を返す。
そのためには Gateway でオブジェクト指向の都合で Domain に詰められているものを Usecase から Rest に運んできた後に
JSON 用のデータクラスに詰め替えて、その上で gson を使って JSON に変換すればうまく行く。
Domain のまま JSON に変換するとこうなりますからね。
{ "list":[ { "name":{ "value":"taro" }, "age":{ "value":3 } }, { "name":{ "value":"hana" }, "age":{ "value":5 } } ] }
Top comments (0)