Hoppa till huvudinnehållet
Version: 10.x

Definiera procedurer

Inofficiell Beta-översättning

Denna sida har översatts av PageTurner AI (beta). Inte officiellt godkänd av projektet. Hittade du ett fel? Rapportera problem →

En procedur är en funktion som exponeras för klienten och kan vara en av följande typer:

  • en Query - används för att hämta data och ändrar vanligtvis inga data

  • en Mutation - används för att skicka data, ofta för att skapa/uppdatera/radera

  • en Subscription - du behöver troligen inte denna funktion, och vi har dedikerad dokumentation

Procedurer i tRPC är mycket flexibla byggstenar för att skapa backend-funktioner. De använder ett oföränderligt byggmönster (immutable builder pattern), vilket innebär att du kan skapa återanvändbara basprocedurer som delar funktionalitet mellan flera procedurer.

Skriva procedurer

t-objektet du skapar vid tRPC-installation returnerar en initial t.procedure som alla andra procedurer bygger på:

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!',
};
}),
});

Återanvändbara "Basprocedurer"

Som generell rekommendation bör du byta namn på och exportera t.procedure som publicProcedure. Detta skapar utrymme att skapa andra namngivna procedurer för specifika användningsfall och exportera även dessa. Detta mönster kallas "basprocedurer" och är centralt för kod- och beteendeåteranvändning i tRPC - varje applikation kommer troligen att behöva det.

Exemplet nedan tar emot användarinput och auktoriserar dem som vaksamma stadsbor. Detta är uppenbart ett uppdiktat exempel för enkelhetens skull, och inte ett lämpligt sätt att säkert auktorisera en applikationsanvändare. I praktiken bör du därför använda någon kombination av Headers, Context, Middleware och Metadata för att autentisera och auktorisera dina användare.

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!',
};
}),
});