响应缓存
非官方测试版翻译
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
由于所有 tRPC 查询都是标准的 HTTP GET 请求,因此你可以使用标准的 HTTP 缓存头来缓存响应。这能够显著提升响应速度,减轻数据库压力,并帮助扩展你的 API。
信息
使用缓存时务必谨慎——尤其是在处理个人信息时。
由于默认启用了批处理,建议在 responseMeta 函数中设置缓存头,并确保没有可能包含个人数据的并发调用——或者,如果存在授权头或 cookie,则应完全省略缓存头。
你也可以使用 splitLink 将公共请求与那些应保持私有且不缓存的请求分开。
使用 responseMeta 缓存响应
大多数 tRPC 适配器都支持 responseMeta 回调函数,允许你根据被调用的过程设置 HTTP 头(包括缓存头)。
这适用于任何支持标准 HTTP 缓存头的托管服务提供商(例如 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);
技巧
如果你正在使用 Next.js,请参阅 Next.js SSR 缓存指南,了解使用 createTRPCNext 和 Next.js 适配器的特定于 Next.js 的缓存示例。