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)