DEV Community

kaede
kaede

Posted on • Edited on

Kotlin Springboot -- Part 13 Usecase 以降で REST で受けった POST の JSON を Entity まで運ぶ。(モジュール分割前)

前回

前回の記事では Rest 層で Postmapping を使って POST リクエストを受け取り、ReqeustBody で、そのリクエストのボディを受け取り、関数内部で受け取ったリクエストのボディの処理を表示するところまで確認した。

とりあえず動くようにする。
エラーハンドリングやレスポンスコードの対応は後日。


今回

今回はその関数で受け取った JSON を Usecase に渡して処理していく。


Port

依存性逆転しているので、中央のポートから実装していく。

interface PersonPort {
    fun getAllPersons(): Persons
    fun postPerson(): Person
}
Enter fullscreen mode Exit fullscreen mode

インターフェースで postPerson として作成して


Gateway

    override fun postPerson(): Person {
        TODO("Not yet implemented")
    }
Enter fullscreen mode Exit fullscreen mode

Alt Enter で Implement Abstract Function を実行して

実装が TODO 状態で Gateway に作成される。


Usecase

ここまでで、Usecase から呼び出してみる。

  fun postPerson(person: Person) {
    personPort.postPerson(person)
  }
Enter fullscreen mode Exit fullscreen mode

返り値はないので返り値と型はなく、
引数だけ型を指定して実行させる。


Rest

  @PostMapping("/persons")
  fun postPerson(@RequestBody request: PersonJson): String {
    personsUsecase.postPerson(Person(Name(request.name), Age(request.age)))
    return request.toString()
  }
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
{
"timestamp":"2022-10-16T12:22:33.962+00:00",
"status":500,
"error":"Internal Server Error",
"path":"/persons"
}
Enter fullscreen mode Exit fullscreen mode

ターミナルのレスポンスには 500 が返ってきて

kotlin.NotImplementedError: 
An operation is not implemented: Not yet implemented
Enter fullscreen mode Exit fullscreen mode

未開発エラーが想定通りでる。
TODO だからね。


Gateway でドメインの中身を .value で出して Driver に渡す

  override fun postPerson(person: Person) {
    personsDriver.add(person.name.value, person.age.value)
  }
Enter fullscreen mode Exit fullscreen mode

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()
  }
}
Enter fullscreen mode Exit fullscreen mode

前回まではこうやって、PersonEntity のインスタンスである persons をデータの本体として、そこから findAll していた。

  val persons = mutableListOf(
    PersonEntity("taro", 3),
    PersonEntity("hana", 5),
    PersonEntity("Dominique", 11),
    PersonEntity("Jackson", 11),
  )
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

persons という変数に引数の値からエンティティを追加して、
一時的に persons を全員表示して確認する

curl -X POST -H "Content-Type: application/json" \
-d '{"name":"test", "age":20}' \
http://localhost:8080/persons
PersonJson(name=test, age=20)
Enter fullscreen mode Exit fullscreen mode
[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)]
Enter fullscreen mode Exit fullscreen mode

無事に追加された。


まとめ

Rest から POST で送られてきた JSON データをインメモリで保存するためには

Usecase から Port を通じて渡して

Gateway では Domain から中身を抜いて渡して

Driver では Entity に詰めてエンティティのインスタンスとして作った変数に追加する。

これで実装できる


今後

POST まで作ったのでまず E2E を追加したい。
しかし、DB ならアサートできるが、変数作っただけのデータでどう保存されたことをテストできるかは課題。

UUID も発行してないので、テストする前にそれをつくってエラーハンドリングして 200 or 500 を返すようにしたい

Top comments (0)