실무 프로젝트로 배우는 Kotlin & Spring/이슈 관리 서비스 개발하기

요구 사항 & 프로젝트 구성

webmaster 2022. 11. 26. 18:11
728x90

요구 사항 

  • 이슈 관리 서비스 메인
    • 상태에 따라 할 일, 진행 중, 완료 세 가지 탭 존재
    • 기본 상태는 할일이고, 탭을 눌렀을 때 상태별 이슈 목록 API를 조회한다
  • 이슈 등록
    • 이슈를 생성하는데 필요한 데이터를 입력받아 이슈 등록 API를 호출한다.
  • 이슈 상세 조회
    • 이슈 상세를 눌렀을 때 선택된 이슈 상세 조회 API 호출한다.
    • 저장 버튼이 눌렀을 때 변경된 데이터로 이슈 수정 API를 호출한다.
    • 삭제 버튼을 누르면 이슈 삭제 API를 호출한다.
    • 댓글 입력 후 엔터를 누르면 코멘트 등록 API를 호출한다.
    • 댓글 수정 버튼을 누르면 댓글을 수정할 수 있고, 엔터를 누르면 코멘트 수정 API를 호출한다.
    • 댓글 삭제 버튼을 누르면 코멘트 삭제 API를 호출한다

프로젝트 구성하기

Main 프로젝트

Spring Initializer 로 생성

  • springweb, h2, spring data JPA, thymeleaf 의존성을 추가한다.

build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "2.7.6"
    id("io.spring.dependency-management") version "1.0.15.RELEASE"
    kotlin("jvm") version "1.6.21"
    kotlin("plugin.spring") version "1.6.21"
    kotlin("plugin.jpa") version "1.6.21"
}

java.sourceCompatibility = JavaVersion.VERSION_11

allprojects {
    group = "com.fastcampus"
    version = "0.0.1-SNAPSHOT"
    repositories {
        mavenCentral()
    }
}
subprojects {
    apply(plugin = "kotlin")
    apply(plugin = "kotlin-spring")
    apply(plugin = "io.spring.dependency-management")

    dependencies {
        // JWT 인증
        implementation("com.auth0:java-jwt:3.19.2")

        // kotlin 로깅
        implementation("io.github.microutils:kotlin-logging:1.12.5")

        //kotlin
        implementation("org.jetbrains.kotlin:kotlin-reflect")
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
        implementation("com.fasterxml.jackson.module:jackson-module-kotlin")

        // H2DB
        runtimeOnly("com.h2database:h2")
        testImplementation("org.springframework.boot:spring-boot-starter-test")
    }

    dependencyManagement {
        imports {
            mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
        }
    }

    tasks.withType<KotlinCompile> {
        kotlinOptions {
            freeCompilerArgs = listOf("-Xjsr305=strict")
            jvmTarget = "11"
        }
    }

    tasks.withType<Test> {
        useJUnitPlatform()
    }
}

Module 프로젝트

build.gradle.kts

apply(plugin = "kotlin-jpa")

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
    implementation("org.springframework.boot:spring-boot-starter-web")
}

후에 있을 인증 관련 ArgumentResolver 설정을 미리 하자

config/Webconfig

@Configuration
class WebConfig(
    private val authUserHandlerArgumentResolver: AuthUserHandlerArgumentResolver
) : WebMvcConfigurationSupport() {
    override fun addArgumentResolvers(argumentResolvers: MutableList<HandlerMethodArgumentResolver>) {
        argumentResolvers.apply {
            add(authUserHandlerArgumentResolver)
        }
    }
}

@Component
class AuthUserHandlerArgumentResolver : HandlerMethodArgumentResolver {
    override fun supportsParameter(parameter: MethodParameter): Boolean =
        AuthUser::class.java.isAssignableFrom(parameter.parameterType) //해당 조건이 맞아야 조건 통과
    override fun resolveArgument(
        parameter: MethodParameter,
        mavContainer: ModelAndViewContainer?,
        webRequest: NativeWebRequest,
        binderFactory: WebDataBinderFactory?
    ): Any? {
        return AuthUser(
            userId = 1,
            username = "테스트"
        )

    }
}

data class AuthUser(
    val userId: Long,
    val username: String,
    val profileUrl: String? = null,
) {

}
  • WebConfigurationSupport()를 상속받아 web관련 설정을 오버라이드 할 수 있게 한다
    • addArgumentResolver를 오버라이드 하여, 인증에 사용될 아규먼트 리졸버를 등록한다.
  • AuthUserHandlerArgumentResolver를 만들어 인증 관련 핸들러로 사용하고, HandlerMethodArgumentResolver를 상속받는다.
    • supportsParameter로 resolveArgument를 적용할 대상을 판단
    • resolveArgument를 통해 인증된 객체를 반환한다.

 

728x90