AdonisJS 6 Principles
TypeScript-first
- Every request, service, and model is typed. Prefer explicit types over any.
1. Thin Controllers, Focused Services
Controllers orchestrate. Business logic lives in services or domain modules.
// app/controllers/users_controller.ts
import
type
{
HttpContext
}
from
"@adonisjs/core/http"
;
import
CreateUserService
from
"#services/users/create_user_service"
;
export
default
class
UsersController
{
async
store
(
{
request
,
response
}
:
HttpContext
)
{
const
payload
=
await
request
.
validateUsing
(
CreateUserService
.
validator
)
;
const
user
=
await
new
CreateUserService
(
)
.
handle
(
payload
)
;
return
response
.
created
(
{
data
:
user
}
)
;
}
}
2. Validate Every Input with VineJS
Never trust request data. Validate on entry.
// app/validators/create_user.ts
import
vine
from
"@vinejs/vine"
;
export
const
createUserValidator
=
vine
.
compile
(
vine
.
object
(
{
email
:
vine
.
string
(
)
.
email
(
)
,
fullName
:
vine
.
string
(
)
.
minLength
(
2
)
.
maxLength
(
120
)
,
password
:
vine
.
string
(
)
.
minLength
(
8
)
,
}
)
,
)
;
3. Lucid Models Own Persistence
Use models for persistence and relationships. Keep queries in one place.
// app/models/user.ts
import
{
BaseModel
,
column
}
from
"@adonisjs/lucid/orm"
;
export
default
class
User
extends
BaseModel
{
@
column
(
{
isPrimary
:
true
}
)
declare
id
:
number
;
@
column
(
)
declare
email
:
string
;
}
4. Middleware for Cross-Cutting Concerns
Authentication, tenant scoping, and rate limiting belong in middleware.
// app/middleware/auth_middleware.ts
import
type
{
HttpContext
}
from
"@adonisjs/core/http"
;
import
type
{
NextFn
}
from
"@adonisjs/core/types/http"
;
export
default
class
AuthMiddleware
{
async
handle
(
ctx
:
HttpContext
,
next
:
NextFn
)
{
await
ctx
.
auth
.
check
(
)
;
return
next
(
)
;
}
}
Build a new feature/endpoint
Debug an existing issue
Write/run tests
Optimize performance
Refactor code
Something else
Then read the matching workflow from
workflows/
and follow it.
After Every Change
1. Type check
pnpm
typecheck
2. Run tests
node
ace
test
tests/functional/changed.spec.ts
3. Lint
pnpm
lint
Report: "Types: OK | Tests: X pass | Lint: clean"
Domain Knowledge
All in
references/
:
Architecture:
architecture.md
Models:
models.md
Controllers:
controllers.md
Serialization (DTOs):
serialization.md
Validations:
validations-callbacks.md
Background Jobs:
background-jobs.md
Performance:
performance.md
Testing:
testing.md
Multi-Tenant:
multi-tenant.md
Anti-Patterns:
anti-patterns.md
Workflows
All in
workflows/
:
File
Purpose
build-feature.md
Create new feature/endpoint from scratch
debug.md
Find and fix bugs
write-tests.md
Write and run tests
optimize-performance.md
Profile and speed up
refactor.md
Restructure code following patterns