Open6

Nuxt3のserver/の勉強メモ

tokuda109tokuda109

https://nuxt.com/docs/guide/directory-structure/server を見ている。

Nuxt3 の server/ ディレクトリではサーバー側の実装をすることができる。
実装をするだけで、Nuxt3 が自動的に読み込んで処理をしてくれる機能があり、機能毎に次の5つに分類されている。

  • API
  • Plugins
  • Routes
  • Middleware
  • Utilities

ディレクトリ的には次のような構成になり、ディレクトリ構造のルールに沿っていると、実装ファイルはアプリケーションの実行時に自動的に読み込まれる。

server/
├ api/
│  └ hello.ts
├ plugins/
│  └ plugin.ts
├ routes/
│  └ bonjour.ts
├ middleware/
│  └ log.ts
└ utils/
   └ helper.ts

以下、1つずつどのような機能なのか、どのように使うのかを調べていく。

tokuda109tokuda109

API & Routes

実装イメージ

api/ ディレクトリに実装したファイルは次のようになる。

server/api/hello.ts
export default defineEventHandler(() => {
  return {
    hello: 'world'
  }
})

また、event.node.res.end() でレスポンスを返却することもできる。

server/api/hello.ts
import { type H3Event } from 'h3';

export default defineEventHandler((event: H3Event) => {
  event.node.res.end('hello');
})

ルーティング

api/ ディレクトリ以下の構造がそのままルーティングとして反映される。

tokuda109tokuda109

Middleware

Middleware は、Routes よりも先に、アプリケーションに対する全てのリクエストに対して処理される。
また、Middleware は Routes や API と違って、レスポンスは返さない。

使い方のイメージとしては、Routes や API の前段の処理として、次の処理を行うために使う。

  • 渡ってくるコンテキストをチェックしたり、データを追加して後続に渡す
  • 例外を投げる

実装イメージ

公式ドキュメントにサンプルコードとして、次の2つがある。

server/middleware/log.ts
export default defineEventHandler((event) => {
  console.log('New request: ' + getRequestURL(event))
})
server/middleware/auth.ts
export default defineEventHandler((event) => {
  event.context.auth = { user: 123 }
})

2つ目の context.auth として渡している箇所が気になったので調べた。

server/api/auth.ts
import { type H3Event } from 'h3';

export default defineEventHandler((event: H3Event) => {
  return {
    user: {
      id: event.context.auth.user
    }
  }
});

Middleware で event.context に追加したデータを、API や Routes で上記のように取得できる。

tokuda109tokuda109

Plugins

Plugins は Nitroのプラグインを実装し、Nitro の機能を拡張したり、Nitro のライフサイクルイベントをフックして任意の処理をします。
今まで見てきた API や Middleware は、Nuxt3 の HTTP サーバーの機能を提供する h3 に対するハンドラの実装であったが、Plugins は Nuxt3 のサーバーサイドの機能を実装するための Nitro に対する実装をすることになる。また、Nitro は内部的に h3 を使っている。

メモ: ドキュメントを読んで、Nuxt3、Nitro、h3 の関係や、それぞれの処理の関係性をもっと正確に知る必要があると感じたが、別の機会にする。

実装イメージ

server/plugins/nitroPlugin.ts
export default defineNitroPlugin((nitroApp) => {
  console.log('Nitro plugin', nitroApp)
})

Nitro Runtime Hooks

nitro.hooks.hook('close', () => {});
nitro.hooks.hook('error', (error, { event? }) => {});
nitro.hooks.hook('render:response', (response, { event }) => {});
nitro.hooks.hook('request', (event) => {});
nitro.hooks.hook('beforeResponse', (event, { body }) => {});
nitro.hooks.hook('afterResponse', (event, { body }) => {});

参考

tokuda109tokuda109

server/tsconfig.json

Nuxt のバージョン3.5以上から使えるようになったもので、server/tsconfig.json ファイルを作成し、次のように実装することで Nitro の実装に必要な TypeScript 設定を自動で読み込んでくれるようになる。

server/tsconfig.json
{
  "extends": "../.nuxt/tsconfig.server.json"
}