Skip to content

Fastify アダプター

@inferdi/fastify は Fastify v5 のプラグインです。スコープドモードでは、ルートを app.di として公開し、onRequest で 1 つのリクエストスコープを作成し、それを request.di として公開し、onResponse で破棄します。

インストール

bash
pnpm add @inferdi/inferdi @inferdi/fastify fastify
ts
import Fastify, { type FastifyRequest } from 'fastify'
import { inferdiFastify } from '@inferdi/fastify'

リクエストスコープ

モジュール拡張(module augmentation)で具体的なコンテナ型を公開します。

ts
const root = buildRootContainer()
const app = Fastify()

type RootContainer = typeof root
type RequestContainer = ReturnType<RootContainer['createScope']>

declare module 'fastify' {
  interface FastifyInstance {
    di: RootContainer
  }

  interface FastifyRequest {
    di: RequestContainer
  }
}

await app.register(inferdiFastify, {
  container: root,
  setupScope: (scope: RequestContainer, request) => {
    const ctx = scope.get('request')
    ctx.requestId = request.id
    ctx.ip = request.ip
  },
})

app.get('/users/:id', async (request) => {
  const { id } = request.params as { id: string }
  return request.di.get('users').profile(id)
})

Fastify の app.register は、インラインフックに対してプラグインのジェネリクスを十分に深く推論できないため、具体的なスコープ型が必要な場合はフックのパラメータに型注釈を付けてください。

オプション

オプションデフォルト説明
container必須app.di として公開されるルートコンテナ。
scopePerRequesttrueルート専用モードにするには false を設定します。
createScoperoot.createScope()カスタムのリクエストスコープ作成。非同期でもかまいません。
setupScopeなしonRequest でスコープをハイドレートします。非同期でもかまいません。
disposeScopescope.dispose()カスタムの破棄。同期でも非同期でもかまいません。
autoDisposetruefalse または false を返す述語は、所有権をアプリケーションコードに移譲します。
disposeRootOnClosefalsefastify.close() 中にルートを破棄します。
onDisposeErrorrequest.log.errorリクエストスコープの破棄失敗のシンク。

ルート専用モード

ハンドラーがシングルトンサービスのみを必要とする場合は、ルート専用モードを使用します。

ts
await app.register(inferdiFastify, {
  container: root,
  scopePerRequest: false,
})

app.get('/health', async function () {
  return this.di.get('health').check()
})

ルート専用モードは、リクエストデコレーションもリクエストライフサイクルフックもインストールしません。

ライフサイクルに関する注意

  • request.di は、セットアップが成功した後にのみ公開されます。
  • セットアップの失敗は、構築途中のスコープを破棄し、元のセットアップエラーのみを表面化します。
  • クリーンアップフックは、実行中に request.di を参照します。
  • 失敗したリクエストは skipInferdiDispose を無視し、autoDispose に従いつつ、それでもスコープを破棄します。
  • クライアント中断のクリーンアップは、スコープが公開された後に onRequestAbort で実行されます。
  • ルートの破棄エラーは、disposeRootOnClose が有効な場合にのみ fastify.close() を通じて伝播します。