サーバーサイドヘルパー
このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →
サーバーサイドヘルパーは、サーバー上でクエリをプリフェッチするために使用できる一連のヘルパー関数を提供します。これはSSGで有用なだけでなく、ssr: trueを使用しない場合のSSRにも役立ちます。
サーバーサイドヘルパーによるプリフェッチでは、クエリキャッシュをサーバー上で事前に埋めることができ、これらのクエリがクライアント側で初期フェッチを必要としないことを意味します。
サーバーサイドヘルパーの2つの使用方法
1. 内部ルーター
この方法は、tRPCルーターに直接アクセスできる場合、例えばモノリシックなNext.jsアプリケーションを開発する際に使用されます。
ヘルパーを使用すると、tRPCはサーバーサイドコールと同様に、HTTPリクエストなしでサーバー上で直接プロシージャを呼び出します。
つまり、通常のようにリクエスト(req)やレスポンス(res)を手元で扱えません。コンテキスト作成時に通常埋められるreqやresを含まないコンテキストでサーバーサイドヘルパーを初期化してください。このシナリオでは"内部"と"外部"コンテキストの概念をお勧めします。
tsimport {createServerSideHelpers } from '@trpc/react-query/server';import {createContext } from './server/context';import {appRouter } from './server/routers/_app';importsuperjson from 'superjson';consthelpers =createServerSideHelpers ({router :appRouter ,ctx : awaitcreateContext (),transformer :superjson ,});
tsimport {createServerSideHelpers } from '@trpc/react-query/server';import {createContext } from './server/context';import {appRouter } from './server/routers/_app';importsuperjson from 'superjson';consthelpers =createServerSideHelpers ({router :appRouter ,ctx : awaitcreateContext (),transformer :superjson ,});
2. 外部ルーター
この方法は、tRPCルーターに直接アクセスできない場合、例えばNext.jsアプリケーションとスタンドアロンなAPIを別々にホストして開発する場合に使用されます。
tsimport {createTRPCClient ,httpBatchLink } from '@trpc/client';import {createServerSideHelpers } from '@trpc/react-query/server';import type {AppRouter } from './server/router';importsuperjson from 'superjson';constproxyClient =createTRPCClient <AppRouter >({links : [httpBatchLink ({url : 'http://localhost:3000/api/trpc',}),],});consthelpers =createServerSideHelpers ({client :proxyClient ,});
tsimport {createTRPCClient ,httpBatchLink } from '@trpc/client';import {createServerSideHelpers } from '@trpc/react-query/server';import type {AppRouter } from './server/router';importsuperjson from 'superjson';constproxyClient =createTRPCClient <AppRouter >({links : [httpBatchLink ({url : 'http://localhost:3000/api/trpc',}),],});consthelpers =createServerSideHelpers ({client :proxyClient ,});
ヘルパーの使用方法
サーバーサイドヘルパーメソッドは、ルーター構造を反映したオブジェクトを返します。このオブジェクトのキーはすべてのルーターとなりますが、useQueryやuseMutationではなく、prefetch、fetch、prefetchInfinite、fetchInfinite関数が提供されます。
prefetchとfetchの主な違いは、fetchが通常の関数呼び出しのように動作してクエリ結果を返すのに対し、prefetchは結果を返さず例外もスローしない点です。そのような動作が必要な場合は代わりにfetchを使用してください。prefetchはクエリをキャッシュに追加し、これをデハイドレートしてクライアントに送信します。
ts// In getServerSideProps / getStaticProps:constprops = {// very important - use `trpcState` as the keytrpcState :helpers .dehydrate (),};
ts// In getServerSideProps / getStaticProps:constprops = {// very important - use `trpcState` as the keytrpcState :helpers .dehydrate (),};
経験則として、クライアント側で必要とわかっているクエリにはprefetchを、サーバー側で結果を使用したいクエリにはfetchを使用します。
これらの関数はすべてreact-query関数のラッパーです。詳細については公式ドキュメントを参照してください。
完全なサンプルはE2E SSGテスト例をご覧ください。
Next.jsの使用例
pages/posts/[id].tsxtsximport {createServerSideHelpers } from '@trpc/react-query/server';import {appRouter } from './server/routers/_app';import {trpc } from './utils/trpc';import {GetServerSidePropsContext ,InferGetServerSidePropsType } from 'next';importsuperjson from 'superjson';export async functiongetServerSideProps (context :GetServerSidePropsContext <{id : string }>,) {consthelpers =createServerSideHelpers ({router :appRouter ,ctx : {},transformer :superjson ,});constid =context .params ?.id as string;/** Prefetching the `post.byId` query.* `prefetch` does not return the result and never throws - if you need that behavior, use `fetch` instead.*/awaithelpers .post .byId .prefetch ({id });// Make sure to return { props: { trpcState: helpers.dehydrate() } }return {props : {trpcState :helpers .dehydrate (),id ,},};}export default functionPostViewPage (props :InferGetServerSidePropsType <typeofgetServerSideProps >,) {const {id } =props ;constpostQuery =trpc .post .byId .useQuery ({id });if (postQuery .status !== 'success') {// won't happen since the query has been prefetchedreturn <>Loading...</>;}const {data } =postQuery ;return (<><h1 >{data .title }</h1 ><em >Created {data .createdAt .toLocaleDateString ()}</em ><p >{data .text }</p ><h2 >Raw data:</h2 ><pre >{JSON .stringify (data , null, 4)}</pre ></>);}
pages/posts/[id].tsxtsximport {createServerSideHelpers } from '@trpc/react-query/server';import {appRouter } from './server/routers/_app';import {trpc } from './utils/trpc';import {GetServerSidePropsContext ,InferGetServerSidePropsType } from 'next';importsuperjson from 'superjson';export async functiongetServerSideProps (context :GetServerSidePropsContext <{id : string }>,) {consthelpers =createServerSideHelpers ({router :appRouter ,ctx : {},transformer :superjson ,});constid =context .params ?.id as string;/** Prefetching the `post.byId` query.* `prefetch` does not return the result and never throws - if you need that behavior, use `fetch` instead.*/awaithelpers .post .byId .prefetch ({id });// Make sure to return { props: { trpcState: helpers.dehydrate() } }return {props : {trpcState :helpers .dehydrate (),id ,},};}export default functionPostViewPage (props :InferGetServerSidePropsType <typeofgetServerSideProps >,) {const {id } =props ;constpostQuery =trpc .post .byId .useQuery ({id });if (postQuery .status !== 'success') {// won't happen since the query has been prefetchedreturn <>Loading...</>;}const {data } =postQuery ;return (<><h1 >{data .title }</h1 ><em >Created {data .createdAt .toLocaleDateString ()}</em ><p >{data .text }</p ><h2 >Raw data:</h2 ><pre >{JSON .stringify (data , null, 4)}</pre ></>);}