Saltar al contenido principal
Versión: 10.x

Helpers para el lado del servidor

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Los helpers para el lado del servidor te proporcionan un conjunto de funciones auxiliares que puedes usar para precargar consultas en el servidor. Esto es útil para SSG (Static Site Generation), pero también para SSR (Server-Side Rendering) si optas por no usar ssr: true.

La precarga mediante estos helpers permite poblar la caché de consultas en el servidor, lo que significa que estas consultas no tendrán que ejecutarse inicialmente en el cliente.

Hay 2 formas de usar los helpers para el lado del servidor

1. Router interno

Este método se usa cuando tienes acceso directo a tu router tRPC. Por ejemplo, cuando desarrollas una aplicación monolítica con Next.js.

Usar estos helpers hace que tRPC llame a tus procedimientos directamente en el servidor sin una solicitud HTTP, similar a las llamadas en el lado del servidor. Esto también significa que no tendrás a mano la solicitud y la respuesta como sueles hacer. Asegúrate de instanciar los helpers con un contexto sin req y res, que normalmente se completan mediante la creación del contexto. Recomendamos el concepto de contexto "interno" y "externo" en ese escenario.

ts
import { createServerSideHelpers } from '@trpc/react-query/server';
import { createContext } from '~/server/context';
import superjson from 'superjson';
const helpers = createServerSideHelpers({
router: appRouter,
ctx: await createContext(),
transformer: superjson, // optional - adds superjson serialization
});
ts
import { createServerSideHelpers } from '@trpc/react-query/server';
import { createContext } from '~/server/context';
import superjson from 'superjson';
const helpers = createServerSideHelpers({
router: appRouter,
ctx: await createContext(),
transformer: superjson, // optional - adds superjson serialization
});

2. Router externo

Este método se usa cuando no tienes acceso directo a tu router tRPC. Por ejemplo, cuando desarrollas una aplicación Next.js con una API independiente alojada por separado.

ts
import { createTRPCProxyClient } from '@trpc/client';
import { createServerSideHelpers } from '@trpc/react-query/server';
import superjson from 'superjson';
const proxyClient = createTRPCProxyClient<AppRouter>({
links: [
httpBatchLink({
url: 'http://localhost:3000/api/trpc',
}),
],
transformer: superjson,
});
const helpers = createServerSideHelpers({
client: proxyClient,
});
ts
import { createTRPCProxyClient } from '@trpc/client';
import { createServerSideHelpers } from '@trpc/react-query/server';
import superjson from 'superjson';
const proxyClient = createTRPCProxyClient<AppRouter>({
links: [
httpBatchLink({
url: 'http://localhost:3000/api/trpc',
}),
],
transformer: superjson,
});
const helpers = createServerSideHelpers({
client: proxyClient,
});

Uso de los helpers

Los métodos de estos helpers devuelven un objeto similar al cliente tRPC, con todos tus routers como claves. Sin embargo, en lugar de useQuery y useMutation, obtienes funciones prefetch, fetch, prefetchInfinite y fetchInfinite.

La diferencia principal entre prefetch y fetch es que fetch actúa como una llamada de función normal, devolviendo el resultado de la consulta, mientras que prefetch no devuelve el resultado y nunca lanza errores - si necesitas ese comportamiento, usa fetch en su lugar. En cambio, prefetch agregará la consulta a la caché, que luego deshidratas y envías al cliente.

ts
return {
props: {
// very important - use `trpcState` as the key
trpcState: helpers.dehydrate(),
},
};
ts
return {
props: {
// very important - use `trpcState` as the key
trpcState: helpers.dehydrate(),
},
};

La regla general es: usa prefetch para consultas que sabes que necesitarás en el cliente, y fetch para consultas cuyo resultado quieras usar en el servidor.

Todas las funciones son wrappers alrededor de las funciones de react-query. Por favor, consulta su documentación para aprender más sobre ellas en detalle.

información

Para un ejemplo completo, consult nuestro ejemplo de prueba E2E SSG

Ejemplo con Next.js

pages/posts/[id].tsx
tsx
import { createServerSideHelpers } from '@trpc/react-query/server';
import { GetServerSidePropsContext, InferGetServerSidePropsType } from 'next';
import { appRouter } from 'server/routers/_app';
import superjson from 'superjson';
import { trpc } from 'utils/trpc';
export async function getServerSideProps(
context: GetServerSidePropsContext<{ id: string }>,
) {
const helpers = createServerSideHelpers({
router: appRouter,
ctx: {},
transformer: superjson,
});
const id = 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.
*/
await helpers.post.byId.prefetch({ id });
// Make sure to return { props: { trpcState: helpers.dehydrate() } }
return {
props: {
trpcState: helpers.dehydrate(),
id,
},
};
}
export default function PostViewPage(
props: InferGetServerSidePropsType<typeof getServerSideProps>,
) {
const { id } = props;
const postQuery = trpc.post.byId.useQuery({ id });
if (postQuery.status !== 'success') {
// won't happen since the query has been prefetched
return <>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].tsx
tsx
import { createServerSideHelpers } from '@trpc/react-query/server';
import { GetServerSidePropsContext, InferGetServerSidePropsType } from 'next';
import { appRouter } from 'server/routers/_app';
import superjson from 'superjson';
import { trpc } from 'utils/trpc';
export async function getServerSideProps(
context: GetServerSidePropsContext<{ id: string }>,
) {
const helpers = createServerSideHelpers({
router: appRouter,
ctx: {},
transformer: superjson,
});
const id = 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.
*/
await helpers.post.byId.prefetch({ id });
// Make sure to return { props: { trpcState: helpers.dehydrate() } }
return {
props: {
trpcState: helpers.dehydrate(),
id,
},
};
}
export default function PostViewPage(
props: InferGetServerSidePropsType<typeof getServerSideProps>,
) {
const { id } = props;
const postQuery = trpc.post.byId.useQuery({ id });
if (postQuery.status !== 'success') {
// won't happen since the query has been prefetched
return <>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>
</>
);
}