코틀린 웹 프로그래밍 using Ktor (2)

ver 1.0

이번 글에서는 지난 글에서 만들었던 ktor-first-app을 모듈형 프로젝트 구조로 변경해보겠습니다.

지난 시간에 만들었던 ktor-first-app은 다음과 같은 디렉토리 구조를 가지고 있었습니다.

Screen Shot 2019-07-14 at 2.23.33 am

ktor generator가 생성해준 이 프로젝트 구조는 전통적인 자바 프로젝트 디렉토리 구조와는 차이가 있습니다. 그리고 자바 9에서 Java Platform Module System(JPMS - 줄여서 Module이라고 흔히 부름)이 추가된 이후로는 아마 대부분의 프로젝트에서 모듈을 흔히 사용합니다. 자바 모듈을 사용하면 연관성 있는 패키지들을 모듈로 묶어 재사용성을 높이고 유지 보수를 더 수월하게 만들 수 있습니다. 따라서 기존 프로젝트를 자바 프로그래머에게 좀 더 익숙하고 장점이 많은 모듈 구조로 바꿔보겠습니다.

먼저 build.gradle.kts 파일을 열고 파일 마지막에 다음 내용을 지웁니다.

1
2
3
4
5
...
kotlin.sourceSets["main"].kotlin.srcDirs("src")
kotlin.sourceSets["test"].kotlin.srcDirs("test")
sourceSets["main"].resources.srcDirs("resources")
sourceSets["test"].resources.srcDirs("testresources")

해당 부분을 지우면 프로젝트 도구 윈도우에서 하늘색 네모 아이콘이 사라진 모습을 보실 수 있습니다.

Screen Shot 2019-07-18 at 9.51.58 pm

프로젝트 도구 윈도우에서 프로젝트 루트를 마우스 오른쪽 버튼으로 선택한후 모듈 추가를 선택합니다.

Screen Shot 2019-07-18 at 9.53.39 pm

다음과 같이 backend 이름을 넣고 모듈을 생성합니다.

Screen Shot 2019-07-18 at 9.55.15 pm

모듈을 생성하면 빌드가 깨지는 것을 볼 수 있습니다. 하지만 당황하지 마시고 backend/build.gradle.kts 파일의 모든 내용을 지운후에 파일을 저장 합니다.

똑같은 방식으로 common, frontend  모듈을 생성하고 각 모듈아래의 build.gradle.kts 내용을 모두 지우고 저장합니다. 작업을 완료하면 다음과 같은 구조를 가지게 됩니다.

Screen Shot 2019-07-18 at 10.08.40 pm

Screen Shot 2019-07-19 at 1.17.59 am

프로젝트 루트 밑의 settings.gradle 파일을 열고 모든 내용을  settings.gradle.kts로 복사합니다. 그리고 다음과 같이 변경합니다.

1
2
3
4
rootProject.name = "ktor-first-app"
include("backend")
include("common")
include("frontend")

변경후에는 settings.gradle파일을 삭제합니다.

프로젝트 루트의 build.gradle.kts  파일을 열어 다음과 같이 변경합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
val kotlin_version: String by project
val logback_version: String by project
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.40")
    }
}
plugins {
    java
}
allprojects {
    group = "com.example"
    version = "0.0.1-SNAPSHOT"
    apply(plugin = "org.jetbrains.kotlin.jvm")
    repositories {
        mavenCentral()
    }
    dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version")
        implementation("ch.qos.logback:logback-classic:$logback_version")
    }
}
subprojects {
    version = "0.0.1-SNAPSHOT"
}
project("backend") {
}
project("common") {
}
project("frontend") {
}

backend 모듈의 build.gradle.kts을 열고 다음과 같이 변경합니다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
val kotlin_version: String by project
val ktor_version: String by project
plugins {
    application
}
application {
    mainClassName = "io.ktor.server.cio.EngineMain"
}
repositories {
    jcenter()
}
dependencies {
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version")
    implementation("io.ktor:ktor-server-cio:$ktor_version")
    testImplementation("io.ktor:ktor-server-tests:$ktor_version")
}

src/Application.kt 파일을 backend 모듈 밑에 src/main/kotlin 폴더를 생성하고 이곳으로 복사합니다. 그리고 기존의 프로젝트 루트 폴더의 src 폴더는 삭제합니다.

Screen Shot 2019-07-19 at 12.51.55 am

test/Application.kt 파일을 backend 모듈 밑에 src/test/kotlin 폴더를 생성하고 이곳으로 복사합니다. 그리고 기존 프로젝트 루트 폴더의 test 폴더는 삭제합니다.

Screen Shot 2019-07-19 at 1.05.06 am

프로젝트 루트 폴더의 resources 폴더를 backend 모듈의 src/main 폴더 밑으로 옮겨 줍니다.

Screen Shot 2019-07-19 at 1.09.25 am

이제 프로젝트 구성을 마쳤습니다.

프로젝트가 잘 변경되었는지 확인해 보겠습니다.

지금은 브라우저에서 / 경로에 저급하면 HELLO WORLD!" 를 출력하고 있습니다.

이 문자열을 "HELLO WORLD from Backend!"로 변경해 봅니다.

backend 모듈의 test/kotlin/ApplicationTest를 열고 다음과 같이 변경합니다.

1
2
3
4
5
6
...
handleRequest(HttpMethod.Get, "/").apply {
    assertEquals(HttpStatusCode.OK, response.status())
    assertEquals("HELLO WORLD from Backend!", response.content)
}
...

테스트를 실행하면 실패하는 것을 보실 수 있습니다.

Screen Shot 2019-07-19 at 1.17.59 am

테스트가 통과할 수 있게 backend/src/kotlin/Application.kt 파일을 다음과 같이 변경합니다.

1
2
3
4
5
6
7
...
routing {
    get("/") {
        call.respondText("HELLO WORLD from Backend!", contentType = ContentType.Text.Plain)
    }
    ...
}

다시 한 번 테스트를 실행해 봅니다. 테스트가 잘 실행되는 것을 볼 수 있습니다.

Screen Shot 2019-07-19 at 1.21.38 am

프로그램을 실행하고 브라우저에서 0.0.0.0:8080에 접근해서 변경한 결과가 나오는지 확인합니다.

Screen Shot 2019-07-19 at 1.24.31 am

축하드립니다. 아마 이 시리즈에서 가장 어려운 부분을 끝마치셨습니다. JVM기반 언어 프로젝트에서는 프로젝트 셋팅이 초보자들에게 가장 큰 허들이라고 해도 과언이 아닙니다. 필자도 초보시절에는 프로젝트 셋팅만으로 몇 일을 고생한 적이 있습니다. 다들 처음에는 익숙하지 않아 어렵게 느껴집니다. 지겹고 어려운 부분은 정말 다 끝났습니다. 이제 다음 글에서는 본격적으로 코딩을 시작해보겠습니다.


Popit은 페이스북 댓글만 사용하고 있습니다. 페이스북 로그인 후 글을 보시면 댓글이 나타납니다.