レスポンスキャッシュ
非公式ベータ版翻訳
このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →
すべてのtRPCクエリは標準的なHTTP GETリクエストであるため、標準的なHTTPキャッシュヘッダーを使用してレスポンスをキャッシュできます。これによりレスポンスが高速化され、データベースの負荷が軽減され、APIのスケーリングが容易になります。
情報
キャッシュには常に注意が必要です - 特に個人情報を扱う場合には慎重に対応してください。
バッチ処理がデフォルトで有効になっているため、キャッシュヘッダーはresponseMeta関数で設定し、個人データを含む可能性のある同時呼び出しがないことを確認することを推奨します。あるいは、認証ヘッダーやクッキーが存在する場合はキャッシュヘッダーを完全に省略してください。
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を使用している場合は、createTRPCNextとNext.jsアダプターを使用したNext.js固有のキャッシュ例についてNext.js SSRキャッシュガイドを参照してください。