Ktor Jimmer Rest¶
A concise RESTful API toolkit built on Ktor and Jimmer.
Tired of writing the same CRUD boilerplate over and over? Try this! Quick Start
Features¶
- Full CRUD from a single
api<T>block — registers query/create/update/delete routes pluscount/exists, with opt-inPATCHand batch endpoints - Declarative filtering & sorting — reuse Jimmer's Kotlin query DSL;
eq?,in?,lt?/gt?,ilike?,between?map parameters automatically,sort()for dynamic ordering - Configurable writes — independent
create {}/edit {}/patch {}blocks for save mode and response projection - Flexible projection — pick a
FetcherDSL or a generatedViewDTO - Input & validation — entity or Jimmer
InputDTO, with a built-in validation DSL and transformers - Batch operations —
batch {}enables batch create / update / delete - Custom actions — register arbitrary routes inside
api<T>withaction {} - Unified errors —
ApiErrorenvelope + one-linejimmerRestErrors() - Customizable parsing & paging — register parsers for your own types, configure defaults and custom page objects
- Plug & play — everything is configured through the
JimmerRestKtor plugin
Before
routing {
route("/book") {
get("/{id}") {
val id = call.defaultPathVariable.parse(entityIdType<Book>())
val book = sqlClient.findById(Book::class, id)
call.respond(book)
}
get {
// ...manually assemble filters, sorting, paging and error handling
}
post { /* receive, validate, transform, save */ }
put { /* receive, validate, transform, update */ }
delete("/{id}") { /* parse id, delete */ }
}
}
After
routing {
api<Book>("/book") {
filter {
where(
`ilike?`(table.name),
`between?`(table.price)
)
where(Book::authors) { // association filtering (EXISTS)
`ilike?`(table.firstName)
}
orderBy(table.id.desc())
}
fetcher {
fetch.by {
allScalarFields()
store { name(); website() }
}
}
input {
validator {
with(it) {
::name.notBlank { "name must not be blank" }
}
}
}
}
}
Documentation¶
- Quick Start
- Data Preparation (简体中文)