tRPCttRPC
Powered by
MrJohzM
tRPC•11mo ago•
6 replies
MrJohz

How can I access the session in fastify when using `useWSS: true`?

I've got a fastify/trpc application that looks something like this:

  await using app = Fastify({
    loggerInstance: logger,
    bodyLimit: 5 * 1024 * 1024,
    https: stores.config.sslOptions ?? null,
    maxParamLength: 5000,
  });

  app.register(ws);
  app.register(fastifyCookie);
  app.register(fastifySession, {
    secret: "super secret, don't look at me",
  });

  function createContext({ req }: CreateFastifyContextOptions) {
    console.log(req.session); // logs "undefined"
    return {};
  }

  app.register(fastifyTRPCPlugin, {
    prefix: "/trpc",
    useWSS: true,
    keepAlive: { enabled: true, pingMs: 50 * 1000 },
    trpcOptions: { router, onError, createContext },
  });
  await using app = Fastify({
    loggerInstance: logger,
    bodyLimit: 5 * 1024 * 1024,
    https: stores.config.sslOptions ?? null,
    maxParamLength: 5000,
  });

  app.register(ws);
  app.register(fastifyCookie);
  app.register(fastifySession, {
    secret: "super secret, don't look at me",
  });

  function createContext({ req }: CreateFastifyContextOptions) {
    console.log(req.session); // logs "undefined"
    return {};
  }

  app.register(fastifyTRPCPlugin, {
    prefix: "/trpc",
    useWSS: true,
    keepAlive: { enabled: true, pingMs: 50 * 1000 },
    trpcOptions: { router, onError, createContext },
  });


I would expect that the
req
req
in the
createContext
createContext
function would have access to the session (and it does if
useWSS
useWSS
is false). However, when using TRPC with websockets, it currently consistently logs
undefined
undefined
.

I assume this is because I'm misconfiguring something somewhere, but I'm not sure what, and I'm not sure how to solve this. Has anyone experienced this, or does anyone have any suggestions about how to resolve this? Thanks in advance!
Solution
Hi @Mr. Joker, I ended up writing my solution up on my blog, you can read that here: https://jonathan-frere.com/posts/trpc-fastify-websockets/

Specifically, the solution I found was this:

// create a new scope so that the hook we add later will only
// affect tRPC-specific requests
app.register((app) => {
  // use a WeakMap to avoid leaking memory by holding on to
  // requests longer than necessary
  const REQS = new WeakMap<
    FastifyRequest | IncomingMessage,
    FastifyRequest
  >();

  app.addHook("onRequest", async (req) => {
    // associate each raw `IncomingMessage` (`req.raw`) with
    // the original `IncomingMessage`
    REQS.set(req.raw, req);
  });

  app.register(fastifyTRPCPlugin, {
    prefix: "/trpc",
    useWSS: true,
    trpcOptions: {
      router,
      onError,
      createContext: ({ req }) => {
        // given either a `FastifyRequest` or an
        // `IncomingMessage`, fetch the related
        // `FastifyRequest` that we saved earlier
        const realReq = REQS.get(req.raw ?? req);
        if (!realReq)
          throw new Error("This should never happen");

        console.log(realReq.session); // logs the session object
        return {};
      },
    },
  });
});
// create a new scope so that the hook we add later will only
// affect tRPC-specific requests
app.register((app) => {
  // use a WeakMap to avoid leaking memory by holding on to
  // requests longer than necessary
  const REQS = new WeakMap<
    FastifyRequest | IncomingMessage,
    FastifyRequest
  >();

  app.addHook("onRequest", async (req) => {
    // associate each raw `IncomingMessage` (`req.raw`) with
    // the original `IncomingMessage`
    REQS.set(req.raw, req);
  });

  app.register(fastifyTRPCPlugin, {
    prefix: "/trpc",
    useWSS: true,
    trpcOptions: {
      router,
      onError,
      createContext: ({ req }) => {
        // given either a `FastifyRequest` or an
        // `IncomingMessage`, fetch the related
        // `FastifyRequest` that we saved earlier
        const realReq = REQS.get(req.raw ?? req);
        if (!realReq)
          throw new Error("This should never happen");

        console.log(realReq.session); // logs the session object
        return {};
      },
    },
  });
});
Accessing Fastify Sessions via tRPC Websockets | Jonathan's Blog
This is a quick post to point out a potential issue that might catch you out with using Fastify’s sessions mechanism alongside tRPC’s websockets transport, and how I’ve fixed it in my projects.
The problem happens with an application that looks something like this:
const app = Fastify(); app.register(ws); app.register(fastifyCookie); app.r...
Jump to solution
tRPCJoin
Move Fast & Break Nothing. End-to-end typesafe APIs made easy.
5,015Members
Resources
Recent Announcements

Similar Threads

Was this page helpful?

Similar Threads

Throwing fastify errors when using fastify adapter
rdRrd / ❓-help
3y ago
Route not found when using Fastify adapter
TeixeiraTTeixeira / ❓-help
13mo ago
How can I disable batching with fastify adapter?
BarakondaBBarakonda / ❓-help
3y ago
How can I reset the cursor when using useInfiniteQuery?
AdnanAAdnan / ❓-help
3y ago