DenoのネイティブHTTPサーバー、Deno Deploy、node.js 16.5以降のミドルウェアフレームワーク、Cloudflare Workers and Bun。また、ミドルウェアルーターも含まれています。
このミドルウェアフレームワークは、 @koa/ルーターに触発されたKOAとミドルウェアルーターに触発されています。
このREADMEは、オークAPIのメカニズムに焦点を当てており、ExpressやKOAなどのJavaScriptミドルウェアフレームワークに精通している人と、Denoのまともな理解を目的としています。これらに慣れていない場合は、oakserver.github.io/oakのドキュメントをご覧ください。
また、私たちのFAQとコミュニティリソースの素晴らしいオークサイトをご覧ください。
注記
このREADMEの例は、 mainからのプルであり、デノCLIまたはデノデプロイ用に設計されています。これは、実際にワークロードを展開しようとしているときには意味がない場合があります。使用しているDenoのバージョンと互換性のある特定のバージョンに「ピン留め」し、期待するAPIの固定セットを持っています。 https://deno.land/x/ 、URLでgitタグを使用して特定のバージョンに誘導することをサポートしています。したがって、Oakのバージョン13.0.0を使用するには、 https://deno.land/x/[email protected]/mod.tsをインポートする必要があります。
OAKは、deno.land/xとJSRの両方で入手できます。 deno.land/xから使用するには、モジュールにインポートします。
import { Application } from "https://deno.land/x/oak/mod.ts" ;JSRから使用するには、モジュールにインポートします。
import { Application } from "jsr:@oak/oak@14" ;OAKは、NPMとJSRの両方でnode.jsで利用できます。 NPMから使用するには、パッケージをインストールします。
npm i @oakserver/oak@14
そして、モジュールにインポートします。
import { Application } from "@oakserver/oak" ;JSRから使用するには、パッケージをインストールします。
npx jsr i @oak/oak@14
そして、モジュールにインポートします。
import { Application } from "@oak/oak/application" ; 注記
送信、WebSocketのアップグレード、TLS/HTTPSを介したサービングは現在サポートされていません。
さらに、CloudFlareワーカー環境と実行コンテキストは現在、ミドルウェアにさらされていません。
OAKは、JSRのCloudFlare労働者が利用できます。使用するには、CloudFlareワーカープロジェクトにパッケージを追加するには:
npx jsr add @oak/oak@14
そして、モジュールにインポートします。
import { Application } from "@oak/oak/application" ;他のランタイムとは異なり、OAKアプリケーションは着信リクエストを聞きません。代わりに、ワーカーフェッチリクエストを処理します。最小限のサンプルサーバーは次のとおりです。
import { Application } from "@oak/oak/application" ;
const app = new Application ( ) ;
app . use ( ( ctx ) => {
ctx . response . body = "Hello CFW!" ;
} ) ;
export default { fetch : app . fetch } ; 注記
送信およびWebSocketのアップグレードは現在サポートされていません。
オークはJSRのBUNで利用できます。パッケージをインストールするには:
bunx jsr i @oak/oak@14
そして、モジュールにインポートします。
import { Application } from "@oak/oak/application" ; 注記
送信およびWebSocketのアップグレードは現在サポートされていません。
Applicationクラスは、HTTPサーバーの管理、ミドルウェアの実行、およびリクエストの処理時に発生するエラーの処理エラーを調整します。通常、2つのメソッドが使用されます: .use()と.listen() 。ミドルウェアは.use()メソッドを介して追加され、 .listen()メソッドはサーバーを開始し、登録されたミドルウェアでリクエストの処理を開始します。
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 } ) ;次に、このスクリプトをDenoで実行します。
> deno run --allow-net helloWorld.ts
Denoの下での実行コードの実行の詳細、またはDeno CLIのインストール方法に関する情報については、Denoマニュアルをご覧ください。
ミドルウェアはスタックとして処理され、各ミドルウェア関数は応答の流れを制御できます。ミドルウェアが呼び出されると、コンテキストが渡され、スタック内の「次の」メソッドへの参照が渡されます。
より複雑な例:
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 } ) ; HTTPSサーバー.keyFile提供するにtrue 、 app.listen()オプション.certFileオプション.secure含める必要があります。
.handle()メソッド.handle()メソッドは、アプリケーションにサーバーの側面を管理することなく、リクエストを処理して応答を受信するために使用されます。ただし、これは高度な使用法であり、ほとんどのユーザーは.listen()を使用する必要があります。
.handle()メソッドは、最大3つの引数を受け入れます。 1つ目はRequest引数であり、2つ目はDeno.Conn引数です。 3番目のオプションの引数は、リクエストがTLS接続からリモートクライアントへの接続から発信されるという意味で、リクエストが「安全」であるかどうかを示すフラグです。このメソッドは、 ctx.respond === trueの場合、 Responseオブジェクトで解決されるか、 undefined 。
例:
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 ) ;
}
}
} ) ;
}アプリケーションのインスタンスには、いくつかのプロパティもあります。
contextState新しいコンテキストのために状態を作成するために使用される方法を決定します。 "clone"の値は、状態をアプリ状態のクローンとして設定します。 "prototype"の値は、アプリの状態がコンテキストの状態のプロトタイプとして使用されることを意味します。 "alias"の値とは、アプリケーションの状態とコンテキストの状態が同じオブジェクトへの参照になることを意味します。 "empty"の値は、空のオブジェクトでコンテキストの状態を初期化します。
.jsonBodyReplacer応答を形成するときにJSON体に適用されるオプションの置き換え関数。
.jsonBodyReviverリクエストでJSONボディを読み取るときに適用されるオプションのリバイバー関数。
.keys
Cookieの署名と検証の際に使用するキー。値は、キーの配列、 KeyStackのインスタンス、またはKeyStackと同じインターフェイスを提供するオブジェクトに設定できます(たとえば、keygripのインスタンス)。キーだけが渡される場合、オークはKeyStackを介してキーを管理し、データ値を再署名することなく簡単にキーローテーションを可能にします。
.proxy
これはデフォルトでfalseになりますが、 Applicationコンストラクターオプションを介して設定できます。これは、アプリケーションがプロキシの背後にあることを示すことを目的としており、リクエストの処理時にX-Forwarded-Proto 、 X-Forwarded-Host 、およびX-Forwarded-Forを使用します。これにより、リクエストに関するより正確な情報が提供されます。
.state
アプリケーション状態の記録。これは、 Application()を構築するときに一般的な引数を指定することで強く入力できます。または、状態オブジェクト( Application({ state }) )を渡すことで推測します。
ミドルウェアに渡されたコンテキストには、いくつかのプロパティがあります。
.app
このミドルウェアを呼び出しているApplicationへの参照。
.cookies
このコンテキストのCookiesインスタンスでは、Cookieを読んでセットできます。
.request
リクエストに関する詳細を含むRequestオブジェクト。
.respond
ミドルウェアが処理が終了したときに、アプリケーションがクライアントに.responseを送信するかどうかを判断します。 true場合、応答は送信され、 false場合は応答が送信されません。デフォルトはtrueですが、 .upgrade()や.sendEvents()などの特定のメソッドはこれをfalseに設定します。
.response
要求者に送信された応答を形成するために使用されるResponseオブジェクト。
.socket
接続がWebソケットにアップグレードされていない場合、これはundefinedなります。接続がアップグレードされている場合、 .socketインターフェイスが設定されます。
.state
アプリケーション状態の記録。これは、 Application()を構築するときに一般的な引数を指定することで強く入力できます。または、状態オブジェクト( Application({ state }) )を渡すことで推測します。
ミドルウェアに渡されたコンテキストにはいくつかの方法があります。
.assert()
真実ではないにしても、 HTTPErrorは2番目の引数によって識別され、メッセージが3番目の引数であるという主張を行います。
.send()
ファイルを要求クライアントにストリーミングします。詳細については、以下の静的コンテンツを参照してください。
.sendEvents()
現在の接続をサーバーセントのイベント応答に変換し、メッセージやイベントをクライアントにストリーミングできるServerSentEventTargetターゲットを返します。これにより、 falseに.respond設定されます。
.throw()
サブクラスは最初の引数によって識別されるHTTPErrorを投げ、メッセージは2番目の引数として渡されます。
.upgrade()
接続をWebソケット接続にアップグレードし、 WebSocketインターフェイスを返します。 Oakの以前のバージョン、これはstd/ws Webソケットで解決するPromiseです。
他のミドルウェアフレームワークとは異なり、 contextエイリアスのかなりの量がありません。リクエストに関する情報は.requestのみにあり、応答に関する情報は.responseのみにあります。
context.cookies使用すると、リクエスト内のCookieの値にアクセスでき、Cookieを応答に設定できます。 .keysプロパティがアプリケーションに設定されている場合、Cookieを自動的に保護します。 .cookies Web Crypto APIを使用してCookieに署名および検証し、それらのAPIが非同期的に動作するため、Cookie APIは非同期的に動作します。いくつかの方法があります:
.get(key: string, options?: CookieGetOptions): Promise<string | undefined>
クッキーをリクエストから取得しようとする試みを試み、キーに基づいてCookieの値を返します。 .keysが設定されている場合、CookieはCookieの署名バージョンに対して検証されます。 Cookieが有効な場合、約束は値とともに解決します。無効な場合、Cookie署名は応答で削除されるように設定されます。 Cookieが現在のキーによって署名されていない場合、辞任され、応答に追加されます。
.set(key: string, value: string, options?: CookieSetDeleteOptions): Promise<void>
提供されたキー、価値、およびすべてのオプションに基づいて、応答にCookieを設定します。 .keysが設定されている場合、Cookieに署名され、署名が応答に追加されます。キーが非同期に署名されているため、 .set()メソッドを待つことをお勧めします。
context.requestには、リクエストに関する情報が含まれています。いくつかのプロパティが含まれています。
.body
リクエストの本文へのアクセスを提供するオブジェクト。リクエストボディAPIの詳細については、以下を参照してください。
.hasBody
リクエストに本文がある場合はtrueに設定するか、そうでない場合はfalseになります。ただし、体が組み込まれたボディパーサーによって支えられているかどうかは検証されません。
[!警告]これは信頼できないAPIです。多くの状況でHTTP/2では、HTTP/2のストリーミングの性質のために、リクエストにボディがあるかどうかを判断することはできません。 Deno 1.16.1の時点で、HTTP/1.1の場合、Denoもその動作を反映しています。リクエストにボディがあるかどうかを判断する唯一の信頼できる方法は、身体を読み込もうとすることです。
特定の方法で身体があなたにとって意味があるかどうかを判断し、特定のコンテキストで意味がある場合は体を読み取って処理しようとすることが最善です。たとえばGET and HEADボディを持つことはありませんが、 DELETEやOPTIONSなどの方法にはボディがあり、アプリケーションにとって意味のある場合は身体を条件付きで処理する必要があります。
.headers
リクエストのヘッダー、 Headersのインスタンス。
.method
リクエストのHTTPメソッドを表す文字列。
.originalRequest
これは、将来のオークのリリースで削除されることを推奨されます。
dom Requestオブジェクトに対する抽象化である「raw」 NativeServerリクエスト。 .originalRequest.requestは、処理されているDOM Requestインスタンスです。ユーザーは通常、これらの使用を避ける必要があります。
.secure
.protocolのショートカット。HTTPSがfalseの場合はtrueを返します。
.source
Denoの下で実行すると、 .sourceソースWeb標準Requestに設定されます。 nodejsの下で実行すると、これはundefinedになります。
.url
リクエストの完全なURLに基づいたURLのインスタンス。これは、Requestオブジェクトの残りの部分にURLの一部を公開する代わりにです。
そしていくつかの方法:
.accepts(...types: string[])
応答の要求によってサポートされているコンテンツタイプを交渉します。コンテンツタイプが渡されない場合、メソッドは、受け入れられたコンテンツタイプの優先順位付けされた配列を返します。コンテンツタイプが渡された場合、最良の交渉コンテンツタイプが返されます。コンテンツタイプの一致がundefinedでない場合。
.acceptsEncodings(...encodings: string[])
応答の要求によってサポートされているコンテンツをエンコードするコンテンツを交渉します。エンコーディングが渡されない場合、メソッドは受け入れられたエンコーディングの優先順位付けされた配列を返します。エンコーディングが渡されると、最良の交渉エンコードが返されます。 undefinedエンコーディングの一致が返されない場合。
.acceptsLanguages(...languages: string[])
クライアントが理解できる言語を交渉します。ロケールバリアントが好みを取る場合。エンコーディングが渡されない場合、メソッドは、理解された言語の優先順位付けされた配列を返します。言語が渡された場合、最高の交渉された言語が返されます。 undefined言語の一致が返されない場合。
重要
このAPIは、Oak V13以降で大幅に変化しました。 OAKが2018年に作成されて以来、以前のAPIは有機的に成長しており、他の一般的なAPIを代表していませんでした。 V13で導入されたAPIは、APIのRequest方法により適しているため、ボディを処理する方法が適切であり、オークに初めて来る開発者により馴染みがあるはずです。
OAKリクエストのAPIは.body Fetch APIのRequestに触発されていますが、機能が追加されています。コンテキストのrequest.bodyは、いくつかのプロパティを提供するオブジェクトのインスタンスです。
.has
リクエストに本文がある場合はtrueに設定するか、そうでない場合はfalseになります。ただし、体が組み込まれたボディパーサーによって支えられているかどうかは検証されません。
[!重要]これは信頼できないAPIです。多くの状況でHTTP/2では、HTTP/2のストリーミングの性質のために、リクエストにボディがあるかどうかを判断することはできません。 Deno 1.16.1の時点で、HTTP/1.1の場合、Denoもその動作を反映しています。リクエストにボディがあるかどうかを判断する唯一の信頼できる方法は、身体を読み込もうとすることです。
特定の方法で身体があなたにとって意味があるかどうかを判断し、特定のコンテキストで意味がある場合は体を読み取って処理しようとすることが最善です。たとえばGET and HEADボディを持つことはありませんが、 DELETEやOPTIONSなどの方法にはボディがあり、アプリケーションにとって意味のある場合は身体を条件付きで処理する必要があります。
.stream
Uint8Arrayチャンクで体を読むことができるReadableStream<Uint8Array> 。これは、Fetch API Requestで.bodyプロパティを装います。
.used
体が使用されている場合はtrue設定され、それ以外の場合はfalseに設定されます。
また、いくつかの方法があります。
arrayBuffer()
ボディの内容を含むArrayBufferで解決します。バイナリデータの読み取り/処理に適しています。
blob()
体の内容を含むBlobで解決します。バイナリデータの読み取り/処理に適しています。
form()
体の内容から解読されたURLSearchParamsで解決します。これは、コンテンツタイプのapplication/x-www-form-urlencodedを備えたボディに適しています。
formData()
体の内容からデコードされたFormDataインスタンスで解決します。これは、コンテンツタイプのmultipart/form-dataを持つボディに適しています。
json()
JSONとして解析されたボディからのデータを解決します。 jsonBodyReviverアプリケーションで指定されている場合、JSONを解析するときに使用されます。
text()
身体の内容を表す文字列で解決します。
type()
身体のデコードに使用する方法を決定するために使用できる身体のエンコードのガイダンスを提供しようとします。このメソッドは、解釈されたボディタイプを表す文字列を返します。
| 価値 | 説明 |
|---|---|
"binary" | ボディには、バイナリデータを示すコンテンツタイプがあり、 .arrayBuffer() 、. .blob()または.streamを使用してボディを読み取る必要があります。 |
"form" | ボディはフォームデータとしてエンコードされ、 .form()を使用してボディを読み取る必要があります。 |
"form-data" | ボディはマルチパート形式としてエンコードされ、 .formData()を使用してボディを読み取る必要があります。 |
"json" | ボディはJSONデータとしてエンコードされ、 .json()を使用してボディを読み取る必要があります。 |
"text" | 本体はテキストとしてエンコードされ、 .text()を使用してボディを読み取る必要があります。 |
"unknown" | ボディがないか、コンテンツタイプに基づいてボディタイプを決定することはできませんでした。 |
.type()メソッドは、ボディのタイプを決定しようとするときに使用されるカスタムメディアタイプのオプションの引数も実行します。これらは、デフォルトのメディアタイプに組み込まれます。値は、キーがbinary 、 form form-data 、 json 、またはtextの1つであるオブジェクトであり、値はタイプIS形式と互換性のある形式の適切なメディアタイプです。
context.responseには、リクエスターに送信される応答に関する情報が含まれています。いくつかのプロパティが含まれています。
.body
応答の本文は、以下に文書化された自動応答本文処理によってしばしば処理できます。
.headers
応答のヘッダーを含むHeadersインスタンス。
.status
応答で返送されるHTTP Statusコード。応答する前にこれが設定されていない場合、オークは.bodyがある場合、デフォルトで200 OKになります。そうでなければ404 Not Found 。
.type
応答用のContent-Typeヘッダーを設定するためのメディアタイプまたは拡張機能。たとえば、 txtまたはtext/plainを提供して身体を説明できます。
そしていくつかの方法:
.redirect(url?: string | URL | REDIRECT_BACK, alt?: string | URL)
別のURLへの応答のリダイレクトを簡素化する方法。 Locationヘッダーを提供されたurlに、ステータスを302 Foundに設定します(ステータスがすでに3XXステータスでない限り)。 urlとしてのシンボルREDIRECT_BACKの使用は、リクエストReferer alt Refererヘッダーを方向として使用する必要があることを示しています。 altもRefererも設定されていない場合、リダイレクトは/に発生します。基本的なHTML(要求者がサポートしている場合)またはテキスト本体が設定され、それらがリダイレクトされていることを説明します。
.toDomResponse()
これにより、OakがFetch API Responseに対する応答について理解している情報を変換します。これにより、応答が完成し、スローへの応答を変更しようとする試みが行われます。これは、リクエストに応答できるように、オーク内で内部で使用することを目的としています。
.with(response: Response) and .with(body?: BodyInit, init?: ResponseInit)
これにより、Web標準Responseに対する応答が設定されます。これにより、ヘッダーやCookieが設定するなど、他のミドルウェアによる他のミドルウェアによる他の情報セットを無視/オーバーライドすることに注意してください。
応答Content-Type .responseのヘッダーに設定されていない場合、Oakは自動的に適切なContent-Typeを決定しようとします。まず、 .response.typeを確認します。割り当てられた場合、 .typeの値をメディアタイプとして扱うか、拡張機能に基づいてメディアタイプを解決することに基づいて、適切なメディアタイプを解決しようとします。たとえば、 .type "html"に設定されている場合、 Content-Type "text/html"に設定されます。
.type値で設定されていない場合、Oakは.response.bodyの値を検査します。値がstringの場合、OAKは文字列がHTMLのように見えるかどうかを確認します。もしそうなら、 Content-Type text/htmlに設定されます。そうしないと、 text/plainに設定されます。値がUint8Array 、 Deno.Reader 、またはnullを除いてオブジェクトである場合、オブジェクトはJSON.stringify()に渡され、 Content-Type application/jsonに設定されます。
ボディの種類が数字、bigint、またはシンボルである場合、文字列に強制され、テキストとして扱われます。
身体の値が関数である場合、関数は引数なしで呼び出されます。関数の返品値が約束である場合、それは待ち望まれ、解決された値は上記のように処理されます。値が約束されていない場合、上記のように処理されます。
アプリケーションメソッド.listen()は、サーバーを開き、リクエストのリスニングを開始し、各リクエストの登録ミドルウェアの処理を開始するために使用されます。この方法は、サーバーが閉じると約束を返します。
サーバーがオープンしたら、リクエストの処理を開始する前に、アプリケーションは.addEventListener()メソッドを介してリッスンできる"listen"イベントを発射します。例えば:
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 } ) ;アプリケーションを閉じたい場合、アプリケーションは中止信号のオプションをサポートします。信号を使用する例は次のとおりです。
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 shutdownミドルウェアは、ミドルウェアで他のエラーを処理するために使用できます。エラーのトラップ中に実行するために他のミドルウェアを待つことができます。したがって、エラーへの適切に管理された応答を提供するミドルウェアの取り扱いエラーがある場合、次のように機能します。
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 ;
}
}
} ) ;猛攻撃のミドルウェアの例外は、アプリケーションによってキャッチされます。 Application DenoのグローバルなEventTargetを拡張し、猛攻撃エラーがミドルウェアで発生したり、回答の送信が発生したりすると、 EventErrorがアプリケーションに発送されます。これらのエラーを聞くには、アプリケーションインスタンスにイベントハンドラーを追加します。
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 } ) ; Routerクラスは、リクエストのパス名に基づいてルーティングを有効にするためにApplicationで使用できるミドルウェアを生成します。
次の例ではhttp://localhost:8000/book/ books and http://localhost:8000/book/1を返す本のマップの安らかなサービスを提供します"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 } ) ;渡されたルートは、パスツーレジックスを使用して正規表現に変換されます。これは、パターンで表されたパラメーターが変換されることを意味します。 path-to-regexpは、一致に使用できる複雑なパターンを作成できる高度な使用法があります。高度なユースケースがある場合は、そのライブラリのドキュメントをご覧ください。
ほとんどの場合、 context.paramsのタイプは、TypeScriptマジックを介してパステンプレート文字列から自動的に推測されます。より複雑なシナリオでは、これは正しい結果をもたらさないかもしれません。その場合、 router.get<RouteParams>でタイプをオーバーライドできます。ここで、 RouteParams context.paramsの明示的なタイプです。
ネストルーターがサポートされています。次の例ではhttp://localhost:8000/forums/oak/posts and 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 } ) ; 関数send()は、ミドルウェア関数の一部として静的コンテンツを提供するように設計されています。最も簡単な使用法では、ルートが提供され、関数に提供されたリクエストは、要求されたパスからのルートに対するローカルファイルシステムからのファイルで満たされます。
基本的な使用法は次のようになります:
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()応答でETagおよびLast-Modifiedヘッダーを提供する機能や、 If-None-MatchおよびIf-Modified-Since処理などの機能を自動的にサポートします。これは、静的コンテンツを提供する際に、クライアントが再ダウンロードする代わりに、キャッシュされたバージョンの資産に依存できることを意味します。
send()メソッドは、静的資産のETagヘッダーの生成を自動的にサポートします。ヘッダーにより、クライアントは資産を再ダウンロードする必要があるかどうかを判断できますが、他のシナリオのETagを計算すると便利です。
context.reponse.bodyを評価し、そのボディタイプのETagヘッダーを作成できるかどうかを判断するミドルウェア関数があり、その場合、応答にETagヘッダーを設定します。基本的な使用法は次のようになります:
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 applicationまた、DENO STDライブラリの一部であるETAG計算に渡すことができるメモリに読み込むことが論理的なものに基づいて、特定のコンテキストのエンティティを取得する関数もあります。
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()移行を取得しますDeno.serve()から移行している場合、またはWeb標準のフェッチAPI RequestとResponse用に設計されたコードの適応を行う場合、オークのいくつかの機能があります。
ctx.request.source Denoの下で実行されると、これはFetch API Requestに設定され、元のリクエストに直接アクセスできます。
ctx.response.with()この方法は、Fetch API Responseを受け入れるか、提供されたBodyInitとResponseInitに基づいて新しい応答を作成します。また、これは応答を完成させ、 .responseに設定された可能性のあるものはすべて無視します。
middleware/serve#serve()およびmiddelware/serve#route()これらの2つのミドルウェアジェネレーターを使用して、 Deno.serve()のように動作するコードを適応させることができます。これは、フェッチAPI Requestを提供し、ハンドラーがフェッチAPI Responseで解決することを期待しています。
Application.prototype.use()でserve()を使用する例:
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 ( ) ;同様のソリューションは、パラメージのように、コンテキストにルーターに関する情報が含まれるroute()で動作します。
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 、作成する可能性のあるオークミドルウェアをテストするためのいくつかのユーティリティを含むtestingという名前のオブジェクトをエクスポートします。詳細については、OAKでのテストをご覧ください。
他のモジュールから直接適合したモジュールがいくつかあります。彼らは個々のライセンスと著作権を保存しています。直接適合したモジュールを含むすべてのモジュールは、MITライセンスの下でライセンスされています。
追加の作業はすべて著作権2018-2024 The Oak Authorsです。無断転載を禁じます。