CRUD
Native CRUD resources with named routes, guards, and OpenAPI.
@velajs/crud (>= 1.18) is Vela's native CRUD engine. @Crud() stamps real
controller routes — named routes (urlFor), guards, pipes, interceptors, and
OpenAPI all flow through Vela's ordinary pipeline. Data access goes through a
pluggable adapter (@velajs/crud-memory for tests and prototypes,
@velajs/crud-drizzle for SQL).
Installation
npm install @velajs/crud @velajs/crud-memoryDefine a model, decorate a controller
import { z } from 'zod';
import { Controller } from '@velajs/vela';
import { Crud, defineModel } from '@velajs/crud';
import { memoryAdapter } from '@velajs/crud-memory';
const Spirit = defineModel({
name: 'spirit',
tableName: 'spirits',
schema: z.object({
id: z.uuid(),
name: z.string().min(1),
element: z.enum(['wind', 'water', 'ember']),
createdAt: z.number().optional(),
updatedAt: z.number().optional(),
deletedAt: z.number().nullable().optional(),
}),
softDelete: true,
});
@Controller('/spirits')
@Crud({
model: Spirit,
adapter: memoryAdapter({ tableName: 'spirits', softDeleteField: 'deletedAt' }),
})
class SpiritsController {}This generates (among others — 22 verbs are available):
| Method | Path | Route name | Operation |
|---|---|---|---|
| POST | /spirits | spirit.create | Create |
| GET | /spirits | spirit.list | List |
| GET | /spirits/:id | spirit.read | Read |
| PATCH | /spirits/:id | spirit.update | Update |
| DELETE | /spirits/:id | spirit.delete | Delete |
| POST | /spirits/:id/restore | spirit.restore | Restore |
| POST | /spirits/upsert | spirit.upsert | Upsert |
Route names feed UrlGeneratorService.urlFor, vela route list, and stable
OpenAPI operationIds (createSpirit, listSpirits, ...). Request bodies are
validated against DTOs derived from the model schema; responses use the
canonical envelope ({ success, result[, result_info] }).
Headless resources with CrudModule
No controller class needed — mount resources from a module:
import { Module } from '@velajs/vela';
import { CrudModule } from '@velajs/crud';
import { drizzleAdapter } from '@velajs/crud-drizzle';
@Module({
imports: [
CrudModule.forRoot({
adapter: drizzleAdapter({ db, dialect: 'sqlite', table: spirits }),
}),
CrudModule.forFeature([
{ path: '/spirits', model: Spirit },
{ path: '/shrines', model: Shrine, only: ['create', 'list', 'read'] },
]),
],
})
class AppModule {}forRoot provides the app-wide default adapter (and optional
versioningStore/auditStore); each forFeature resource may override it.
Overrides
Override providers, guards, pipes, interceptors, and filters in tests.
Configuration
Configure verbs, filtering, hooks, tenancy, and guards.
Last updated on