第7章
Fastifyのpluginsとencapsulation — 機能単位でAPIを分割する
約4分
Fastifyでは、機能を分割するときにpluginを使います。pluginは「ルート、hooks、decorator、設定をまとめた部品」です。そしてFastifyのpluginには、encapsulation という重要な性質があります。
Fastifyのpluginは、単なるファイル分割ではありません。登録した範囲にだけ設定やhooksを効かせるための境界です。register() の構文
構文: fastify.register(plugin, options)
| 引数 | 型 | 説明 |
|---|---|---|
plugin | function | Fastifyインスタンスを受け取ってルートなどを登録する関数 |
options | object | pluginへ渡す設定。prefix なども指定できる |
戻り値: Fastifyインスタンス。登録処理として使います。
fastify.register(todoRoutes, { prefix: '/todos' });js
ルートをpluginに分ける
src/routes/todos.js を作ります。
const todos = [
{ id: 1, title: 'Fastifyを学ぶ', completed: false },
];
export async function todoRoutes(fastify) {
fastify.get('/', async () => {
return todos;
});
fastify.get('/:id', async (request, reply) => {
const todo = todos.find((item) => item.id === Number(request.params.id));
if (!todo) {
return reply.code(404).send({ error: 'TODO_NOT_FOUND' });
}
return todo;
});
}js
src/app.js で登録します。
import Fastify from 'fastify';
import { todoRoutes } from './routes/todos.js';
export function buildApp() {
const fastify = Fastify({ logger: true });
fastify.register(todoRoutes, { prefix: '/todos' });
return fastify;
}js
この場合、plugin内の / は /todos、/:id は /todos/:id として公開されます。
encapsulationとは
Fastifyのpluginは、親子関係を持つスコープを作ります。pluginの中で登録したhookやdecoratorは、基本的にそのpluginと子pluginの中で有効になります。
たとえば、管理画面用のpluginだけに認証hookを付けたい場合、/admin 配下に閉じ込められます。
async function adminRoutes(fastify) {
fastify.addHook('preHandler', async (request, reply) => {
if (request.headers.authorization !== 'Bearer secret') {
return reply.code(401).send({ error: 'UNAUTHORIZED' });
}
});
fastify.get('/stats', async () => {
return { users: 10 };
});
}
fastify.register(adminRoutes, { prefix: '/admin' });js
このhookは /admin/stats には効きますが、別のpluginとして登録した /todos には効きません。
学習者Expressの app.use('/admin', auth) と似ていますか?
先生近いですが、Fastifyではhooksやdecoratorもスコープに閉じ込められます。大きいAPIほど、この境界が効いてきます。
prefixでURLをまとめる
register() の prefix を使うと、plugin内のルートに共通のURLを付けられます。
fastify.register(todoRoutes, { prefix: '/api/todos' });
fastify.register(adminRoutes, { prefix: '/api/admin' });js
| plugin内のpath | prefix | 実際のURL |
|---|---|---|
/ | /api/todos | /api/todos |
/:id | /api/todos | /api/todos/:id |
/stats | /api/admin | /api/admin/stats |
参考リンク
次章では、リクエストのライフサイクルに処理を差し込むhooksを学びます。
Node.jsクイズに挑戦するモジュール分割やHTTPサーバーの知識をクイズで確認しよう
