定义过程
过程是暴露给客户端的函数,它可以是以下之一:
¥A procedure is a function which is exposed to the client, it can be one of:
一个
Query
- 用于获取数据,一般不改变任何数据¥a
Query
- used to fetch data, generally does not change any data一个
Mutation
- 用于发送数据,通常用于创建/更新/删除目的¥a
Mutation
- used to send data, often for create/update/delete purposes一个
Subscription
- 你可能不需要这个,我们有 专用文档¥a
Subscription
- you might not need this, and we have dedicated documentation
tRPC 中的过程是创建后端函数的非常灵活的原语。它们使用不可变的构建器模式,这意味着你可以在多个过程之间共享功能。
¥Procedures in tRPC are very flexible primitives to create backend functions. They use an immutable builder pattern, which means you can create reusable base procedures that share functionality among multiple procedures.
编写过程
¥Writing procedures
你在 tRPC 设置期间创建的 t
对象返回一个初始 t.procedure
,所有其他过程都基于该初始 t.procedure
构建:
¥The t
object you create during tRPC setup returns an initial t.procedure
which all other procedures are built on:
ts
import {initTRPC } from '@trpc/server';import {z } from 'zod';constt =initTRPC .context <{signGuestBook : () =>Promise <void> }>().create ();export constrouter =t .router ;export constpublicProcedure =t .procedure ;constappRouter =router ({// Queries are the best place to fetch datahello :publicProcedure .query (() => {return {message : 'hello world',};}),// Mutations are the best place to do things like updating a databasegoodbye :publicProcedure .mutation (async (opts ) => {awaitopts .ctx .signGuestBook ();return {message : 'goodbye!',};}),});
ts
import {initTRPC } from '@trpc/server';import {z } from 'zod';constt =initTRPC .context <{signGuestBook : () =>Promise <void> }>().create ();export constrouter =t .router ;export constpublicProcedure =t .procedure ;constappRouter =router ({// Queries are the best place to fetch datahello :publicProcedure .query (() => {return {message : 'hello world',};}),// Mutations are the best place to do things like updating a databasegoodbye :publicProcedure .mutation (async (opts ) => {awaitopts .ctx .signGuestBook ();return {message : 'goodbye!',};}),});
可重复使用 "基本过程"
¥Reusable "Base Procedures"
作为一般模式,我们建议你将 t.procedure
重命名并导出为 publicProcedure
,这样你就可以为特定用例创建其他命名过程并导出它们。该模式称为 "基本过程",是 tRPC 中代码和行为重用的关键模式;每个应用都可能需要它。
¥As a general pattern we recommend you rename and export t.procedure
as publicProcedure
, which then makes room for you to create other named procedures for specific use cases and export those too. This pattern is called "base procedures" and is a key pattern for code and behaviour re-use in tRPC; every application is likely to need it.
下面的示例接受用户输入,并像保护城镇居民一样对他们进行 authorizes 处理。这显然是为了简单起见而设计的示例,而不是安全授权应用用户的适当方法,因此在实践中你可能希望使用 标头、上下文、中间件 和 元数据 到 authenticate 的某种组合并授权你的用户。
¥The below example takes a user input and authorizes them like protective towns-people. This is obviously a contrived example for simplicity, and not an appropriate way to securely authorize an application user, so in practice you may want to use some combination of Headers, Context, Middleware, and Metadata, to authenticate and authorize your users.
ts
export constauthorizedProcedure =publicProcedure .input (z .object ({townName :z .string () })).use ((opts ) => {if (opts .input .townName !== 'Pucklechurch') {throw newTRPCError ({code : 'FORBIDDEN',message : "We don't take kindly to out-of-town folk",});}returnopts .next ();});export constappRouter =t .router ({hello :authorizedProcedure .query (() => {return {message : 'hello world',};}),goodbye :authorizedProcedure .mutation (async (opts ) => {awaitopts .ctx .signGuestBook ();return {message : 'goodbye!',};}),});
ts
export constauthorizedProcedure =publicProcedure .input (z .object ({townName :z .string () })).use ((opts ) => {if (opts .input .townName !== 'Pucklechurch') {throw newTRPCError ({code : 'FORBIDDEN',message : "We don't take kindly to out-of-town folk",});}returnopts .next ();});export constappRouter =t .router ({hello :authorizedProcedure .query (() => {return {message : 'hello world',};}),goodbye :authorizedProcedure .mutation (async (opts ) => {awaitopts .ctx .signGuestBook ();return {message : 'goodbye!',};}),});