Lewati ke konten

Penanganan Request

Referensi: Dokumentasi API Request Deno

Deserve menyediakan objek Context yang membungkus Request native, jadi query, route param, header, cookie, dan body semua lewat Context tanpa parsing manual. Untuk permukaan Context lengkap, termasuk helper response dan penanganan error, lihat Objek Context.

Sebuah handler menerima satu Context dan membaca apa pun yang dibutuhkannya dari namespace ctx.get:

typescript
import type { 
Context
} from '@neabyte/deserve'
// Baca data request dari ctx.get export function
GET
(
ctx
:
Context
): Response {
const
query
=
ctx
.
get
.
query
()
return
ctx
.
send
.
json
({
query
})
}

Bagian di bawah membahas tiap jenis input. Setiap pembaca berada di ctx.get dan didokumentasikan lengkap di Objek Context.

Parameter Query

Query string diurai saat akses pertama, lalu di-cache. ctx.get.query() mengembalikan record lengkap, dan ctx.get.query(key) mengembalikan satu nilai. Nilai pertama menang untuk kunci ganda:

typescript
// URL: /search?q=deno&limit=10
export function 
GET
(
ctx
:
Context
): Response {
const
query
=
ctx
.
get
.
query
()
return
ctx
.
send
.
json
({
search
:
query
.
q
,
limit
:
parseInt
(
query
.
limit
|| '10')
}) }

Ketika sebuah kunci berulang di URL, nilai pertama yang disimpan:

typescript
// URL: /search?tag=deno&tag=typescript
ctx
.
get
.
query
('tag') // 'deno', nilai pertama menang
ctx
.
get
.
query
() // { tag: 'deno' }

Parameter Rute

Segmen dinamis dari routing berbasis file tiba sebagai route param, dibaca satu per satu dengan ctx.get.param(key) atau sekaligus dengan ctx.get.param():

typescript
// routes/users/[id]/posts/[postId].ts
// URL: /users/123/posts/456
export function 
GET
(
ctx
:
Context
): Response {
const
id
=
ctx
.
get
.
param
('id') // '123'
const
all
=
ctx
.
get
.
param
() // { id: '123', postId: '456' }
return
ctx
.
send
.
json
({
id
,
all
})
}

Nilai di-percent-decode sekali sebelum handler membacanya. Cara pola dicocokkan dibahas di Pola Rute.

Header dibaca lewat ctx.get.header(). Beri sebuah kunci untuk membaca satu header, atau panggil tanpa argumen untuk membaca semua header sebagai record. Kunci dicocokkan tanpa membedakan huruf besar kecil:

typescript
// Baca satu header berdasarkan nama
const 
contentType
=
ctx
.
get
.
header
('content-type')
// Baca semua header sebagai record const
headers
=
ctx
.
get
.
header
()

Untuk akses langsung ke objek Headers native, pakai ctx.get.request().headers:

typescript
// Akses Headers API mentah
const 
contentType
=
ctx
.
get
.
request
().
headers
.
get
('Content-Type')

Cookie dibaca lewat ctx.get.cookie(). Beri sebuah kunci untuk membaca satu cookie, atau panggil tanpa argumen untuk membaca semua cookie sebagai record. Cookie diurai sekali lalu di-cache untuk panggilan berikutnya:

typescript
// Baca satu cookie berdasarkan nama
const 
sessionId
=
ctx
.
get
.
cookie
('sessionId')
// Baca semua cookie sebagai record const
cookies
=
ctx
.
get
.
cookie
() // { sessionId: 'abc123', theme: 'dark' }

Body

Body dibaca lewat salah satu dari beberapa method async di ctx.get. Formatnya dipilih otomatis oleh ctx.get.body() berdasarkan header Content-Type, atau dipaksa dengan memanggil pembaca tertentu:

MethodFormatContent-Type
ctx.get.body()Deteksi otomatisJSON, form-data, atau teks
ctx.get.json()JSONApa saja
ctx.get.text()Teks polosApa saja
ctx.get.formData()Form dataApa saja
ctx.get.blob()BlobApa saja
ctx.get.bytes()Uint8ArrayApa saja

Body hanya bisa dibaca sekali. Panggilan kedua dengan format sama mengembalikan nilai dari cache, sedangkan panggilan kedua dengan format berbeda melempar 409 Conflict.

Body Deteksi Otomatis

typescript
// POST /api/users dengan body JSON
export async function 
POST
(
ctx
:
Context
):
Promise
<Response> {
// Body diparsing dari Content-Type const
body
= await
ctx
.
get
.
body
()
return
ctx
.
send
.
json
({
created
:
body
})
}

Body JSON

typescript
// POST /api/users dengan body JSON
export async function 
POST
(
ctx
:
Context
):
Promise
<Response> {
// Parsing body sebagai JSON const
body
= await
ctx
.
get
.
json
()
return
ctx
.
send
.
json
({
created
:
body
})
}

Form Data

typescript
// POST /api/users dengan form data
export async function 
POST
(
ctx
:
Context
):
Promise
<Response> {
// Parsing body sebagai form data const
formData
= await
ctx
.
get
.
formData
()
const
name
=
formData
.
get
('name')
return
ctx
.
send
.
json
({
name
})
}

Teks Mentah

typescript
// POST /api/text dengan teks polos
export async function 
POST
(
ctx
:
Context
):
Promise
<Response> {
// Baca body sebagai teks polos const
text
= await
ctx
.
get
.
text
()
return
ctx
.
send
.
text
(
text
)
}

Data Biner

typescript
// POST /api/upload dengan data biner
export async function 
POST
(
ctx
:
Context
):
Promise
<Response> {
// Baca body sebagai byte array const
bytes
= await
ctx
.
get
.
bytes
()
return
ctx
.
send
.
json
({
size
:
bytes
.
byteLength
})
}

URL dan Pathname

Detail URL dibaca lewat ctx.get.url() dan ctx.get.pathname():

typescript
export function 
GET
(
ctx
:
Context
): Response {
const
url
=
ctx
.
get
.
url
() // URL instance
const
pathname
=
ctx
.
get
.
pathname
() // '/api/users/123'
return
ctx
.
send
.
json
({
path
:
pathname
,
fullUrl
:
url
.
href
}) }

IP Klien

IP klien dibaca lewat ctx.get.ip(). Beri { direct: true } untuk membaca peer TCP langsung alih-alih IP yang sudah diresolusi:

typescript
export function 
GET
(
ctx
:
Context
): Response {
const
client
=
ctx
.
get
.
ip
() // IP pengunjung yang diresolusi
const
peer
=
ctx
.
get
.
ip
({
direct
: true }) // peer TCP langsung
return
ctx
.
send
.
json
({
client
,
peer
})
}

Keduanya mengembalikan undefined ketika peer tidak diketahui. Tanpa aturan trustProxy yang cocok, keduanya mengembalikan alamat peer langsung yang sama. Middleware pembatasan IP memakai ctx.get.ip() untuk aturan allow dan deny-nya.

Memvalidasi Sebelum Handler

Setiap pembaca di atas mengembalikan nilai mentah seperti saat tiba, jadi handler tetap memeriksa bentuknya sendiri. Sebuah schema memindahkan pemeriksaan itu ke depan handler, menjalankan kontrak terhadap tiap sumber, dan menyisakan hanya data yang sudah lolos. Lihat Ringkasan Validasi untuk bagaimana ctx.get.json(), ctx.get.query(), dan pembaca lain mengisi sebuah kontrak.

Dirilis di bawah Lisensi MIT.