skip to Main Content

I’m studying Fastify and register plugin with @fastify/redis like this

  app.register(redisPlugin, {
    client: initRedis(app.config.REDIS_INTERNAL__HOST, app.config.REDIS_INTERNAL__PASS),
    closeClient: true,
  });

And register route:

import { FastifyInstance, FastifyPluginAsync } from "fastify";

import v1Routes from "./v1/index.js";

const routes: FastifyPluginAsync = async (fastify: FastifyInstance): Promise<void> => {
  fastify.register(v1Routes, { prefix: "/v1" });
};

export default routes;

and inside v1 route

const v1Routes: FastifyPluginAsync = async (fastify: FastifyInstance): Promise<void> => {
  fastify.register(seedlogsRoutes, { prefix: "/seedlogs" });
};

route with controller

const orderRoutes: FastifyPluginAsync = async (fastify: FastifyInstance) => {
  fastify.get("/", getOrders);
};

export default orderRoutes;

with getOrders function, I can access redis like this:

const getOrders = async (request: FastifyRequest, reply: FastifyReply) => {
  const redis = request.server.redis;
  await redis.set("orders", "abc");
  const orders = await redis.get("orders");
  return { message: "Orders", orders };
};

But what if I want to access redis from an inner service, how can I access redis from the
FastifyInstance, like

const cacheOrder = async (order) => {
  await redis.set("order",order)
}

Should I init a client before passing it to the plugin and reuse it wherever does not have access to the FastifyInstance?

import redis from "./cache/redis.js"

I try to search on Google but still can not find any satisfactory answer. Any comment is appreciated. Many thanks.

2

Answers


  1. Should I init a client before passing it to the plugin and reuse it wherever does not have access to the FastifyInstance?

    No, or you will have global clients that is a foot-gun. You need to propagate the redis client attached to the Fastify server.

    This code can be simplified:

    async function getOrders (request: FastifyRequest, reply: FastifyReply) {
      // in a named function, `this` is the Fastify server
      const redis = this.redis;
      await redis.set("orders", "abc");
      const orders = await redis.get("orders");
      return { message: "Orders", orders };
    };
    

    how can I access redis from the FastifyInstance

    Be sure to have the right server instance, that is bound to this almost everywhere in:

    • hooks
    • decorators
    • route handlers

    handler(request, reply): the function that will handle this request. The Fastify server will be bound to this when the handler is called. Note: using an arrow function will break the binding of this.

    Documentation reference: https://fastify.dev/docs/latest/Reference/Routes/#routes-options

    Useful reading: https://backend.cafe/the-complete-guide-to-the-fastify-plugin-system

    Login or Signup to reply.
  2. With Decorators, you can access it from anywhere within the Fastify context, including routes, hooks, and services.

    app.register(redisPlugin, {
      client: initRedis(app.config.REDIS_INTERNAL__HOST, app.config.REDIS_INTERNAL__PASS),
      closeClient: true,
    });
    
    app.decorate('redis', app.redis); // Decorate Fastify instance with the Redis client
    
    

    Then, in your service or other parts of your application, you can access it using fastify.redis:

    const cacheOrder = async (order, fastify) => {
      await fastify.redis.set('order', order);
    };
    
    

    When calling this function, pass the Fastify instance:

    const getOrders = async (request, reply) => {
      const orders = await cacheOrder('someOrder', request.server);
      return { message: 'Orders', orders };
    };
    

    This will work.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search