🦄

Elysia.jsを始める【Handler】

2024/09/04に公開

※ 前回:Elysia.jsを始める【Handler】

※ 主に https://elysiajs.com/essential/handler.html の日本語訳+αの検証をしているものになっているので、詳細は公式ページを参照のこと

Elysiaのhandler

import { Elysia } from 'elysia'

new Elysia()
    .get('/mikochi', () => 'Nyahallo !')
    .listen(3000)

リソース(パス)に対して定義されているメソッドをElysiaではhandlerとしている。
上記であれば、() => 'Nyahallo !'部分がhandlerになる。

Elysiaでは、静的ファイルや固定のレスポンスは、インラインで定義することで、パフォーマンスの最適化が図られるように設計されているとされている。これにより、サーバーの負荷が軽減されレスポンスの一貫性が保たれるようになる。

import { Elysia } from 'elysia'

const app = new Elysia()
    .get('/vivideba', () => Bun.file('/your/file/path/vivideba.mp3'))
    .listen(3000)

上記のように、音声ファイルのようなものも、インラインで定義した方がパフォーマンスが最適化される。

Context

ElysiaでのContextとは、サーバーに送られるリクエスト情報のこと。

Context.set

setは、Context.setを介して、アクセス可能なレスポンスを形成する変更可能なプロパティ。

以下項目を設定できる

項目 説明
set.status ステータスコードの設定
set.headers カスタムヘッダーの追加
set.redirect リダイレクトの追加
import { Elysia } from 'elysia'

const app = new Elysia()
  .get('/mikochi', ({ set }) => {
    set.headers['x-powered-by'] = 'Sakura Miko'
    set.status = 301
    set.redirect = '/suichan'

    return { message: "Mikochi is elite." }
  })
  .get('/suichan', () => 'miComet')
  .listen(3000)

ただし、Visual Stadio Codeでは、set.redirectを使おうとしたら、set.redirectは非推奨として取消線がつく(v1.1)。
なお、v1.2set.recirectは削除される予定となっている。

代わりに

new Elysia()
  .get(({ redirect }) => redirect('/'))

でリダイレクトを設定することになる様子。

カスタムステータスの設定

  • errorメソッドの利用
  • set.statusでの設定

errorメソッドでエラーレスポンスを生成する

import { Elysia } from 'elysia'

const app = new Elysia()
  .get('/mikochi', ({ error }) => error(418, "Mikochi is elite miko!"))
  .listen(3000)

Elysiaでは、上記のようにメインハンドラ内では、error()によるエラーレスポンス生成を推奨している。
理由としては、

  • エラーレスポンスの型推論の向上
  • ステータスコードに基づく型の絞り込み
  • Edenとの統合によるエンドツーエンドの型安全性確保

としている。

エラーレスポンスの型推論の向上

error()を使用することで、エラーレスポンスが特定の型に合致するかどうかを推論するようになる。
これによって、返される値が期待される型に合致しているかどうかをコンパイル時にチェックようになり、エラーハンドリングが型安全に行えるようになる。

ステータスコードに基づく型の絞り込み

error()に渡されるステータスコードに基づいて、レスポンスの型を絞り込むようになる。
これで特定のステータスコードに対応するレスポンス型が自動的に推論されるようになる。

Edenとの統合によるエンドツーエンドの型安全性確保

Elysiaでは、Edenという型安全性を強化する仕組みと統合することができる。
Edenを利用することによって、レスポンスの型をより正確に推論し、エラーハンドリングを型安全に行うことができるようになる。

レスポンスステータスの設定

デフォルトとなるレスポンスステータスをset.statusで設定することができる。

import { Elysia } from 'elysia'

const app = new Elysia()
  .onBeforeHandle(({ set }) => {
    set.status = 418

    return 'Not Ajimaru ...'
  })
  .get('/subaru', () => 'Ajimaru')
  .listen(3000)

なお、Elysiaのデフォルトのレスポンスで特にエラーなく正常に処理された場合のデフォルトレスポンスコードは200となっている。

また、statusの設定は、レスポンスコードだけでなくステータスの通称を利用して設定することも可能。

import { Elysia } from 'elysia'

const app = new Elysia()
  .onBeforeHandle(({ set }) => {
    set.status = 'Created'

    return 'Ajima ... ru?'
  })
  .get('/subaru', () => 'Ajimaru')
  .listen(3000)

カスタムヘッダーの設定

Elysiaでは、set.headersを利用してレスポンスヘッダーの設定をすることができる。

import { Elysia } from 'elysia'

const app = new Elysia()
  .get('/subaru', ({ set }) => {
    set.headers['x-powered-by'] = 'Ajimaruyasan'

    return 'syuba syuba'
  })
  .listen(3000)

カスタムヘッダーの設定の際の注意点

Elysiaでヘッダー名は小文字で設定することを推奨している。
ヘッダー名を小文字で指定することで、開発環境(IDE)でのオートコンプリートが一貫して機能するようになる。
これにより、ヘッダー名を入力する際に一貫した補完を受けることオートコンプリートを利用しやすくするためである。

redirect

リダイレクトの設定の仕方は、以下のように設定できる。

import { Elysia } from 'elysia'

const app = new Elysia()
  .get('/ajima', ({ redirect }) => {
    return redirect('/ru')
  })
  .get('/ru', ({ set }) => {
    return 'Ajimreru !'
  })
  .get('/bibideba', ({ redirect }) => {
    return redirect('https://youtu.be/8ZP5eqm4JqM?si=j1-9qmWlqzB8z8Yj')
  })
  .listen(3000)

上記例であれば、/ajimaでリクエストした場合は、/ruにリダイレクトされるのでブラウザには「Ajimaru !」と表示される。
外部リソースへのリダイレクトであれば、URLを設定すれば良いので、上記であれば、/bibidebaをリクエストした場合は、ビビデバ / 星街すいせい(official)にリダイレクトすることが確認できる。

Response

Elysiaは、Web標準のRequest/Responseモデルに準拠している。
ルートハンドラーから返される値を自動的にResponseオブジェクトにマッピングをするため、開発者はボイラープレートコードのようなものを書く必要はなく、ビジネスロジックに集中することができるとしている。

自動マッピング
import { Elysia } from 'elysia'

const app = new Elysia()
  .get('/oozora_subaru', () => 'syuba! syuba! syuba!')
  .listen(3000)

なお、明示的にnew Response()を使うことも可能。

new Response()の利用パターン
import { Elysia } from 'elysia'

const app = new Elysia()
  .get('/oozora_subaru', () => new Response('syuba! syuba! syuba!'))
  .listen(3000)

パフォーマンスの観点

自動マッピングの場合でも、new Response()を利用する場合でもレスポンス性能は+- 0.1%とのことで、どちらの形式を利用しても良いとしている。


Elysia.jsを始める【Context】に続きます。

参考: https://elysiajs.com/

Discussion