rembrembdocs

Since all tRPC queries are normal HTTP GET requests, you can use standard HTTP cache headers to cache responses. This can make responses snappy, give your database a rest, and help scale your API.

Most tRPC adapters support a responseMeta callback that lets you set HTTP headers (including cache headers) based on the procedures being called.

server.ts

ts

import { initTRPC } from '@trpc/server';

import { createHTTPServer } from '@trpc/server/adapters/standalone';

import type { CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';

export const createContext = async (opts: CreateHTTPContextOptions) => {

return {

`req: opts.req,`

`res: opts.res,`

};

};

type Context = Awaited<ReturnType<typeof createContext>>;

export const t = initTRPC.context<Context>().create();

const waitFor = async (ms: number) =>

new Promise((resolve) => setTimeout(resolve, ms));

export const appRouter = t.router({

public: t.router({

`slowQueryCached: t.procedure.query(async (opts) => {`

  `await waitFor(5000); // wait for 5s`

  `return {`

    `lastUpdated: new Date().toJSON(),`

  `};`

`}),`

}),

});

// Exporting `type AppRouter` only exposes types that can be used for inference

// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export

export type AppRouter = typeof appRouter;

// export API handler

const server = createHTTPServer({

router: appRouter,

createContext,

responseMeta(opts) {

`const { paths, errors, type } = opts;`

``// assuming you have all your public routes with the keyword `public` in them``

`const allPublic = paths && paths.every((path) => path.includes('public'));`

`// checking that no procedures errored`

`const allOk = errors.length === 0;`

`// checking we're doing a query request`

`const isQuery = type === 'query';`

`if (allPublic && allOk && isQuery) {`

  `// cache request for 1 day + revalidate once every second`

  `const ONE_DAY_IN_SECONDS = 60 * 60 * 24;`

  `return {`

    `headers: new Headers([`

      `[`

        `'cache-control',`

        `` `s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS}`, ``

      `],`

    `]),`

  `};`

`}`

`return {};`

},

});

server.listen(3000);