🦄
Elysia.jsを始める【Life Cycle】
※ この記事は、https://elysiajs.com/essential/life-cycle.html を日本語に翻訳しながら要点をまとめたものになるので、詳細は公式を確認してください。
Elysia.jsでのライフサイクル図
Events
Elysiaでのライフサイクルの大まかな概要は以下となる。
イベント名 | 内容 |
---|---|
Request | 新しいイベントを受信した時に通知される。この際、オーバーヘッドを減らすために最小限のコンテキストのみが提供される。 |
Parse | リクエストのあったbodyを解析し、Context.body へ内容を追加する。 |
Transform | バリデーション前に既存のコンテキストをバリデーションに適合させるために修正したり、あたらしいコンテキストを追加する。 |
Validation | 受信したリクエストのバリデーション |
Before Handle | ルートハンドラー処理(Handle)に入る前に、カスタムバリデーションを行うことができる。 |
Handle(ルートハンドラー) | 各ルートの処理 |
After Handle | 返却値をレスポンスにマッピングする。カスタムヘッダーを追加したり、値を新しいレスポンスに変換することなどができる。 |
Error | throwされたエラーをキャッチする。カスタムエラーレスポンスを処理したり、エラーレスポンスをキャッチすることなどができる。 |
After Response | クライアントにレスポンスが送信された後に実行される。 |
Hook
Elysiaで、ライフサイクルイベント中に利用できるhookは、大まかに2種類。
- Local Hook
- Interceptor Hook
の2種類ある。
Local Hook
特定のルートに対してのみ実行されるフック。
ルートハンドラー内で、インラインで設定ができる。
Local Hook(ローカルフック)の例
import { Elysia } from 'elysia'
import { isHtml } from '@elysiajs/html';
const app = new Elysia()
.get('/mikochi', () => '<h1>NyaHello World !!</h1>', {
afterHandle({ response, set }) {
if (isHtml(response)) {
set.headers['content-type'] = 'text/html; charset=utf8'
}
}
})
.get('/subaru', () => '<h1>Ajimaru! Ajimaru!</h1>')
.listen(3000)
上記を実行して、ブラウザで確認すると(ブラウザのNetworkタブで確認できる)、
path | content-type |
---|---|
/mikochi | text/html; charset=utf8 |
/subaru | text/plain;charset=utf-8 |
となる。
/mikochi
のブラウザでの確認画像
/subaru
のブラウザでの確認画像
ちなみに...
上記の表と画像を見てもらうとわかるがset.headers
の設定値は、設定した通りに反映される模様。
/mikochi
のルートパスで、text/html;
とcharset=utf8
の間に半角スペースを入れて確認したところ、半角スペースはそのままになっていた。
また、charsetの値もutf8
を代入した場合、ブラウザ側ではutf-8
と修正されずにutf8
として認識されていた。
Interceptor Hook
Interceptor Hookとして記述した後のルートハンドラーすべてに、記述したHookを適用する。
import { Elysia } from 'elysia'
import { isHtml } from '@elysiajs/html';
const app = new Elysia()
.get('/mikochi', () => '<h1>NyaHello World !!</h1>')
.onAfterHandle(({ response, set }) => {
if (isHtml(response)) {
set.headers['content-type'] = 'text/html; charset=utf-8'
}
})
.get('/subaru', () => '<h1>Ajimaru! Ajimaru!</h1>')
.get('/fubuki', () => '<h1>Hi! Friends!!</h1>')
.listen(3000)
上記の場合、onAfterHandle()の記述より下のルートハンドラーにHook内の処理である、set.handler
が適用される。
そのため、/mikochi
のみheaders
のcontent-typeに'text/html; charset=utf-8'
が登録されない。
path | content-type |
---|---|
/mikochi | text/plain;charset=utf-8 |
/subaru | text/html;charset=utf-8 |
/fubuki | text/html;charset=utf-8 |
/mikochi
のブラウザでの確認画像
/subaru
のブラウザでの確認画像
/fubuki
のブラウザでの確認画像
コードの順番
Elysiaのイベントのライフサイクルは、キューとして管理・登録される。
そのため、キューへ登録した順にFIFO(先入先出し)でコードが実行される。
import { Elysia } from 'elysia'
const app = new Elysia()
.onBeforeHandle(() => {
console.log('mikochi')
})
.onAfterHandle(() => {
console.log('subaru')
})
.get('/fubuki', () => '<h1>Hi! Friends!!</h1>', {
beforeHandle() {
console.log('shirakami')
}
})
.listen(3000)
上記例だと、
-
onBeforeHandle()
を実行 → 出力:mikochi
-
get()
内の、beforeHandle()
を実行 → 出力:shirakami
-
onAfterHandle()
を実行 → 出力:subaru
という順番になる。
Discussion