Skip to content
kotlin-spring-reviewer logo

Kotlin Spring Reviewer Skill

kotlin-spring-reviewer

WHEN: Spring Boot + Kotlin, Ktor backend review, coroutine-based server, WebFlux/R2DBC pattern checks WHAT: Spring Kotlin idioms + Coroutines integration + WebFlux patterns + Data class usage + Test strategies WHEN NOT: Android → kotlin-android-reviewer, KMP shared code → kotlin-multiplatform-rev...

SKILL.md

Full skill instructions

Kotlin Spring Reviewer Skill

Purpose

Reviews Spring Boot + Kotlin and Ktor backend projects for Kotlin idioms, Coroutines integration, WebFlux, and data class best practices.

When to Use

  • Spring Boot + Kotlin project code review
  • Ktor server project review
  • "WebFlux", "R2DBC", "Coroutines server" mentions
  • Projects with spring-boot or ktor in build.gradle.kts

Project Detection

  • org.springframework.boot plugin in build.gradle.kts
  • io.ktor dependency in build.gradle.kts
  • application.yml or application.properties
  • Application.kt main class

Workflow

Step 1: Analyze Project

**Framework**: Spring Boot 3.2.x
**Kotlin**: 1.9.x
**Build Tool**: Gradle (Kotlin DSL)
**Dependencies**:
  - Spring WebFlux (reactive)
  - Spring Data R2DBC
  - Kotlinx Coroutines

Step 2: Select Review Areas

AskUserQuestion:

"Which areas to review?"
Options:
- Full Kotlin Spring pattern check (recommended)
- Kotlin idiom usage
- Coroutines/​WebFlux integration
- Data class/​DTO design
- Test strategies
multiSelect: true

Detection Rules

Kotlin Idioms

CheckRecommendationSeverity
Java-style getter/​setterUse Kotlin propertyLOW
if-based null checkUse ?.let, ?:, avoid !!MEDIUM
if-else chainUse when expressionLOW
Missing extension functionsUtility → extension functionLOW
Missing scope functionsUse apply, let, run, alsoLOW
// BAD: Java style
class User {
    private var name: String? = null
    fun getName(): String? = name
    fun setName(name: String?) { this.name = name }
}

// GOOD: Kotlin property
class User {
    var name: String? = null
}

// BAD: Java-style null check
fun process(user: User?) {
    if (user != null) {
        if (user.name != null) {
            println(user.name)
        }
    }
}

// GOOD: Kotlin null-safe operators
fun process(user: User?) {
    user?.name?.let { println(it) }
}

// BAD: if-else chain
fun getStatus(code: Int): String {
    if (code == 200) return "OK"
    else if (code == 404) return "Not Found"
    else return "Unknown"
}

// GOOD: when expression
fun getStatus(code: Int): String = when (code) {
    200 -> "OK"
    404 -> "Not Found"
    else -> "Unknown"
}

Spring + Kotlin Patterns

CheckRecommendationSeverity
@Autowired field injectionConstructor injectionHIGH
lateinit var abuseConstructor injection or lazyMEDIUM
Missing open classUse all-open pluginHIGH
data class @EntityUse regular classHIGH
// BAD: Field injection
@Service
class UserService {
    @Autowired
    private lateinit var userRepository: UserRepository
}

// GOOD: Constructor injection (Kotlin default)
@Service
class UserService(
    private val userRepository: UserRepository
)

// BAD: data class as JPA Entity
@Entity
data class User(
    @Id val id: Long,
    val name: String
)  // equals/​hashCode issues

// GOOD: Regular class with explicit equals/​hashCode
@Entity
class User(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null,
    var name: String
) {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is User) return false
        return id != null && id == other.id
    }
    override fun hashCode(): Int = javaClass.hashCode()
}

Gradle Plugin Check:

// build.gradle.kts
plugins {
    kotlin("plugin.spring")  // all-open for Spring
    kotlin("plugin.jpa")     // no-arg for JPA entities
}

Coroutines Integration

CheckRecommendationSeverity
runBlocking in controllerUse suspend functionCRITICAL
GlobalScope in serverUse structured concurrencyCRITICAL
Missing DispatcherSpecify IO/​DefaultMEDIUM
Missing exception handlingUse CoroutineExceptionHandlerHIGH
// BAD: runBlocking in controller
@GetMapping("/​users")
fun getUsers(): List<User> = runBlocking {
    userService.getUsers()
}

// GOOD: suspend function (WebFlux/​Coroutines)
@GetMapping("/​users")
suspend fun getUsers(): List<User> =
    userService.getUsers()

// BAD: GlobalScope in service
@Service
class UserService {
    fun processAsync() {
        GlobalScope.launch {
            // Dangerous: Not cancelled on app shutdown
        }
    }
}

// GOOD: Structured concurrency
@Service
class UserService(
    private val applicationScope: CoroutineScope
) {
    fun processAsync() = applicationScope.launch {
        // Properly cancelled on app shutdown
    }
}

WebFlux + Coroutines

CheckRecommendationSeverity
Direct Mono/​Flux usageConvert to suspend/​FlowMEDIUM
awaitSingle abuseUse coRouter DSLLOW
Blocking callUse Dispatchers.IOCRITICAL
// OK: Direct Mono/​Flux
@GetMapping("/​user/​{id}")
fun getUser(@PathVariable id: Long): Mono<User> =
    userRepository.findById(id)

// BETTER: Kotlin Coroutines
@GetMapping("/​user/​{id}")
suspend fun getUser(@PathVariable id: Long): User? =
    userRepository.findById(id).awaitSingleOrNull()

// BEST: coRouter DSL (functional endpoints)
@Configuration
class RouterConfig {
    @Bean
    fun routes(handler: UserHandler) = coRouter {
        "/​api/​users".nest {
            GET("", handler::getAll)
            GET("/​{id}", handler::getById)
            POST("", handler::create)
        }
    }
}

class UserHandler(private val service: UserService) {
    suspend fun getAll(request: ServerRequest): ServerResponse =
        ServerResponse.ok().bodyAndAwait(service.getAll())
}

Ktor Patterns

CheckRecommendationSeverity
Excessive routing nestingSplit into modulesMEDIUM
No DIUse Koin/​KodeinMEDIUM
Missing error handlingUse StatusPages pluginHIGH
Missing serializationUse ContentNegotiationHIGH
// BAD: All routes in one file
fun Application.module() {
    routing {
        get("/​users") { /​* ... */ }
        get("/​users/​{id}") { /​* ... */ }
        get("/​products") { /​* ... */ }
        // ... 100 more
    }
}

// GOOD: Split into modules
fun Application.module() {
    configureRouting()
    configureSerialization()
    configureDI()
}

fun Application.configureRouting() {
    routing {
        userRoutes()
        productRoutes()
    }
}

fun Route.userRoutes() {
    route("/​users") {
        get { /​* ... */ }
        get("/​{id}") { /​* ... */ }
        post { /​* ... */ }
    }
}

Data Class Design

CheckRecommendationSeverity
var in DTOUse val (immutable)MEDIUM
Excessive nullableUse defaults or requiredLOW
Missing validationUse @field:Valid, init {}MEDIUM
// BAD: Mutable DTO
data class CreateUserRequest(
    var name: String?,
    var email: String?
)

// GOOD: Immutable + validation
data class CreateUserRequest(
    @field:NotBlank
    val name: String,

    @field:Email
    val email: String
) {
    init {
        require(name.length <= 100) { "Name too long" }
    }
}

Response Template

## Kotlin Spring Code Review Results

**Project**: [name]
**Spring Boot**: 3.2.x | **Kotlin**: 1.9.x
**Stack**: WebFlux + R2DBC + Coroutines

### Kotlin Idioms
| Status | File | Issue |
|--------|------|-------|
| LOW | UserService.kt | Java-style null check → ?.let recommended |

### Spring Patterns
| Status | File | Issue |
|--------|------|-------|
| HIGH | ProductService.kt | @Autowired field injection → constructor injection |
| HIGH | User.kt | data class @Entity → regular class |

### Coroutines
| Status | File | Issue |
|--------|------|-------|
| CRITICAL | ReportService.kt | runBlocking in controller |
| HIGH | BatchJob.kt | GlobalScope usage |

### Recommended Actions
1. [ ] Verify kotlin-spring, kotlin-jpa plugins
2. [ ] runBlocking → suspend function conversion
3. [ ] GlobalScope → applicationScope injection
4. [ ] data class Entity → regular class change

Best Practices

  1. Constructor Injection: Use default constructor instead of @Autowired
  2. Immutability: val, data class (except Entity)
  3. Coroutines: suspend functions, structured concurrency
  4. Kotlin DSL: coRouter, bean { }
  5. Testing: MockK, Kotest, @SpringBootTest

Integration

  • code-reviewer skill: General code quality
  • kotlin-multiplatform-reviewer skill: KMP server sharing
  • security-scanner skill: API security checks

Notes

  • Based on Spring Boot 3.x + Kotlin 1.9+
  • WebFlux/​R2DBC reactive stack support
  • Ktor 2.x support

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View