教程 fastify tutorial

插件介绍与意义

Fastify 的插件系统是其核心设计理念之一,支持高度模块化、可复用和可组合的服务开发方式。

什么是插件?

在 Fastify 中,插件本质上是一个封装了功能的函数,它接受 fastify 实例作为参数,并可以注册路由、装饰器、钩子等功能:

js
async function myPlugin(fastify, options) {
  fastify.get('/ping', async () => 'pong');
}

module.exports = myPlugin;

注册插件:

js
const fastify = require('fastify')();

fastify.register(require('./my-plugin'));

插件的作用

  • 逻辑拆分:将不同功能划分为多个模块,增强可维护性。
  • 功能复用:公共功能如认证、数据库连接、日志系统等可在多个项目间共享。
  • 隔离作用域:插件内部注册的路由、装饰器默认不会污染全局实例。
  • 插件链式组合:可通过注册顺序灵活组合多个插件。

插件注册参数

注册插件时可以传递配置选项:

js
fastify.register(require('./auth-plugin'), { secret: 'abc123' });

插件内部可通过 options 参数接收配置。

可选择作用域封闭

通过 { encapsulate: true/false } 控制作用域:

  • 默认封装作用域,插件中的内容不会暴露给其他插件。
  • 使用 fastify-plugin 可以显式定义为全局插件。

使用 fastify-plugin

使用 fastify-plugin 可以:

  • 控制插件的封装行为
  • 定义依赖关系
  • 确保插件只注册一次

示例:

js
const fp = require('fastify-plugin');

async function dbConnector(fastify, opts) {
  fastify.decorate('db', { query: () => 'mock result' });
}

module.exports = fp(dbConnector);

示例:数据库插件

js
async function dbPlugin(fastify, options) {
  const db = await connectToDatabase();
  fastify.decorate('db', db);
}

fastify.register(dbPlugin);

在其他路由中使用:

js
fastify.get('/users', async (request, reply) => {
  const users = await fastify.db.query('SELECT * FROM users');
  return users;
});

插件体系下的开发模式

  • 项目可按功能模块(如用户、文章、支付)组织为多个插件
  • 插件可以包含路由、schema、服务逻辑、钩子
  • 利于团队协作和大规模系统开发
plaintext
src/
├── plugins/
│   ├── auth.js
│   └── db.js
├── routes/
│   ├── user.js
│   └── article.js

每个模块都是插件,只需通过 register 注册即可。

js
fastify.register(require('./plugins/db'));
fastify.register(require('./routes/user'));