如何在顶层单次传入fastify instance供控制器内所有方法使用
Fastify实例仅顶层传递一次的实现方案
方案1:控制器类注入(最适合复杂控制器、有复用需求的场景)
把控制器改成类,在实例化的时候一次性传入fastify实例,所有类方法都可以通过实例属性访问fastify,不需要每个方法单独传参。
控制器文件修改
import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify' export default class RootController { private fastify: FastifyInstance constructor(fastify: FastifyInstance) { this.fastify = fastify } async index(request: FastifyRequest, reply: FastifyReply) { const hugs = this.fastify.someSupport() reply.send({ status: 'ok', love: hugs }) } async show(request: FastifyRequest, reply: FastifyReply) { const hugs = 'extra ' + this.fastify.someSupport() reply.send({ status: 'ok', love: hugs }) } }
路由文件修改
import { FastifyPluginAsync } from 'fastify' import RootController from '../root.controller' const root: FastifyPluginAsync = async (fastify, opts): Promise<void> => { // 仅此处实例化一次,传入fastify const controller = new RootController(fastify) fastify.get('/', controller.index.bind(controller)) fastify.get('/show', controller.show.bind(controller)) } export default root
方案2:闭包工厂函数(适合轻量控制器、不想用类的场景)
写一个工厂函数,接收fastify后返回包含所有控制器方法的对象,所有方法通过闭包共享同一个fastify实例。
控制器文件修改
import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify' export default function createRootController(fastify: FastifyInstance) { return { async index(request: FastifyRequest, reply: FastifyReply) { const hugs = fastify.someSupport() reply.send({ status: 'ok', love: hugs }) }, async show(request: FastifyRequest, reply: FastifyReply) { const hugs = 'extra ' + fastify.someSupport() reply.send({ status: 'ok', love: hugs }) } } }
路由文件修改
import { FastifyPluginAsync } from 'fastify' import createRootController from '../root.controller' const root: FastifyPluginAsync = async (fastify, opts): Promise<void> => { // 仅此处调用一次工厂函数,传入fastify const controller = createRootController(fastify) fastify.get('/', controller.index) fastify.get('/show', controller.show) } export default root
方案3:直接从请求对象获取(零注入成本,最省事)
Fastify 原生在每个请求对象上挂载了server属性,就是当前的Fastify实例,不需要主动传递,直接在控制器里访问即可。
控制器文件修改
import { FastifyRequest, FastifyReply } from 'fastify' export default { async index(request: FastifyRequest, reply: FastifyReply) { const hugs = request.server.someSupport() reply.send({ status: 'ok', love: hugs }) }, async show(request: FastifyRequest, reply: FastifyReply) { const hugs = 'extra ' + request.server.someSupport() reply.send({ status: 'ok', love: hugs }) } }
路由文件修改
import { FastifyPluginAsync } from 'fastify' import RootController from '../root.controller' const root: FastifyPluginAsync = async (fastify, opts): Promise<void> => { // 不需要传递fastify,直接注册方法即可 fastify.get('/', RootController.index) fastify.get('/show', RootController.show) } export default root
不同方案适用场景:
- 方案3适合绝大多数简单场景,不需要修改注入逻辑,代码量最小
- 方案2适合偏好函数式编程、不需要类特性的场景
- 方案1适合控制器逻辑复杂、需要继承/混入、或者有多处复用控制器逻辑的场景
内容的提问来源于stack exchange,提问作者mybigman
相关产品推荐
相关产品推荐

