关于 kotlin-patterns
kotlin-patterns 是面向 Orca 项目的 Kotlin 编码模式参考,适用于编写服务端应用的开发者。内容涵盖实体、服务、仓库、控制器、API、DTO、异常处理与空安全规范。
主要功能
- 01实体与 DTO 模式
- 02服务与仓库模式
- 03控制器和 API 接口模式
- 04类型化异常处理模式
- 05Kotlin 空安全规范
适用场景
- 01按项目模式新增实体接口
- 02实现服务及仓库逻辑
- 03统一处理校验与异常
- 04编写空安全的 Kotlin 代码
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ ashchupliak/ dream-team --skill kotlin-patterns安装后在 Claude Code 中输入/kotlin-patterns确认已加载。
详细介绍
Orca 的 Kotlin 模式
实体模式
data class EntityName(
val id: UUID,
val name: String,
val createdAt: Instant,
val updatedAt: Instant?
)
服务模式
@Service
class EntityNameService(
private val repository: EntityNameRepository,
private val relatedService: RelatedService
) {
@Transactional(propagation = Propagation.NEVER)
fun create(request: CreateRequest): Pair<EntityResponse, Boolean> {
// Check exists, validate, create
// Return Pair for idempotent operations
}
fun findById(id: UUID): EntityName? =
repository.findById(id)
fun findAll(): List<EntityName> =
repository.findAll()
}
仓库模式(JOOQ)
@Repository
class EntityNameRepository(
private val dsl: DSLContext
) {
fun findById(id: UUID): EntityName? =
dsl.selectFrom(ENTITY_NAME)
.where(ENTITY_NAME.ID.eq(id))
.fetchOne()
?.toEntity()
fun findAll(): List<EntityName> =
dsl.selectFrom(ENTITY_NAME)
.fetch()
.map { it.toEntity() }
fun save(entity: EntityName): EntityName =
dsl.insertInto(ENTITY_NAME)
.set(ENTITY_NAME.ID, entity.id)
.set(ENTITY_NAME.NAME, entity.name)
.set(ENTITY_NAME.CREATED_AT, entity.createdAt)
.returning()
.fetchOne()!!
.toEntity()
private fun EntityNameRecord.toEntity() = EntityName(
id = id,
name = name,
createdAt = createdAt,
updatedAt = updatedAt
)
}
控制器模式
@RestController
class EntityNameController(
private val service: EntityNameService
) : EntityNameApi {
override fun create(request: CreateRequest): ResponseEntity<EntityResponse> {
val (result, isNew) = service.create(request)
return if (isNew) ResponseEntity.status(201).body(result)
else ResponseEntity.ok(result)
}
override fun getById(id: UUID): ResponseEntity<EntityResponse> {
val entity = service.findById(id)
?: throw ResourceNotFoundRestException("EntityName", id)
return ResponseEntity.ok(entity.toResponse())
}
}
API 接口模式
@Tag(name = "Entity Name")
interface EntityNameApi {
@Operation(summary = "Create entity")
@PostMapping("/api/v1/entities")
fun create(@RequestBody @Valid request: CreateRequest): ResponseEntity<EntityResponse>
@Operation(summary = "Get entity by ID")
@GetMapping("/api/v1/entities/{id}")
fun getById(@PathVariable id: UUID): ResponseEntity<EntityResponse>
}
DTO 模式
data class CreateRequest(
@field:NotBlank
val name: String,
@field:Size(max = 255)
val description: String?
)
data class EntityResponse(
val id: UUID,
val name: String,
val description: String?,
val createdAt: Instant
)
异常模式
// Use typed exceptions
throw ResourceNotFoundRestException("EntityName", id)
throw ValidationRestException("Name cannot be empty")
throw ConflictRestException("Entity already exists")
空安全指南
- 对可选操作使用
?.let{} - 使用
when进行穷尽匹配 - 避免使用
!!,改用.single()、.firstOrNull() - 对幂等操作返回
Pair<Result, Boolean>
评论
支持 Markdown