Objek Konteks
Objek Context membungkus Request native dan menyediakan method yang nyaman untuk mengakses data request, mengatur response header, dan mengirim response.
Apa Itu Context?
Context adalah wrapper di sekitar objek Request native Deno. Setiap request yang masuk akan dibungkus menjadi satu objek Context yang sama dari middleware hingga route handler. Alih-alih bekerja langsung dengan Request mentah, Anda menggunakan Context yang memberi Anda:
- Lazy parsing - Data di-parse hanya saat Anda mengaksesnya
- Method yang nyaman - API sederhana untuk operasi umum
- Utility response - Method built-in untuk mengirim response
- Manajemen header - Manipulasi response header yang mudah
Mengapa Menggunakan Context?
Context menghindari multiple parsing dan pemrosesan berulang selama lifecycle request. Handler menerima satu objek Context yang bertahan melalui seluruh lifecycle — dari middleware ke route handler.
Membuat Context
Deserve membuat Context secara otomatis saat request datang:
// 1. Import tipe Context
import type { Context } from '@neabyte/deserve'
// 2. Handler menerima ctx (Deserve membuat otomatis per request)
export function GET(ctx: Context): Response {
return ctx.send.json({ message: 'Hello' })
}Struktur Context
Context membungkus beberapa bagian kunci:
- Original Request - Diakses via
ctx.request - Parsed URL - Digunakan internal untuk query params
- Route Parameters - Diekstrak dari dynamic routes
- Response Headers - Diatur sebelum mengirim response
Lazy Parsing
Context menggunakan lazy parsing untuk performa: data (query, body, cookie, header) hanya di-parse saat Anda memanggil method yang menggunakannya, lalu hasilnya di-cache untuk pemanggilan berikutnya.
export function GET(ctx: Context): Response {
// 1. Query belum di-parse sampai ctx.query() dipanggil
const query = ctx.query()
// 2. Hasil di-cache; panggilan berikutnya pakai cache
// 3. Body di-parse pada akses pertama (berdasarkan Content-Type)
const body = await ctx.body()
// 4. Kirim gabungan query + body
return ctx.send.json({ query, body })
}Akses Data Request
Akses data request melalui method Context:
- Query Parameters -
ctx.query(),ctx.queries() - Route Parameters -
ctx.param(),ctx.params() - Headers -
ctx.header(),ctx.headers - Cookies -
ctx.cookie() - Body -
ctx.body(),ctx.json(),ctx.formData(),ctx.text(),ctx.arrayBuffer(),ctx.blob() - Informasi URL -
ctx.url,ctx.pathname
Utility Response
Kirim response menggunakan ctx.send:
ctx.send.json()- Response JSONctx.send.text()- Plain textctx.send.html()- Konten HTMLctx.send.file()- Unduhan filectx.send.data()- Unduhan data in-memoryctx.send.stream()- Response stream (ReadableStream)ctx.send.redirect()- Redirectctx.send.custom()- Response customctx.handleError()- Error handling
Anda juga dapat menggunakan ctx.redirect() secara langsung sebagai method convenience:
export function GET(ctx: Context): Response {
// 1. Redirect 301 ke path baru (shorthand untuk ctx.send.redirect)
return ctx.redirect('/new-location', 301)
}Response Headers
Atur response header sebelum mengirim:
export function GET(ctx: Context): Response {
// 1. Atur header satu per satu
ctx.setHeader('X-Custom', 'value')
ctx.setHeader('Cache-Control', 'no-cache')
// 2. Kirim response (header ikut terkirim)
return ctx.send.json({ data: 'test' })
}Mengatur Banyak Header Sekaligus
Gunakan setHeaders() untuk mengatur multiple headers sekaligus:
export function GET(ctx: Context): Response {
// 1. Atur banyak header sekaligus (object)
ctx.setHeaders({
'X-Custom': 'value',
'Cache-Control': 'no-cache',
'X-Request-ID': 'abc123'
})
return ctx.send.json({ data: 'test' })
}Membaca Header Response
Akses semua response headers yang telah diatur:
export function GET(ctx: Context): Response {
// 1. Set header
ctx.setHeader('X-Custom', 'value')
ctx.setHeader('Cache-Control', 'no-cache')
// 2. Baca map header yang sudah diatur
const headers = ctx.responseHeadersMap
return ctx.send.json({ data: 'test' })
}URL Dan Pathname
Dapatkan informasi URL langsung:
ctx.url- String URL lengkapctx.pathname- Bagian pathname dari URL (contoh:/api/users/123)
export function GET(ctx: Context): Response {
// 1. URL lengkap (termasuk query string)
const fullUrl = ctx.url
// 2. Hanya pathname (tanpa origin + query)
const path = ctx.pathname
return ctx.send.json({ path, fullUrl })
}Penanganan Error
Tangani error secara konsisten menggunakan ctx.handleError():
export function GET(ctx: Context): Response {
try {
// 1. Cek auth; jika gagal, trigger error handler (router.catch atau default)
if (!isAuthorized) {
return ctx.handleError(401, new Error('Unauthorized'))
}
return ctx.send.json({ data: 'success' })
} catch (error) {
// 2. Tangkap error lain → kirim ke error handler
return ctx.handleError(500, error as Error)
}
}Cara Kerja handleError
ctx.handleError() menghormati error handler global yang diatur dengan router.catch():
- Jika
router.catch()didefinisikan - Menggunakan error handler kustom Anda - Jika tidak ada error handler - Mengembalikan response sederhana dengan status code
Penggunaan Di Middleware
Middleware dapat menggunakan ctx.handleError() untuk memicu error handling:
// 1. Di middleware, validasi request
router.use(async (ctx, next) => {
if (!isValid) {
// 2. Trigger error handling (router.catch dipanggil jika ada)
return ctx.handleError(401, new Error('Unauthorized'))
}
return await next()
})Lifecycle Context
- Request datang - Deserve membuat Context dengan Request dan URL
- Route matching - Route parameters diekstrak dan ditambahkan ke Context
- Eksekusi middleware - Context dilewatkan melalui middleware chain
- Route handler - Handler Anda menerima Context
- Response dikirim - Method Context digunakan untuk membangun Response