Kerangka middleware untuk server HTTP asli Deno, Deno Deploy, node.js 16.5 dan kemudian, pekerja cloudflare dan roti. Ini juga termasuk router middleware.
Kerangka middleware ini terinspirasi oleh router KOA dan middleware yang terinspirasi oleh @koa/router.
Readme ini berfokus pada mekanisme Oak API dan ditujukan untuk mereka yang akrab dengan kerangka middleware JavaScript seperti Express dan KOA serta pemahaman yang layak tentang Deno. Jika Anda tidak terbiasa dengan ini, silakan lihat dokumentasi di oakserver.github.io/oak.
Juga, lihat FAQ kami dan situs sumber daya komunitas yang mengagumkan.
Catatan
Contoh -contoh dalam tarikan readme ini dari main dan dirancang untuk Deno Cli atau Deno Deploy, yang mungkin tidak masuk akal untuk dilakukan ketika Anda ingin benar -benar menggunakan beban kerja. Anda ingin "pin" ke versi tertentu yang kompatibel dengan versi Deno yang Anda gunakan dan memiliki satu set API tetap yang Anda harapkan. https://deno.land/x/ mendukung menggunakan tag git di URL untuk mengarahkan Anda pada versi tertentu. Jadi untuk menggunakan versi 13.0.0 dari Oak, Anda ingin mengimpor https://deno.land/x/[email protected]/mod.ts .
Oak tersedia di Deno.land/x dan JSR. Untuk digunakan dari deno.land/x , impor ke modul:
import { Application } from "https://deno.land/x/oak/mod.ts" ;Untuk digunakan dari JSR, impor ke modul:
import { Application } from "jsr:@oak/oak@14" ;Oak tersedia untuk Node.js di NPM dan JSR. Untuk digunakan dari NPM, instal paket:
npm i @oakserver/oak@14
Dan kemudian mengimpor ke modul:
import { Application } from "@oakserver/oak" ;Untuk digunakan dari JSR, instal paket:
npx jsr i @oak/oak@14
Dan kemudian mengimpor ke modul:
import { Application } from "@oak/oak/application" ; Catatan
Kirim, peningkatan WebSocket dan melayani melalui TLS/HTTPS saat ini tidak didukung.
Selain itu lingkungan CloudFlare Worker dan konteks eksekusi saat ini tidak terpapar dengan middleware.
Oak tersedia untuk pekerja Cloudflare di JSR. Untuk menggunakan tambahkan paket ke proyek pekerja cloudflare Anda:
npx jsr add @oak/oak@14
Dan kemudian mengimpor ke modul:
import { Application } from "@oak/oak/application" ;Tidak seperti runtime lainnya, aplikasi Oak tidak mendengarkan permintaan yang masuk, sebaliknya menangani permintaan pengambilan pekerja. Server contoh minimal adalah:
import { Application } from "@oak/oak/application" ;
const app = new Application ( ) ;
app . use ( ( ctx ) => {
ctx . response . body = "Hello CFW!" ;
} ) ;
export default { fetch : app . fetch } ; Catatan
Pembaruan Kirim dan Websocket saat ini tidak didukung.
Oak tersedia untuk roti di JSR. Untuk menggunakan instal paket:
bunx jsr i @oak/oak@14
Dan kemudian mengimpor ke modul:
import { Application } from "@oak/oak/application" ; Catatan
Pembaruan Kirim dan Websocket saat ini tidak didukung.
Kelas Application berkoordinasi mengelola server HTTP, menjalankan middleware, dan penanganan kesalahan yang terjadi saat memproses permintaan. Dua metode umumnya digunakan: .use() dan .listen() . Middleware ditambahkan melalui metode .use() dan metode .listen() akan memulai server dan mulai memproses permintaan dengan middleware terdaftar.
Penggunaan dasar, menanggapi setiap permintaan dengan Hello World! :
import { Application } from "jsr:@oak/oak/application" ;
const app = new Application ( ) ;
app . use ( ( ctx ) => {
ctx . response . body = "Hello World!" ;
} ) ;
await app . listen ( { port : 8000 } ) ;Anda kemudian akan menjalankan skrip ini di Deno seperti:
> deno run --allow-net helloWorld.ts
Untuk informasi lebih lanjut tentang menjalankan kode di bawah Deno, atau informasi tentang cara menginstal Deno CLI, lihat Manual Deno.
Middleware diproses sebagai tumpukan, di mana setiap fungsi middleware dapat mengontrol aliran respons. Ketika middleware dipanggil, dilewatkan konteks dan referensi ke metode "berikutnya" di tumpukan.
Contoh yang lebih kompleks:
import { Application } from "jsr:@oak/oak/application" ;
const app = new Application ( ) ;
// Logger
app . use ( async ( ctx , next ) => {
await next ( ) ;
const rt = ctx . response . headers . get ( "X-Response-Time" ) ;
console . log ( ` ${ ctx . request . method } ${ ctx . request . url } - ${ rt } ` ) ;
} ) ;
// Timing
app . use ( async ( ctx , next ) => {
const start = Date . now ( ) ;
await next ( ) ;
const ms = Date . now ( ) - start ;
ctx . response . headers . set ( "X-Response-Time" , ` ${ ms } ms` ) ;
} ) ;
// Hello World!
app . use ( ( ctx ) => {
ctx . response . body = "Hello World!" ;
} ) ;
await app . listen ( { port : 8000 } ) ; Untuk menyediakan server HTTPS, maka opsi app.listen() perlu menyertakan opsi .secure Opsi aman diatur ke true dan menyediakan opsi .certFile dan .keyFile juga.
.handle() Metode .handle() digunakan untuk memproses permintaan dan menerima tanggapan tanpa meminta aplikasi mengelola aspek server. Namun ini adalah penggunaan lanjutan dan sebagian besar pengguna ingin menggunakan .listen() .
Metode .handle() menerima hingga tiga argumen. Yang pertama adalah argumen Request , dan yang kedua adalah argumen Deno.Conn . Argumen opsional ketiga adalah bendera untuk menunjukkan jika permintaan itu "aman" dalam arti itu berasal dari koneksi TLS ke klien jarak jauh. Metode diselesaikan dengan objek Response atau undefined jika ctx.respond === true .
Contoh:
import { Application } from "jsr:@oak/oak/application" ;
const app = new Application ( ) ;
app . use ( ( ctx ) => {
ctx . response . body = "Hello World!" ;
} ) ;
const listener = Deno . listen ( { hostname : "localhost" , port : 8000 } ) ;
for await ( const conn of listener ) {
( async ( ) => {
const requests = Deno . serveHttp ( conn ) ;
for await ( const { request , respondWith } of requests ) {
const response = await app . handle ( request , conn ) ;
if ( response ) {
respondWith ( response ) ;
}
}
} ) ;
}Sebuah contoh aplikasi memiliki beberapa properti juga:
contextState - Menentukan metode yang digunakan untuk membuat status untuk konteks baru. Nilai "clone" akan menetapkan negara sebagai klon dari keadaan aplikasi. Nilai "prototype" berarti keadaan aplikasi akan digunakan sebagai prototipe keadaan konteks. Nilai "alias" berarti bahwa keadaan aplikasi dan keadaan konteks akan menjadi referensi ke objek yang sama. Nilai "empty" akan menginisialisasi keadaan konteks dengan objek kosong.
.jsonBodyReplacer - fungsi penggantian opsional yang akan diterapkan pada tubuh JSON saat membentuk respons.
.jsonBodyReviver - fungsi reviver opsional yang akan diterapkan saat membaca tubuh JSON dalam permintaan.
.keys
Kunci yang akan digunakan saat menandatangani dan memverifikasi cookie. Nilai dapat diatur ke array tombol, dan contoh KeyStack , atau objek yang menyediakan antarmuka yang sama dengan KeyStack (misalnya instance keygrip). Jika hanya tombol yang dilewati, OAK akan mengelola tombol melalui KeyStack yang memungkinkan rotasi kunci mudah tanpa memerlukan penandatanganan ulang nilai data.
.proxy
Ini default ke false , tetapi dapat diatur melalui opsi konstruktor Application . Ini dimaksudkan untuk menunjukkan aplikasi berada di belakang proxy dan akan menggunakan X-Forwarded-Proto , X-Forwarded-Host , dan X-Forwarded-For saat memproses permintaan, yang seharusnya memberikan informasi yang lebih akurat tentang permintaan tersebut.
.state
Catatan status aplikasi, yang dapat diketik dengan kuat dengan menentukan argumen generik saat membangun Application() , atau disimpulkan dengan meneruskan objek negara (misalnya Application({ state }) ).
Konteks yang diteruskan ke middleware memiliki beberapa properti:
.app
Referensi ke Application yang memohon middleware ini.
.cookies
Cookies contoh untuk konteks ini yang memungkinkan Anda membaca dan mengatur cookie.
.request
Objek Request yang berisi perincian tentang permintaan.
.respond
Menentukan apakah ketika middleware selesai diproses, aplikasi harus mengirim .response ke klien. Jika true respons akan dikirim, dan jika false respons tidak akan dikirim. Standarnya true tetapi metode tertentu, seperti .upgrade() dan .sendEvents() akan mengatur ini menjadi false .
.response
Objek Response yang akan digunakan untuk membentuk respons yang dikirim kembali ke pemohon.
.socket
Ini akan undefined jika koneksi belum ditingkatkan ke soket web. Jika koneksi telah ditingkatkan, antarmuka .socket akan ditetapkan.
.state
Catatan status aplikasi, yang dapat diketik dengan kuat dengan menentukan argumen generik saat membangun Application() , atau disimpulkan dengan meneruskan objek negara (misalnya Application({ state }) ).
Konteks yang diteruskan ke middleware memiliki beberapa metode:
.assert()
Membuat pernyataan, yang jika tidak benar, melempar HTTPError , yang subkelas diidentifikasi oleh argumen kedua, dengan pesan tersebut menjadi argumen ketiga.
.send()
Streaming file ke klien yang meminta. Lihat konten statis di bawah ini untuk informasi lebih lanjut.
.sendEvents()
Konversikan koneksi saat ini menjadi respons acara yang Sent Server dan kembalikan ServerSentEventTarget di mana pesan dan acara dapat dialirkan ke klien. Ini akan false .respond
.throw()
Melempar HTTPError , subkelas mana yang diidentifikasi oleh argumen pertama, dengan pesan yang disahkan sebagai yang kedua.
.upgrade()
Cobalah untuk meningkatkan koneksi ke koneksi soket web, dan mengembalikan antarmuka WebSocket . Versi Oak sebelumnya, ini akan menjadi Promise yang diselesaikan dengan soket web std/ws .
Tidak seperti kerangka kerja middleware lainnya, context tidak memiliki jumlah alias yang signifikan. Informasi tentang permintaan hanya terletak di .request dan informasi tentang respons hanya terletak di .response .
context.cookies Cookies memungkinkan akses ke nilai cookie dalam permintaan, dan memungkinkan cookie diatur dalam respons. Secara otomatis mengamankan cookie jika properti .keys diatur pada aplikasi. Karena .cookies menggunakan Web Crypto API untuk menandatangani dan memvalidasi cookie, dan API itu bekerja dengan cara yang tidak sinkron, API Cookie bekerja dengan cara yang tidak sinkron. Ia memiliki beberapa metode:
.get(key: string, options?: CookieGetOptions): Promise<string | undefined>
Upaya untuk mengambil cookie dari permintaan dan mengembalikan nilai cookie berdasarkan kunci. Jika aplikasi .keys diatur, maka cookie akan diverifikasi terhadap versi cookie yang ditandatangani. Jika cookie valid, janji akan diselesaikan dengan nilainya. Jika tidak valid, tanda tangan cookie akan diatur untuk dihapus pada respons. Jika cookie tidak ditandatangani oleh kunci saat ini, itu akan pasrah dan ditambahkan ke respons.
.set(key: string, value: string, options?: CookieSetDeleteOptions): Promise<void>
Akan mengatur cookie di respons berdasarkan kunci yang disediakan, nilai, dan opsi apa pun. Jika aplikasi .keys diatur, maka cookie akan ditandatangani dan tanda tangan ditambahkan ke respons. Karena kunci ditandatangani secara tidak sinkron, menunggu metode .set() disarankan.
The context.request berisi informasi tentang permintaan tersebut. Ini berisi beberapa properti:
.body
Objek yang menyediakan akses ke badan permintaan. Lihat di bawah untuk detail tentang API Badan Permintaan.
.hasBody
Setel ke true jika permintaan mungkin memiliki tubuh, atau false jika tidak. Itu tidak memvalidasi jika tubuh didukung oleh parser tubuh bawaan.
[! Peringatan] Ini adalah API yang tidak dapat diandalkan. Dalam HTTP/2 dalam banyak situasi Anda tidak dapat menentukan apakah suatu permintaan memiliki tubuh atau tidak kecuali Anda mencoba membaca tubuh, karena sifat streaming HTTP/2. Pada Deno 1.16.1, untuk HTTP/1.1, Deno juga mencerminkan perilaku itu. Satu -satunya cara yang dapat diandalkan untuk menentukan apakah suatu permintaan memiliki tubuh atau tidak adalah dengan mencoba membaca tubuh.
Yang terbaik adalah menentukan apakah suatu tubuh mungkin bermakna bagi Anda dengan metode yang diberikan, dan kemudian mencoba membaca dan memproses tubuh jika itu bermakna dalam konteks yang diberikan. Misalnya GET dan HEAD tidak boleh memiliki tubuh, tetapi metode seperti DELETE dan OPTIONS mungkin memiliki tubuh dan harus diproses secara kondisional jika itu berarti bagi aplikasi Anda.
.headers
Header untuk permintaan, contoh Headers .
.method
String yang mewakili metode HTTP untuk permintaan tersebut.
.originalRequest
Tercerahkan ini akan dihapus dalam rilis Oak di masa depan.
Permintaan "asli" NativeServer , yang merupakan abstraksi atas objek Request DOM. .originalRequest.request adalah instance Request DOM yang sedang diproses. Pengguna umumnya harus menghindari menggunakan ini.
.secure
Pintasan untuk .protocol , mengembalikan true jika https sebaliknya false .
.source
Saat berjalan di bawah Deno, .source akan diatur ke Request standar Web Standard. Saat berjalan di bawah nodeJS, ini undefined .
.url
Sebuah contoh URL yang didasarkan pada URL lengkap untuk permintaan tersebut. Ini ada di tempat memiliki bagian URL yang terpapar pada sisa objek permintaan.
Dan beberapa metode:
.accepts(...types: string[])
Menegosiasikan jenis konten yang didukung oleh permintaan tanggapan. Jika tidak ada jenis konten yang dilewati, metode ini mengembalikan array yang diprioritaskan dari jenis konten yang diterima. Jika jenis konten dilewati, jenis konten yang dinegosiasikan terbaik dikembalikan. Jika tidak ada pencocokan tipe konten undefined dikembalikan.
.acceptsEncodings(...encodings: string[])
Menegosiasikan pengkodean konten yang didukung oleh permintaan tanggapan. Jika tidak ada penyandian yang dilewati, metode ini mengembalikan serangkaian penyandian yang diterima. Jika pengkodean disahkan, penyandian yang dinegosiasikan terbaik dikembalikan. Jika tidak ada penyandian yang cocok undefined dikembalikan.
.acceptsLanguages(...languages: string[])
Menegosiasikan bahasa yang dapat dipahami klien. Di mana varian lokal lebih disukai. Jika tidak ada penyandian yang dilewati, metode ini mengembalikan serangkaian bahasa yang dipahami. Jika bahasa disahkan, bahasa yang dinegosiasikan terbaik dikembalikan. Jika tidak ada bahasa yang cocok undefined dikembalikan.
Penting
API ini berubah secara signifikan di Oak V13 dan yang lebih baru. API sebelumnya telah tumbuh secara organik sejak Oak dibuat pada tahun 2018 dan tidak mewakili API umum lainnya. API yang diperkenalkan di V13 menyelaraskan lebih baik dengan cara Request API untuk berurusan dengan tubuh, dan harus lebih akrab bagi pengembang yang datang ke Oak untuk pertama kalinya.
API untuk permintaan Oak .body terinspirasi oleh Request API Fetch tetapi dengan beberapa fungsionalitas tambahan. request.body konteks. Body adalah instance dari suatu objek yang menyediakan beberapa properti:
.has
Setel ke true jika permintaan mungkin memiliki tubuh, atau false jika tidak. Itu tidak memvalidasi jika tubuh didukung oleh parser tubuh bawaan.
[! Penting] Ini adalah API yang tidak dapat diandalkan. Dalam HTTP/2 dalam banyak situasi Anda tidak dapat menentukan apakah suatu permintaan memiliki tubuh atau tidak kecuali Anda mencoba membaca tubuh, karena sifat streaming HTTP/2. Pada Deno 1.16.1, untuk HTTP/1.1, Deno juga mencerminkan perilaku itu. Satu -satunya cara yang dapat diandalkan untuk menentukan apakah suatu permintaan memiliki tubuh atau tidak adalah dengan mencoba membaca tubuh.
Yang terbaik adalah menentukan apakah suatu tubuh mungkin bermakna bagi Anda dengan metode yang diberikan, dan kemudian mencoba membaca dan memproses tubuh jika itu bermakna dalam konteks yang diberikan. Misalnya GET dan HEAD tidak boleh memiliki tubuh, tetapi metode seperti DELETE dan OPTIONS mungkin memiliki tubuh dan harus diproses secara kondisional jika itu berarti bagi aplikasi Anda.
.stream
A ReadableStream<Uint8Array> yang akan memungkinkan pembacaan tubuh di potongan Uint8Array . Ini adalah properti .body yang mirip dalam Request API fetch.
.used
Diatur ke true jika tubuh telah digunakan, jika tidak diatur ke false .
Itu juga memiliki beberapa metode:
arrayBuffer()
Menyelesaikan dengan ArrayBuffer yang berisi isi tubuh, jika ada. Cocok untuk membaca/menangani data biner.
blob()
Diselesaikan dengan Blob yang berisi isi tubuh. Cocok untuk membaca/menangani data biner.
form()
Diselesaikan dengan URLSearchParams yang telah didekodekan dari isi tubuh. Ini sesuai untuk badan dengan jenis konten application/x-www-form-urlencoded .
formData()
Diselesaikan dengan instance FormData yang telah diterjemahkan dari isi tubuh. Ini sesuai untuk tubuh dengan jenis konten multipart/form-data .
json()
Menyelesaikan dengan data dari tubuh yang diuraikan sebagai JSON. Jika jsonBodyReviver telah ditentukan dalam aplikasi, itu akan digunakan saat mem -parsing JSON.
text()
Diselesaikan dengan string yang mewakili isi tubuh.
type()
Upaya untuk memberikan panduan tentang bagaimana tubuh dikodekan yang dapat digunakan untuk menentukan metode apa yang digunakan untuk memecahkan kode tubuh. Metode ini mengembalikan string yang mewakili tipe tubuh yang ditafsirkan:
| Nilai | Keterangan |
|---|---|
"binary" | Tubuh memiliki jenis konten yang menunjukkan data biner dan .arrayBuffer() , .blob() atau .stream harus digunakan untuk membaca tubuh. |
"form" | Tubuh dikodekan sebagai data form dan .form() harus digunakan untuk membaca tubuh. |
"form-data" | Tubuh dikodekan sebagai bentuk multi-bagian dan .formData() harus digunakan untuk membaca tubuh. |
"json" | Tubuh dikodekan sebagai data JSON dan .json() harus digunakan untuk membaca tubuh. |
"text" | Tubuh dikodekan sebagai teks dan .text() harus digunakan untuk membaca tubuh. |
"unknown" | Entah tidak ada tubuh atau tidak mungkin untuk menentukan jenis tubuh berdasarkan jenis konten. |
Metode .type() juga mengambil argumen opsional dari jenis media kustom yang akan digunakan saat mencoba menentukan jenis tubuh. Ini kemudian dimasukkan ke dalam jenis media default. Nilai adalah objek di mana kunci adalah salah satu dari binary , form , form-data , json , atau text dan nilainya adalah jenis media yang sesuai dalam format yang kompatibel dengan format tipe-IS.
context.response berisi informasi tentang respons yang akan dikirim kembali ke pemohon. Ini berisi beberapa properti:
.body
Tubuh respons, yang sering dapat ditangani oleh penanganan badan respons otomatis yang didokumentasikan di bawah ini.
.headers
Contoh Headers yang berisi header untuk respons.
.status
Kode Status HTTP yang akan dikirim kembali dengan respons. Jika ini tidak ditetapkan sebelum merespons, Oak akan default menjadi 200 OK jika ada .body , jika tidak 404 Not Found .
.type
Jenis atau ekstensi media untuk mengatur header Content-Type untuk respons. Misalnya, Anda dapat menyediakan txt atau text/plain untuk menggambarkan tubuh.
Dan beberapa metode:
.redirect(url?: string | URL | REDIRECT_BACK, alt?: string | URL)
Metode untuk menyederhanakan pengalihan respons ke URL lain. Ini akan mengatur header Location ke url yang disediakan dan status ke 302 Found (kecuali status sudah status 3XX ). Penggunaan simbol REDIRECT_BACK sebagai url menunjukkan bahwa header Referer dalam permintaan harus digunakan sebagai arah, dengan alt menjadi lokasi alternatif jika Referer tidak diatur. Jika alt maupun Referer tidak ditetapkan, pengalihan akan terjadi pada / . HTML dasar (jika pemohon mendukungnya) atau badan teks akan diatur menjelaskan bahwa mereka dialihkan.
.toDomResponse()
Ini mengonversi informasi yang dipahami Oak tentang respons terhadap Response API Fetch. Ini akan menyelesaikan respons, menghasilkan upaya lebih lanjut untuk memodifikasi respons untuk melempar. Ini dimaksudkan untuk digunakan secara internal di dalam Oak untuk dapat menanggapi permintaan.
.with(response: Response) dan .with(body?: BodyInit, init?: ResponseInit)
Ini menetapkan respons terhadap Response standar web. Perhatikan bahwa ini akan mengabaikan/mengganti informasi lain yang ditetapkan pada respons oleh middleware lain termasuk hal -hal seperti header atau cookie yang akan diatur.
Ketika Content-Type respons tidak diatur dalam header .response , Oak akan secara otomatis mencoba untuk menentukan Content-Type yang sesuai. Pertama akan terlihat pada .response.type . Jika ditugaskan, ia akan mencoba menyelesaikan jenis media yang sesuai berdasarkan pada memperlakukan nilai .type sebagai jenis media, atau menyelesaikan jenis media berdasarkan ekstensi. Misalnya jika .type diatur ke "html" , maka Content-Type akan diatur ke "text/html" .
Jika .type tidak diatur dengan nilai, maka Oak akan memeriksa nilai .response.body . Jika nilainya adalah string , maka Oak akan memeriksa untuk melihat apakah string terlihat seperti html, jika demikian, Content-Type akan diatur ke text/html jika tidak akan diatur ke text/plain . Jika nilainya adalah objek, selain Uint8Array , Deno.Reader , atau null , objek akan diteruskan ke JSON.stringify() dan Content-Type akan diatur ke application/json .
Jika jenis tubuh adalah angka, bigint atau simbol, itu akan dipaksa menjadi string dan diperlakukan sebagai teks.
Jika nilai tubuh adalah fungsi, fungsi akan dipanggil tanpa argumen. Jika nilai pengembalian fungsi seperti janji, itu akan menunggu, dan nilai yang diselesaikan akan diproses seperti di atas. Jika nilainya tidak janji seperti, itu akan diproses seperti di atas.
Metode aplikasi .listen() digunakan untuk membuka server, mulai mendengarkan permintaan, dan memproses middleware terdaftar untuk setiap permintaan. Metode ini mengembalikan janji saat server ditutup.
Setelah server terbuka, sebelum mulai memproses permintaan, aplikasi akan menembakkan acara "listen" , yang dapat didengarkan melalui metode .addEventListener() . Misalnya:
import { Application } from "jsr:@oak/oak/application" ;
const app = new Application ( ) ;
app . addEventListener ( "listen" , ( { hostname , port , secure } ) => {
console . log (
`Listening on: ${ secure ? "https://" : "http://" } ${
hostname ?? "localhost"
} : ${ port } ` ,
) ;
} ) ;
// register some middleware
await app . listen ( { port : 80 } ) ;Jika Anda ingin menutup aplikasi, aplikasi mendukung opsi sinyal abort. Berikut adalah contoh menggunakan sinyal:
import { Application } from "jsr:@oak/oak/application" ;
const app = new Application ( ) ;
const controller = new AbortController ( ) ;
const { signal } = controller ;
// Add some middleware using `app.use()`
const listenPromise = app . listen ( { port : 8000 , signal } ) ;
// In order to close the server...
controller . abort ( ) ;
// Listen will stop listening for requests and the promise will resolve...
await listenPromise ;
// and you can do something after the close to shutdownMiddleware dapat digunakan untuk menangani kesalahan lain dengan middleware. Menunggu middleware lain untuk dieksekusi saat kesalahan jebakan berfungsi. Jadi jika Anda memiliki middleware penanganan kesalahan yang memberikan respons yang dikelola dengan baik terhadap kesalahan akan bekerja seperti ini:
import { Application } from "jsr:@oak/oak/application" ;
import { isHttpError } from "jsr:@oak/commons/http_errors" ;
import { Status } from "jsr:@oak/commons/status" ;
const app = new Application ( ) ;
app . use ( async ( ctx , next ) => {
try {
await next ( ) ;
} catch ( err ) {
if ( isHttpError ( err ) ) {
switch ( err . status ) {
case Status . NotFound :
// handle NotFound
break ;
default :
// handle other statuses
}
} else {
// rethrow if you can't handle the error
throw err ;
}
}
} ) ; Pengecualian middleware yang tidak dibawa akan ditangkap oleh aplikasi. Application Memperluas Global EventTarget di Deno, dan ketika kesalahan yang tidak dibawa terjadi di middleware atau pengiriman tanggapan, EventError akan dikirim ke aplikasi. Untuk mendengarkan kesalahan ini, Anda akan menambahkan event handler ke instance aplikasi:
import { Application } from "jsr:@oak/oak/application" ;
const app = new Application ( ) ;
app . addEventListener ( "error" , ( evt ) => {
// Will log the thrown error to the console.
console . log ( evt . error ) ;
} ) ;
app . use ( ( ctx ) => {
// Will throw a 500 on every request.
ctx . throw ( 500 ) ;
} ) ;
await app . listen ( { port : 80 } ) ; Kelas Router menghasilkan middleware yang dapat digunakan dengan Application untuk mengaktifkan perutean berdasarkan pathname dari permintaan.
Contoh berikut ini melayani layanan yang tenang dari peta buku, di mana http://localhost:8000/book/ akan mengembalikan array buku dan http://localhost:8000/book/1 akan mengembalikan buku dengan ID "1" :
import { Application } from "jsr:@oak/oak/application" ;
import { Router } from "jsr:@oak/oak/router" ;
const books = new Map < string , any > ( ) ;
books . set ( "1" , {
id : "1" ,
title : "The Hound of the Baskervilles" ,
author : "Conan Doyle, Arthur" ,
} ) ;
const router = new Router ( ) ;
router
. get ( "/" , ( context ) => {
context . response . body = "Hello world!" ;
} )
. get ( "/book" , ( context ) => {
context . response . body = Array . from ( books . values ( ) ) ;
} )
. get ( "/book/:id" , ( context ) => {
if ( books . has ( context ?. params ?. id ) ) {
context . response . body = books . get ( context . params . id ) ;
}
} ) ;
const app = new Application ( ) ;
app . use ( router . routes ( ) ) ;
app . use ( router . allowedMethods ( ) ) ;
await app . listen ( { port : 8000 } ) ; Rute yang ditularkan dikonversi ke ekspresi reguler menggunakan path-to-regexp, yang berarti parameter yang diekspresikan dalam pola akan dikonversi. path-to-regexp memiliki penggunaan lanjutan yang dapat menciptakan pola kompleks yang dapat digunakan untuk pencocokan. Lihat dokumentasi untuk perpustakaan itu jika Anda memiliki kasus penggunaan lanjutan.
Dalam kebanyakan kasus, jenis context.params secara otomatis disimpulkan dari string template jalur melalui sihir naskah. Namun dalam skenario yang lebih kompleks ini mungkin tidak menghasilkan hasil yang benar. Dalam hal ini Anda dapat mengganti tipe dengan router.get<RouteParams> , di mana RouteParams adalah jenis eksplisit untuk context.params .
Router bersarang didukung. Contoh berikut menanggapi http://localhost:8000/forums/oak/posts dan http://localhost:8000/forums/oak/posts/nested-routers .
import { Application } from "jsr:@oak/oak/application" ;
import { Router } from "jsr:@oak/oak/router" ;
const posts = new Router ( )
. get ( "/" , ( ctx ) => {
ctx . response . body = `Forum: ${ ctx . params . forumId } ` ;
} )
. get ( "/:postId" , ( ctx ) => {
ctx . response . body =
`Forum: ${ ctx . params . forumId } , Post: ${ ctx . params . postId } ` ;
} ) ;
const forums = new Router ( ) . use (
"/forums/:forumId/posts" ,
posts . routes ( ) ,
posts . allowedMethods ( ) ,
) ;
await new Application ( ) . use ( forums . routes ( ) ) . listen ( { port : 8000 } ) ; Fungsi send() dirancang untuk melayani konten statis sebagai bagian dari fungsi middleware. Dalam penggunaan yang paling lurus ke depan, root disediakan dan permintaan yang diberikan untuk fungsi dipenuhi dengan file dari sistem file lokal relatif terhadap root dari jalur yang diminta.
Penggunaan dasar akan terlihat seperti ini:
import { Application } from "jsr:@oak/oak/application" ;
const app = new Application ( ) ;
app . use ( async ( context , next ) => {
try {
await context . send ( {
root : ` ${ Deno . cwd ( ) } /examples/static` ,
index : "index.html" ,
} ) ;
} catch {
await next ( ) ;
}
} ) ;
await app . listen ( { port : 8000 } ) ; send() secara otomatis mendukung fitur seperti menyediakan header ETag dan Last-Modified dalam respons serta memproses header If-None-Match dan If-Modified-Since dalam permintaan. Ini berarti ketika melayani konten statis, klien akan dapat mengandalkan versi aset yang di-cache alih-alih mengunduhnya kembali.
Metode send() secara otomatis mendukung menghasilkan header ETag untuk aset statis. Header memungkinkan klien untuk menentukan apakah perlu mengunduh ulang aset atau tidak, tetapi dapat berguna untuk menghitung ETag untuk skenario lain.
ETag fungsi middleware ETag menilai context.reponse.body Penggunaan dasar akan terlihat seperti ini:
import { Application } from "jsr:@oak/oak/application" ;
import { factory } from "jsr:@oak/oak/etag" ;
const app = new Application ( ) ;
app . use ( factory ( ) ) ;
// ... other middleware for the applicationAda juga fungsi yang mengambil entitas untuk konteks yang diberikan berdasarkan apa yang logis untuk membaca ke dalam memori yang dapat diteruskan ke Etag menghitung yang merupakan bagian dari perpustakaan Deno Std:
import { Application } from "jsr:@oak/oak/application" ;
import { getEntity } from "jsr:@oak/oak/etag" ;
import { calculate } from "jsr:@std/http/etag" ;
const app = new Application ( ) ;
// The context.response.body has already been set...
app . use ( async ( ctx ) => {
const entity = await getEntity ( ctx ) ;
if ( entity ) {
const etag = await calculate ( entity ) ;
}
} ) ; Deno.serve() Migrasi Jika Anda bermigrasi dari Deno.serve() atau adaptasi kode yang dirancang untuk Request dan Response API Standard Fetch Standard, ada beberapa fitur Oak untuk membantu.
ctx.request.source Saat berjalan di bawah Deno, ini akan diatur ke Request API Fetch, memberikan akses langsung ke permintaan asli.
ctx.response.with() Metode ini akan menerima Response API Fetch atau membuat respons baru berdasarkan BodyInit dan ResponseInit yang disediakan. Ini juga akan menyelesaikan respons dan mengabaikan apa pun yang mungkin telah ditetapkan pada oak .response .
middleware/serve#serve() dan middelware/serve#route() Dua generator middleware ini dapat digunakan untuk mengadaptasi kode yang beroperasi lebih seperti Deno.serve() di mana ia memberikan Request API Fetch dan mengharapkan pawang untuk diselesaikan dengan Response API fetch.
Contoh penggunaan serve() dengan Application.prototype.use() :
import { Application } from "jsr:@oak/oak/application" ;
import { serve } from "jsr:@oak/oak/serve" ;
const app = new Application ( ) ;
app . use ( serve ( ( req , ctx ) => {
console . log ( req . url ) ;
return new Response ( "Hello world!" ) ;
} ) ) ;
app . listen ( ) ; Dan solusi serupa berfungsi dengan route() di mana konteksnya berisi informasi tentang router, seperti param:
import { Application } from "jsr:@oak/oak/application" ;
import { Router } from "jsr:@oak/oak/router" ;
import { route } from "jsr:@oak/oak/serve" ;
const app = new Application ;
const router = new Router ( ) ;
router . get ( "/books/:id" , route ( ( req , ctx ) => {
console . log ( ctx . params . id ) ;
return Response . json ( { title : "hello world" , id : ctx . params . id } ) ;
} ) ) ;
app . use ( router . routes ( ) ) ;
app . listen ( ) ; mod.ts mengekspor objek bernama testing yang berisi beberapa utilitas untuk menguji middleware oak yang mungkin Anda buat. Lihat pengujian dengan Oak untuk informasi lebih lanjut.
Ada beberapa modul yang secara langsung diadaptasi dari modul lain. Mereka telah melestarikan lisensi dan hak cipta masing -masing. Semua modul, termasuk yang secara langsung diadaptasi dilisensikan di bawah lisensi MIT.
Semua pekerjaan tambahan adalah Hak Cipta 2018 - 2024 Penulis Oak. Semua hak dilindungi undang -undang.