Kotlin Springboot -- Part 13 Usecase 以降で REST で受けった POST の JSON を Entity まで運ぶ。(モジュール分割前)
kaede
Posted on October 16, 2022
前回
前回の記事では Rest 層で Postmapping を使って POST リクエストを受け取り、ReqeustBody で、そのリクエストのボディを受け取り、関数内部で受け取ったリクエストのボディの処理を表示するところまで確認した。
とりあえず動くようにする。
エラーハンドリングやレスポンスコードの対応は後日。
今回
今回はその関数で受け取った JSON を Usecase に渡して処理していく。
Port
依存性逆転しているので、中央のポートから実装していく。
interface PersonPort {
fun getAllPersons(): Persons
fun postPerson(): Person
}
インターフェースで postPerson として作成して
Gateway
override fun postPerson(): Person {
TODO("Not yet implemented")
}
Alt Enter で Implement Abstract Function を実行して
実装が TODO 状態で Gateway に作成される。
Usecase
ここまでで、Usecase から呼び出してみる。
fun postPerson(person: Person) {
personPort.postPerson(person)
}
返り値はないので返り値と型はなく、
引数だけ型を指定して実行させる。
Rest
@PostMapping("/persons")
fun postPerson(@RequestBody request: PersonJson): String {
personsUsecase.postPerson(Person(Name(request.name), Age(request.age)))
return request.toString()
}
Rest で Usecase を呼び出す。
request から中身を取り出して、
Person ドメインと内部の Name, Age ドメインにいれて呼び出す。
Curl でリクエストする
Gateway が TODO の状態で外部から実行してみる
curl -X POST -H "Content-Type: application/json" \
-d '{"name":"test", "age":20}' \
http://localhost:8080/persons
{
"timestamp":"2022-10-16T12:22:33.962+00:00",
"status":500,
"error":"Internal Server Error",
"path":"/persons"
}
ターミナルのレスポンスには 500 が返ってきて
kotlin.NotImplementedError:
An operation is not implemented: Not yet implemented
未開発エラーが想定通りでる。
TODO だからね。
Gateway でドメインの中身を .value で出して Driver に渡す
override fun postPerson(person: Person) {
personsDriver.add(person.name.value, person.age.value)
}
Person ドメインで渡されたデータの中身を取り出して
追加するための Driver に渡す
エラーハンドリングは後日。
Driver で Entity に追加する
package com.example.springboot
import org.springframework.stereotype.Component
@Component
class PersonsDriver {
data class PersonEntity(val name: String , val age: Int)
val taro = PersonEntity("taro", 3)
val hana = PersonEntity("hana", 5)
val dom = PersonEntity("Dominique", 11)
val jack = PersonEntity("Jackson", 11)
val persons = listOf<PersonEntity>(taro,hana,dom,jack)
fun findAll(): List<PersonEntity> {
return persons
}
fun add(name: String, age: Int){
val currentPersons = findAll()
}
}
前回まではこうやって、PersonEntity のインスタンスである persons をデータの本体として、そこから findAll していた。
val persons = mutableListOf(
PersonEntity("taro", 3),
PersonEntity("hana", 5),
PersonEntity("Dominique", 11),
PersonEntity("Jackson", 11),
)
persons を少し見やすくして、mutable にした。
この persons に付け加えるように今回は実装する。
データストアにいれたい
現状、ちゃんとデータを保持していなかった
gauge E2E の回でやったデータストアを使ってみる
https://codelabs.developers.google.com/codelabs/cloud-spring-datastore#2
ググると GCP のデータストアがでてくる
他は Android のデータストアしかでてこないので諦める。
Driver で add する
fun add(name: String, age: Int){
persons.add(
PersonEntity(name, age),
)
println(persons)
}
persons という変数に引数の値からエンティティを追加して、
一時的に persons を全員表示して確認する
curl -X POST -H "Content-Type: application/json" \
-d '{"name":"test", "age":20}' \
http://localhost:8080/persons
PersonJson(name=test, age=20)
[PersonEntity(name=taro, age=3), PersonEntity(name=hana, age=5), PersonEntity(name=Dominique, age=11), PersonEntity(name=Jackson, age=11), PersonEntity(name=test, age=20)]
無事に追加された。
まとめ
Rest から POST で送られてきた JSON データをインメモリで保存するためには
Usecase から Port を通じて渡して
Gateway では Domain から中身を抜いて渡して
Driver では Entity に詰めてエンティティのインスタンスとして作った変数に追加する。
これで実装できる
今後
POST まで作ったのでまず E2E を追加したい。
しかし、DB ならアサートできるが、変数作っただけのデータでどう保存されたことをテストできるかは課題。
UUID も発行してないので、テストする前にそれをつくってエラーハンドリングして 200 or 500 を返すようにしたい
Posted on October 16, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.