Almacenamiento en caché de respuestas
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Dado que todas las consultas de tRPC son solicitudes HTTP GET normales, puedes usar cabeceras HTTP estándar para almacenar respuestas en caché. Esto puede acelerar las respuestas, darle un respiro a tu base de datos y ayudar a escalar tu API.
Siempre ten cuidado con el almacenamiento en caché, especialmente si manejas información personal.
Como la agrupación de solicitudes está activada por defecto, se recomienda configurar las cabeceras de caché en la función responseMeta y asegurarte de que no haya llamadas concurrentes que puedan incluir datos personales. Alternativamente, omite completamente las cabeceras de caché si existe una cabecera de autenticación o cookie.
También puedes usar un splitLink para separar tus solicitudes públicas de aquellas que deben ser privadas y no almacenadas en caché.
Uso de responseMeta para almacenar respuestas en caché
La mayoría de los adapters de tRPC soportan un callback responseMeta que te permite configurar cabeceras HTTP (incluyendo las de caché) según los procedimientos llamados.
Esto funciona con cualquier proveedor de hosting que soporte cabeceras HTTP estándar de caché (ej. Vercel, Cloudflare, AWS CloudFront).
server.tstsimport {initTRPC } from '@trpc/server';import {createHTTPServer } from '@trpc/server/adapters/standalone';import type {CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';export constcreateContext = async (opts :CreateHTTPContextOptions ) => {return {req :opts .req ,res :opts .res ,};};typeContext =Awaited <ReturnType <typeofcreateContext >>;export constt =initTRPC .context <Context >().create ();constwaitFor = async (ms : number) =>newPromise ((resolve ) =>setTimeout (resolve ,ms ));export constappRouter =t .router ({public :t .router ({slowQueryCached :t .procedure .query (async (opts ) => {awaitwaitFor (5000); // wait for 5sreturn {lastUpdated : newDate ().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-exportexport typeAppRouter = typeofappRouter ;// export API handlerconstserver =createHTTPServer ({router :appRouter ,createContext ,responseMeta (opts ) {const {paths ,errors ,type } =opts ;// assuming you have all your public routes with the keyword `public` in themconstallPublic =paths &&paths .every ((path ) =>path .includes ('public'));// checking that no procedures erroredconstallOk =errors .length === 0;// checking we're doing a query requestconstisQuery =type === 'query';if (allPublic &&allOk &&isQuery ) {// cache request for 1 day + revalidate once every secondconstONE_DAY_IN_SECONDS = 60 * 60 * 24;return {headers : newHeaders ([['cache-control',`s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS }`,],]),};}return {};},});server .listen (3000);
server.tstsimport {initTRPC } from '@trpc/server';import {createHTTPServer } from '@trpc/server/adapters/standalone';import type {CreateHTTPContextOptions } from '@trpc/server/adapters/standalone';export constcreateContext = async (opts :CreateHTTPContextOptions ) => {return {req :opts .req ,res :opts .res ,};};typeContext =Awaited <ReturnType <typeofcreateContext >>;export constt =initTRPC .context <Context >().create ();constwaitFor = async (ms : number) =>newPromise ((resolve ) =>setTimeout (resolve ,ms ));export constappRouter =t .router ({public :t .router ({slowQueryCached :t .procedure .query (async (opts ) => {awaitwaitFor (5000); // wait for 5sreturn {lastUpdated : newDate ().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-exportexport typeAppRouter = typeofappRouter ;// export API handlerconstserver =createHTTPServer ({router :appRouter ,createContext ,responseMeta (opts ) {const {paths ,errors ,type } =opts ;// assuming you have all your public routes with the keyword `public` in themconstallPublic =paths &&paths .every ((path ) =>path .includes ('public'));// checking that no procedures erroredconstallOk =errors .length === 0;// checking we're doing a query requestconstisQuery =type === 'query';if (allPublic &&allOk &&isQuery ) {// cache request for 1 day + revalidate once every secondconstONE_DAY_IN_SECONDS = 60 * 60 * 24;return {headers : newHeaders ([['cache-control',`s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS }`,],]),};}return {};},});server .listen (3000);
Si usas Next.js, consulta la guía de caché SSR para Next.js para ver ejemplos específicos usando createTRPCNext y el adapter de Next.js.