查询与变更接口
两类操作
查询使用 .query(),不产生业务写入;变更使用 .mutation(),用于创建、修改和删除。输入使用 Zod 定义,私有操作使用 protectedProcedure。
以下是独立示例,演示接口结构;若加入项目,还要注册路由。
ts
import { z } from "zod";
import { protectedProcedure, router } from "../lib/trpc";
export const profileRouter = router({
summary: protectedProcedure.query(({ ctx }) => ({
id: ctx.user.id,
name: ctx.user.name,
})),
validateName: protectedProcedure
.input(z.object({ name: z.string().trim().min(1).max(100) }))
.mutation(({ input }) => ({ name: input.name })),
});validateName 仅返回校验后的输入,不保存资料。真实写入还需数据模型、权限校验及相应测试。
注册与调用
在 apps/api/lib/app.ts 的 appRouter 中加入新路由,客户端类型随之更新。工作台使用统一 tRPC 客户端;把查询键、请求及失效逻辑放在 apps/app/lib/queries/。
安全与幂等
登录不代表可以读取任意用户或组织资源。查询条件需要同时包含当前身份范围;写入必须重新验证。涉及积分、支付和可重试任务时,使用唯一业务事件键与数据库事务,避免重复扣费。
限制输入大小及返回字段,只返回调用方需要的数据。列表接口设数量上限并选择明确排序,避免无界查询。
验证
至少检查合法输入、非法输入、未登录、越权及重复请求。纯格式展示改动无需新增接口测试;新增数据边界应使用真实数据库语义测试,见 测试与排查。