DEV Community

kaede
kaede

Posted on • Updated on

Kotlin Springboot -- Part 15 Rest と Usecase で Domain を使えるようにする ( モジュール分割後 )

why

前回の記事で各層のモジュールを分離して
とりあえず Rest だけは動くようにした。

今回は Rest から Domain と Usecase のモジュールも使えるようにする。


Rest


Rest モジュールから Domain モジュールに何も依存を足さずにアクセスする

package com.kaede
Enter fullscreen mode Exit fullscreen mode

パッケージ自体はこのように、Rest, Usecase, Domain, Port, Gateway, Driver, とすべて同じものを使っている。

一方、マルチモジュールにするためにモジュールを分割した。
なのでモジュール外部のクラスの関数を使うことはこのままではできない。

特に外部モジュールだということを意識せずに
同一モジュールにあった時と同様に Domain, Usecase を使ってみる。

  @GetMapping("/persons")
  @ResponseBody
  fun getPersons(): String {
    val persons = personsUsecase.getAllPersons()
    val gson = Gson()
    val personsJson = persons.toJson()

    return gson.toJson(personsJson)
  }
Enter fullscreen mode Exit fullscreen mode

toJson は Domain の拡張。

Caused by: java.lang.NoClassDefFoundError: com/kaede/PersonsUsecase
Enter fullscreen mode Exit fullscreen mode

すると Usecase がみつからないとエラーがでて
アプリケーションが落ちる。

usecase だけを追加しても

e: /home/kaede/source/springboot/rest/src/main/kotlin/
com/kaede/PersonResource.kt: (18, 34): 
Cannot access class 'com.kaede.Persons'. 
Check your module classpath 
for missing or conflicting dependencies
Enter fullscreen mode Exit fullscreen mode

Persons ドメインが見つからないとエラーでビルドできなくなる。


Rest の設定ファイルに Usecase と Domain の依存を追加

rest/bulid.gradle.kts に

dependencies {
    implementation(project(":usecase"))
    implementation(project(":domain"))
}
Enter fullscreen mode Exit fullscreen mode

usecase と domain のパッケージを読み込めるように設定する

Image description

その後に Gradle の象さんのポップアップしたリロードボタンを押す

基本的にはモジュール(プロジェクト)外のクラスは使えないが
こうすることでモジュール外のプロジェクトも読めるようになる。

2022-11-26 21:35:27.840  INFO 1943002 --- [           
main] com.kaede.PersonApiApplicationKt         
: Started PersonApiApplicationKt in 1.915 seconds 
(JVM running for 2.309)
Enter fullscreen mode Exit fullscreen mode

無事に起動できた。


Usecase

同様に Usecase からも他のモジュールたちが読み込めるようにする。

@Component
class PersonsUsecase(
  private val personPort: PersonPort,
) {
  fun getAllPersons():Persons {
    return personPort.getAllPersons()
  }
Enter fullscreen mode Exit fullscreen mode

Usecase の実装と

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

Port の実装がこちら(実装というかインターフェイスだが)


依存の記述なしで起動する

Caused by: java.lang.NoClassDefFoundError: com/kaede/PersonPort
Enter fullscreen mode Exit fullscreen mode

Port の依存を書かずに動かすと、当然 Port のクラスが
見つからないエラーが出る。

なので、Usecase の設定ファイル
build.gradle.kts に Port の依存を追加する
Domain の依存は自明。

dependencies {
    implementation(project(":domain"))
    implementation(project(":port"))
// ...
}
Enter fullscreen mode Exit fullscreen mode

しかし、Port だけ追加しても


***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.kaede.PersonsUsecase 
required a bean of type 'com.kaede.PersonPort' 
that could not be found.
Enter fullscreen mode Exit fullscreen mode

PersonPort はみつからないとでてしまう

dependencies {
    implementation(project(":domain"))
    implementation(project(":port"))
    implementation(project(":gateway"))
// ...
}
Enter fullscreen mode Exit fullscreen mode

Port の先の Gateway まで Usecase の依存に追加する。

2022-11-26 21:46:12.453  INFO 1945207 --- [           
main] com.kaede.PersonApiApplicationKt         
: Started PersonApiApplicationKt in 1.999 seconds 
(JVM running for 2.418)
Enter fullscreen mode Exit fullscreen mode

すると無事に起動するようになる。

Image description

以前作成した図を参照する。

Gateway が必要なのは、Port は単なる穴であるからだ。
穴単体を覗くという行為は成立しない。
穴の先が有るから、穴を覗けるのだ。

だから Port という穴と、同時に穴の先に存在する Gateway を、
Usecase からは依存として必要になる。


まとめ

クリーンアーキテクチャで各層ごとにモジュールを分離した。

その後、正常に動作させるためには
各モジュールの依存先として

  • Rest モジュールの build.gradle.kts
    • Domain
    • Usecase
  • Usecase モジュールの build.gradle.kts
    • Domain
    • Port
    • Gateway

まず、これらの記述が必要になる。

以上。

Top comments (0)