From ai-toolkit
Designs RPC-style APIs with layered architecture (Controller → Manager → Repository). Use when creating new API endpoints, designing contracts, or reviewing patterns.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ai-toolkit:backend-api-designThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
```
GET /api/v1/employees # List (plural)
GET /api/v1/employee # Get one (?id=xxx)
POST /api/v1/employee # Create
POST /api/v1/employee/update # Update (?id=xxx)
POST /api/v1/employee/delete # Soft delete (?id=xxx)
POST /api/v1/employee/restore # Restore (?id=xxx)
POST /api/v1/sync/employees # Action
@QueryValue, never @PathVariable/employee not /employees/{id}/employees/delete, /restore, /syncController → thin, just delegates
↓
Manager → business logic, transactions, Either returns
↓
Repository → data access only, no business logic
.throwOrValue()Either<ClientException, T>transaction(db.primary) { }db.replica for reads, db.primary for writesdeletedAt.isNull()The core controller delegation pattern:
@Get("/employee")
suspend fun getEmployee(@QueryValue id: UUID): EmployeeResponse {
return employeeManager.findById(id).throwOrValue()
}
companion object { fun from(entity) } in module-client/response/{domain}/EmployeeListResponse with items, total, page, limit, hasMoreClientError.NOT_FOUND.asException().left() from managers, never throw@Factory class with @Singleton method, wire repos + db into managerSee code-patterns.md for complete controller, response model, pagination, error handling, and factory bean templates.
@QueryValue params MUST have explicit snake_case names. The frontend axios interceptor sends project_id but Micronaut matches the literal param name. Write @QueryValue("project_id") projectId: UUID, not bare @QueryValue projectId: UUID.@Put, @Delete, or @Patch. This is RPC-style — all mutations are @Post. The only @Get is for reads.private val fooRepository: FooRepository in a controller, move it to the manager.andWhere {} not second .where {}. Calling .where {} twice replaces the first condition. Use .andWhere {} to chain.@ExecuteOn(TaskExecutors.IO). Without it, suspend functions may hang or run on the wrong thread pool. Every controller needs it.npx claudepluginhub c0x12c/ai-toolkit --plugin ai-toolkitCreates RPC-style API endpoints following layered architecture (Controller → Manager → Repository), including request/response models, controllers, and Retrofit clients for Kotlin/Micronaut backends. Use for new CRUD operations.
Establishes REST API design patterns for resource naming, HTTP methods and status codes, pagination, filtering, error responses, versioning, and rate limiting for production APIs.
Guides RESTful API design and implementation: resource naming, HTTP methods, URL patterns, error responses, versioning, and core principles.