Info
Repository
Environment
- kotlin
- java 17
- spring-boot v3.3.2
- gradle
- cache
- redis
- logging
- log4j
- database
- mysql
- h2 (in Local)
- jpa
- querydsl
- security
- spring-security
- validation
- test
- junit5
- restdocs-mockmvc
- mockk
- object
- mapstruct
- kassava
Package
plugins {
id("org.springframework.boot") version "3.3.2"
id("io.spring.dependency-management") version "1.1.6"
kotlin("jvm") version "1.9.24"
kotlin("plugin.spring") version "1.9.24"
kotlin("plugin.jpa") version "1.9.20"
kotlin("kapt") version "1.7.10"
id("org.asciidoctor.jvm.convert") version "3.3.2"
idea
jacoco}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
maven("https://jitpack.io")
}
dependencies {
// DEFAULT
implementation("org.springframework.boot:spring-boot-starter-web:3.1.0")
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.jetbrains.kotlin:kotlin-reflect")
// CACHING
implementation("org.springframework.boot:spring-boot-starter-data-redis")
// LOGGING
implementation("org.springframework.boot:spring-boot-starter-log4j2:3.0.4")
// JPA
implementation("org.springframework.boot:spring-boot-starter-data-jpa:3.0.4")
// QUERY_DSL
implementation("com.querydsl:querydsl-jpa:5.0.0:jakarta")
kapt("com.querydsl:querydsl-apt:5.0.0:jakarta")
kapt("jakarta.annotation:jakarta.annotation-api")
kapt("jakarta.persistence:jakarta.persistence-api")
// DATABASE
runtimeOnly("com.mysql:mysql-connector-j:8.0.32")
runtimeOnly("com.h2database:h2")
// SECURITY
implementation("org.springframework.boot:spring-boot-starter-security:3.0.4")
implementation("org.springframework.security:spring-security-jwt:1.1.1.RELEASE")
implementation("com.sun.xml.bind:jaxb-impl:4.0.1")
implementation("com.sun.xml.bind:jaxb-core:4.0.1")
implementation("javax.xml.bind:jaxb-api:2.4.0-b180830.0359")
implementation("io.jsonwebtoken:jjwt:0.9.1")
testImplementation("org.springframework.security:spring-security-test:6.0.2")
// VALIDATING
implementation("org.springframework.boot:spring-boot-starter-validation:3.0.4")
// JSON PARSING
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-hibernate5:2.13.3")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.glassfish.jaxb:jaxb-runtime:2.3.2")
// TEST
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
testImplementation("io.mockk:mockk:1.9.3")
testImplementation("io.kotest:kotest-runner-junit5-jvm:4.6.0")
// MAPPING
implementation("org.mapstruct:mapstruct:1.5.3.Final")
kapt("org.mapstruct:mapstruct-processor:1.5.3.Final")
kaptTest("org.mapstruct:mapstruct-processor:1.5.3.Final")
// CUSTOM toString & equals & hashCode
implementation("com.github.consoleau:kassava:2.1.0")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
configurations.forEach {
it.exclude(group = "org.springframework.boot", module = "spring-boot-starter-logging")
it.exclude(group = "org.apache.logging.log4j", module = "log4j-to-slf4j")
}
kotlin {
compilerOptions {
freeCompilerArgs.addAll("-Xjsr305=strict")
}
}
kotlin.sourceSets.main {
setBuildDir("$buildDir")
}
idea {
module {
val kaptMain = file("build/generated/source/kapt/main")
sourceDirs.add(kaptMain)
generatedSourceDirs.add(kaptMain)
}
}
allOpen {
annotation("jakarta.persistence.Entity")
annotation("jakarta.persistence.Embeddable")
annotation("jakarta.persistence.MappedSuperclass")
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
tasks.register<Test>("jacocoTest") {
group = "verification"
description = "only jacoco tests"
testClassesDirs = sourceSets["test"].output.classesDirs
classpath = sourceSets["test"].runtimeClasspath
include("**/coverage/**")
}
tasks.register<Test>("restDocsTest") {
group = "verification"
description = "Run tests for the restDocs directory"
testClassesDirs = sourceSets["test"].output.classesDirs
classpath = sourceSets["test"].runtimeClasspath
include("**/com/example/kotlinapiserverguide/restDocs/docs/**")
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
showStandardStreams = true
}
}
tasks {
test {
finalizedBy(jacocoTestReport)
}
jacocoTestReport {
dependsOn("jacocoTest")
executionData(fileTree(buildDir).include("jacoco/*.exec"))
reports {
html.required = true
xml.required = false
csv.required = false
classDirectories.setFrom(
sourceSets.main.get().output.asFileTree.matching {
exclude("**/dto/*", "**/entity/*", "**/common/filter/*")
}
)
}
}
val snippetsDir by extra { file("build/generated-snippets") }
val generateDocs by registering {
group = "documentation"
dependsOn("restDocsTest")
finalizedBy(asciidoctor)
}
asciidoctor {
outputs.dir(snippetsDir)
doFirst {
delete(file("src/main/resources/static/docs"))
}
inputs.dir(snippetsDir)
doLast {
copy {
from("build/docs/asciidoc")
into("src/main/resources/static/docs")
}
} }
build {
dependsOn(asciidoctor)
}
bootJar {
dependsOn(asciidoctor)
}
}
gradle.startParameter.isParallelProjectExecutionEnabled = trueDirectory Structure
- docs - asciidoc κ²°κ³Όλ¬Ό (build μμλ§ μ¬μ©νκ³ μ¬μ©λμ§ μμ.)
- main
- kotlin
- api - κ° λλ©μΈλ³λ‘ λΆλ₯
- common - λλ©μΈκ³Ό 무κ΄ν μ€μ λͺ¨μ
- application - μ΄ν리μΌμ΄μ μ€μ
- cache - μΌμ κ΄λ¦¬ (redis)
- encrypt - μ볡νΈν κ΄λ¦¬
- exception - μλ¬ κ΄λ¦¬
- filter - νν° κ΄λ¦¬ (νμ¬λ loggingλ§ μ²λ¦¬)
- function - 곡ν΅μΌλ‘ μ¬μ©νλ top level function μ μ
- http - μμ² μλ΅ κ°μ²΄ κ΄λ¦¬
- interface - κ³΅ν΅ μΈν°νμ΄μ€ κ΄λ¦¬
- jpa - jpa κ΄λ ¨ μ€μ κ΄λ¦¬
- paging - νμ΄μ§ κ°μ²΄ κ΄λ¦¬
- security - 보μ κ΄λ¦¬
- util - κ³΅ν΅ function λλ Bean κ΄λ¦¬
- resources
- sql - DB κ΄λ¦¬ (h2 μ¬μ© λ° νμ€ν 리 κ΄λ¦¬ μ©λ)
- static - docs html λ³ν κ²°κ³Όλ¬Ό μ μ₯
- application.yaml - μ΄ν리μΌμ΄μ κ³΅ν΅ μ€μ
- application-{profile}.yaml - νλ‘νμΌμ ν΄λΉνλ μ΄ν리μΌμ΄μ μ€μ
- log4j2.xml - λ‘κ·Έ μ€μ
- kotlin
- test - ν
μ€νΈ λͺ¨μ
- restDocs - rest api document μμ± Test λͺ¨μ.
- serviceTest - coverage Test λͺ¨μ.
Tree
.
βββ docs
βΒ Β βββ asciidoc
βββ main
βΒ Β βββ kotlin
βΒ Β βΒ Β βββ com
βΒ Β βΒ Β βββ example
βΒ Β βΒ Β βββ kotlinapiserverguide
βΒ Β βΒ Β βββ api
βΒ Β βΒ Β βΒ Β βββ member
βΒ Β βΒ Β βΒ Β βΒ Β βββ controller
βΒ Β βΒ Β βΒ Β βΒ Β βββ domain
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ dto
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ entity
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ mapper
βΒ Β βΒ Β βΒ Β βΒ Β βββ repository
βΒ Β βΒ Β βΒ Β βΒ Β βββ service
βΒ Β βΒ Β βΒ Β βββ user
βΒ Β βΒ Β βΒ Β βββ controller
βΒ Β βΒ Β βΒ Β βββ domain
βΒ Β βΒ Β βΒ Β βΒ Β βββ dto
βΒ Β βΒ Β βΒ Β βΒ Β βββ mapper
βΒ Β βΒ Β βΒ Β βββ service
βΒ Β βΒ Β βββ common
βΒ Β βΒ Β βββ application
βΒ Β βΒ Β βββ cache
βΒ Β βΒ Β βββ encrypt
βΒ Β βΒ Β βΒ Β βββ annotation
βΒ Β βΒ Β βββ exception
βΒ Β βΒ Β βΒ Β βββ controller
βΒ Β βΒ Β βββ filter
βΒ Β βΒ Β βΒ Β βββ domain
βΒ Β βΒ Β βββ function
βΒ Β βΒ Β βββ http
βΒ Β βΒ Β βΒ Β βββ constant
βΒ Β βΒ Β βΒ Β βββ domain
βΒ Β βΒ Β βββ interfaces
βΒ Β βΒ Β βββ jpa
βΒ Β βΒ Β βΒ Β βββ entity
βΒ Β βΒ Β βΒ Β βββ querydsl
βΒ Β βΒ Β βββ paging
βΒ Β βΒ Β βΒ Β βββ annotation
βΒ Β βΒ Β βΒ Β βββ dto
βΒ Β βΒ Β βββ security
βΒ Β βΒ Β βΒ Β βββ config
βΒ Β βΒ Β βΒ Β βββ constant
βΒ Β βΒ Β βΒ Β βββ provider
βΒ Β βΒ Β βββ util
βΒ Β βββ resources
βΒ Β βββ sql
βΒ Β βββ static
βΒ Β βββ docs
βββ test
βββ kotlin
βΒ Β βββ com
βΒ Β βββ example
βΒ Β βββ kotlinapiserverguide
βΒ Β βββ restDocs
βΒ Β βΒ Β βββ constant
βΒ Β βΒ Β βΒ Β βββ parser
βΒ Β βΒ Β βββ docs
βΒ Β βΒ Β βΒ Β βββ base
βΒ Β βΒ Β βββ infix
βΒ Β βΒ Β βββ util
βΒ Β βββ serviceTest
βΒ Β βββ member
βΒ Β βΒ Β βββ coverage
βΒ Β βΒ Β βββ memberService
βΒ Β βββ user
βΒ Β βββ coverage
βΒ Β βββ userService
βββ resources
βββ org
βββ springframework
βββ restdocs
βββ templates