Kotlin Springboot -- Part 14 モジュールを 1 つから 6 つに分けて Rest から起動できるようにする
Tags: ca, kotlin, springboot
Published: 2022-10-26 16:18:54

## why?

シングルからマルチモジュールにしたい。
その方が各層の UT (単体テスト) が書きやすいから。

サブモジュールの Kotlin の有効化はこちらの
Kotlin 基礎の記事を参照。

https://dev.to/kaede_io/kotlin-ji-chu-part-11-mac-de-spring-apuride-kotlin-de-rest-moziyuruwodong-kasu-ok9

---

## 今回やらないこと

Rest から外部モジュールになった Usecase 以降を呼び出すこと。
一時的に Rest モジュールだけを動作確認する。

---

# モジュールを分割する

---

## 現状と理想

springboot / src / main / kotlin / com / example / springboot / {Resource, Usecase, Domain, ...} .kt

現状はこのように、springboot というシングルモジュールのプロジェクトになっていた。

springboot / {rest,usecase,domain, ...} / src / main / kotlin / com / kaede / {Resource, Usecase, Domain, ...} .kt

これを正確なクリーンアーキにするためには、このような構成になっているのが理想。そのためにマルチモジュールにする。

---

## モジュールの中にモジュールを作る

前提として現在 springboot という名前のモジュール(プロジェクト)を開いている。

この中にモジュールとして rest/ などを作成する。ディレクトリではない。

IntelliJ で親の springboot を右クリックして New を選ぶと

Project, Module, Java Class, ..., と新しく作るものを選べる。

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cn5onmnh5g255wotq5cr.png)

この中から Module を選ぶとこのウインドウがたちが上がる。

一例で、モジュール名は usecase として
言語が Java (デフォルト)
ビルドシステムは Gradle (デフォルト)
Gradle の記述言語は kotlin
親は springboot (デフォルト)

と選択して作成する。

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ciyngy4yc2uwudb2ffc0.png)

すると、usecase のディレクトリの中に src/main/java,kotlin,resouces,

ここまで階層が生成できる。

---

## 各モジュールの中に package を作る

rest は既にやっちゃったので usecase で説明する。

この kotlin ディレクトリの中になら package が作成できる。
作成して、com / kaede / まで作成して

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nsiarl4blrox7fwjkz5m.png)

その中に Usecase のファイルを作成する。

なお、一つ一つ手作業で GUI で作成する必要が有る。
コピーではモジュールやパッケージは作れないからだ。

---

## 5 層それぞれのモジュールと内部のパッケージを作成して親の settings.gradle.kts を確認する

こうして rest, usecase, domain, port, gateway, driver,
これらのモジュールとその中身の com / kaede のパッケージを作成。

この正式な手順を踏むことで root の settings.gradle.kts に

```kotlin
rootProject.name = "springboot"
include(
    ":target-discovery:rest"
)
include("rest")
include("usecase")
include("port")
include("domain")
include("gateway")
include("driver")
```

include で親から子供モジュールたちへの参照が自動生成された。

これでマルチモジュールは完成した。

---

# 分割された後の Rest でアプリケーションを起動してリクエストを受け取る

実際に分割された後の Rest が動くか確認する

## PersonApplication ( main )

今までは SpringbootApplication のファイルとクラス名でプロジェクトを動かしていた。

これら PersonApplication に変更する。

PersonApiApplication.kt

```kotlin
@SpringBootApplication
class PersonApiApplication

fun main(args: Array<String>) {
	runApplication<PersonApiApplication>(*args)
}
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06bmtztljhuesm60khjt.png)

すると PersonApplication の電源ボタンが表示される。

---

## PersonResource で簡単な GET リクエストを受け取る

PersonResource.kt ではエンドポイントへのハンドラを最小限にした。
ドメインとユースケースを一旦切り離した。

```kotlin
package com.kaede

import com.google.gson.Gson
import org.springframework.web.bind.annotation.*

@RestController
class PersonHandler() {
  @GetMapping("/")
  fun root(): String {
    return "PersonApiApplication Worked"
  }

  @GetMapping("/persons")
  @ResponseBody
  fun getPersons(): String {
    return "/persons"
  }
}
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/azgjns2dwhqghynyq0gv.png)

そして PersonApplication を起動して
動いている URL に GET リクエストすると
ちゃんと getPersons の return に設定した値が返ってきた。

これで Rest としてモジュールを切り離してもちゃんと動くことが確認できた。

---

# まとめ

シングルモジュールアプリケーションから
マルチモジュールアプリケーションにするためには

IntelliJ で親のモジュールを右クリックして
New -> Module で GUI からモジュールを作成する
モジュールの内部に com/所属 でパッケージを作成する

これで各層の名前でモジュールを作成数する。

そして rest 層にアプリケーション起動用の main を置く

これでとりあえず分割された rest から動くようになる。

ここから別モジュールの domain や usecase を DI する。