Menguasai validasi request di ElysiaJS menggunakan TypeBox: mendefinisikan object, string, number, array, nested objects, optional fields, default values, serta custom error handling untuk response yang informatif.

Setelah di episode 5 kita memahami object context dan berbagai jenis response, pada episode ini kita akan mendalami validasi — lapisan pertahanan pertama melawan input yang tidak valid atau berbahaya. ElysiaJS menggunakan TypeBox sebagai fondasi schema validation, yang menghasilkan JSON Schema dari definisi tipe TypeScript.
Tanpa validasi, aplikasi rentan terhadap:
Schema validation memastikan setiap request memenuhi kontrak yang didefinisikan sebelum diproses oleh handler.
TypeBox menyediakan fungsi-fungsi untuk mendefinisikan tipe secara deklaratif:
import { Type as t } from '@sinclair/typebox'
// Primitive types
t.String() // string
t.Number() // number
t.Boolean() // boolean
t.Null() // null
t.Undefined() // undefined
// Complex types
t.Array(t.String()) // string[]
t.Object({ name: t.String() }) // { name: string }const userSchema = t.Object({
name: t.String({ minLength: 1, maxLength: 100 }),
email: t.String({ format: 'email' }),
age: t.Optional(t.Number({ minimum: 0, maximum: 150 })),
tags: t.Array(t.String()),
address: t.Optional(t.Object({
street: t.String(),
city: t.String(),
zip: t.String(),
})),
})Optional menandai field yang tidak wajib dikirim. Jika client tidak mengirim field ini, validasi tetap lolos.
const paginationSchema = t.Object({
page: t.Default(t.Numeric(), 1),
limit: t.Default(t.Numeric(), 20),
sort: t.Default(t.String(), 'created_at'),
})Integrasikan schema langsung di route options untuk validasi otomatis:
import { Elysia, t } from 'elysia'
const app = new Elysia()
.post('/user', ({ body }) => {
return {
id: 1,
name: body.name,
email: body.email,
}
}, {
body: t.Object({
name: t.String({ minLength: 1 }),
email: t.String({ format: 'email' }),
age: t.Optional(t.Number({ minimum: 18 })),
}),
response: t.Object({
id: t.Number(),
name: t.String(),
email: t.String(),
}),
})
.listen(3000)Schema body memvalidasi request body, dan schema response mendefinisikan tipe response — keduanya otomatis terekspos ke Eden Treaty.
Jika request tidak valid, ElysiaJS secara otomatis mengembalikan 422 Unprocessable Entity dengan detail error:
{
"type": "validation",
"on": "body",
"message": "Expected string, found number",
"expected": { "type": "string" },
"found": 42
}Untuk custom error handling, gunakan app.onError():
app.onError(({ code, error }) => {
if (code === 'VALIDATION') {
return new Response(
JSON.stringify({ error: 'Invalid input', details: error }),
{ status: 422, headers: { 'Content-Type': 'application/json' } }
)
}
})Tip
Selalu validasi semua input — body, query, dan params. Jangan pernah mempercayai data dari client tanpa validasi, bahkan jika client adalah SPA yang kalian buat sendiri. Validation di server adalah satu-satunya pertahanan yang benar-benar bisa diandalkan.
Pada episode 6 ini, kalian telah menguasai schema validation dengan TypeBox — dari tipe dasar hingga nested objects, optional fields, dan custom error handling.
Inti yang harus dibawa pulang:
t.String(), t.Number(), t.Boolean(), t.Array(), t.Object().t.Optional() untuk field yang tidak wajib, t.Default() untuk default values.app.onError().Di episode 7 selanjutnya kita akan memahami plugin system dan middleware — bagaimana membuat plugin custom, lifecycle hooks, dan menggunakan plugin dari ekosistem seperti CORS, JWT, dan Swagger. Sampai jumpa di episode 7!