Saltar al contenido principal
Versión: 10.x

Definir procedimientos

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 →

Un procedimiento es una función expuesta al cliente, que puede ser uno de:

  • una Query (consulta): se utiliza para obtener datos y generalmente no modifica información

  • una Mutation (mutación): se emplea para enviar datos, frecuentemente para crear/actualizar/eliminar

  • una Subscription (suscripción): puede que no la necesites, y tenemos documentación dedicada

Los procedimientos en tRPC son primitivas muy flexibles para crear funciones backend. Utilizan un patrón de construcción inmutable, lo que permite crear procedimientos base reutilizables que comparten funcionalidad entre múltiples procedimientos.

Escritura de procedimientos

El objeto t creado durante la configuración de tRPC devuelve un t.procedure inicial sobre el que se construyen todos los demás procedimientos:

ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
 
const t = initTRPC.context<{ signGuestBook: () => Promise<void> }>().create();
 
export const router = t.router;
export const publicProcedure = t.procedure;
 
const appRouter = router({
// Queries are the best place to fetch data
hello: publicProcedure.query(() => {
return {
message: 'hello world',
};
}),
 
// Mutations are the best place to do things like updating a database
goodbye: publicProcedure.mutation(async (opts) => {
await opts.ctx.signGuestBook();
 
return {
message: 'goodbye!',
};
}),
});
ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
 
const t = initTRPC.context<{ signGuestBook: () => Promise<void> }>().create();
 
export const router = t.router;
export const publicProcedure = t.procedure;
 
const appRouter = router({
// Queries are the best place to fetch data
hello: publicProcedure.query(() => {
return {
message: 'hello world',
};
}),
 
// Mutations are the best place to do things like updating a database
goodbye: publicProcedure.mutation(async (opts) => {
await opts.ctx.signGuestBook();
 
return {
message: 'goodbye!',
};
}),
});

Procedimientos base reutilizables

Como patrón general, recomendamos renombrar y exportar t.procedure como publicProcedure, lo que permite crear otros procedimientos con nombre para casos de uso específicos y exportarlos también. Este patrón se llama "procedimientos base" y es fundamental para reutilizar código y comportamiento en tRPC; es probable que cada aplicación lo necesite.

El siguiente ejemplo toma un input del usuario y los autoriza como protectores habitantes de un pueblo. Obviamente, este es un ejemplo artificial por simplicidad y no es una forma apropiada de autorizar de manera segura a un usuario de aplicación. En la práctica, probablemente querrás usar alguna combinación de Headers, Context, Middleware y Metadata para autenticar y autorizar a tus usuarios.

ts
export const authorizedProcedure = publicProcedure
.input(z.object({ townName: z.string() }))
.use((opts) => {
if (opts.input.townName !== 'Pucklechurch') {
throw new TRPCError({
code: 'FORBIDDEN',
message: "We don't take kindly to out-of-town folk",
});
}
 
return opts.next();
});
 
export const appRouter = t.router({
hello: authorizedProcedure.query(() => {
return {
message: 'hello world',
};
}),
goodbye: authorizedProcedure.mutation(async (opts) => {
await opts.ctx.signGuestBook();
 
return {
message: 'goodbye!',
};
}),
});
ts
export const authorizedProcedure = publicProcedure
.input(z.object({ townName: z.string() }))
.use((opts) => {
if (opts.input.townName !== 'Pucklechurch') {
throw new TRPCError({
code: 'FORBIDDEN',
message: "We don't take kindly to out-of-town folk",
});
}
 
return opts.next();
});
 
export const appRouter = t.router({
hello: authorizedProcedure.query(() => {
return {
message: 'hello world',
};
}),
goodbye: authorizedProcedure.mutation(async (opts) => {
await opts.ctx.signGuestBook();
 
return {
message: 'goodbye!',
};
}),
});