Skip to content

2. Guía de desarrollo

Arturo Lopez edited this page Apr 8, 2026 · 2 revisions

Prerrequisitos:

JDK 21, Gradle 8.x, IntelliJ IDEA.

Ejecución:

  • ./gradlew bootRun
  • Swagger UI: /swagger-ui.html
  • OpenAPI: /api-docs
  • H2 Console: /h2-console (solo dev)

Convenciones:

  • Organización de imports y KDoc.
  • Naming: PingController, PingService, PingResponse. Sin PingUseCase ni PingMapper.
  • Inyección por constructor.
  • Kotlin idioms:
    • data classes para DTO y modelos de dominio.
    • val sobre var.
    • null-safety.
    • extension functions.

Cómo agregar una funcionalidad (ejemplo Users):

Dentro de features/users/ crea estos archivos en orden:

  1. Modelo de dominio: User.kt (data class puro, sin dependencias de Spring)
  2. Entidad JPA: UserEntity.kt con anotaciones @Entity
  3. Repositorio: UserRepository.kt que extiende JpaRepository
  4. Service: UserService.kt con @Service, orquesta el repositorio
  5. DTOs: dto/UserResponse.kt con companion object fromDomain(), dto/CreateUserRequest.kt
  6. Controller: UserController.kt con @RestController, delega al service
  7. Tests: unit del service (sin Spring), integración del controller con @WebMvcTest

Regla de oro: máximo 2 niveles de anidación dentro de una feature. users/dto/ es el límite.

Patrón de mapeo — companion object en el DTO:

data class UserResponse(
    val id: Long,
    val username: String,
    val email: String,
    val createdAt: LocalDateTime
) {
    companion object {
        fun fromDomain(user: User) = UserResponse(
            id = requireNotNull(user.id),
            username = user.username,
            email = user.email,
            createdAt = user.createdAt
        )
    }
}

Excepciones de dominio:

Las excepciones específicas de una feature viven en features/<feature>/exceptions/. El manejo global está en common/exception/GlobalExceptionHandler.kt.

// features/users/exceptions/DuplicateEmailException.kt
class DuplicateEmailException(email: String) :
    RuntimeException("El email '$email' ya está registrado")

Clone this wiki locally