菜单

TRPC API 层

相关源文件

本文档全面概述了 Tech Interview Handbook 门户应用程序中的 tRPC API 层实现。tRPC 实现了应用程序客户端和服务器组件之间的类型安全通信。本文档侧重于 tRPC 实现的结构、组织和使用模式。

有关利用此 API 层的特定功能实现的信息,请参阅门户应用程序架构或各个功能页面:简历审查系统Offer 系统题库系统

目的与作用

tRPC API 层作为前端 Next.js 组件和后端数据库之间的通信桥梁。它提供了一种类型安全、高效的方式来定义和公开 API 端点(称为“过程”),这些端点处理数据获取、操作和业务逻辑。

主要目的

  • 实现客户端和服务器之间的类型安全 API 调用
  • 提供后端过程的结构化组织
  • 处理输入验证和错误处理
  • 支持查询(数据检索)和变异(数据修改)

来源:apps/portal/src/server/router/index.ts1-78

架构概述

tRPC API 层架构

来源:apps/portal/src/server/router/index.ts35-78

主路由器结构

tRPC API 层围绕一个中央 appRouter 进行组织,该路由器合并了多个特定于功能的路由器。每个功能(Offer、Resume、Questions)都有自己的一组路由器,负责处理该功能不同方面的功能。

主路由器组成

路由器使用命名空间模式,其中每个端点都以其功能名称为前缀,从而创建分层 API 结构(例如,offers.profile.questions.answers.)。

来源:apps/portal/src/server/router/index.ts35-75

路由器创建和上下文

每个路由器都是使用 createRouter 函数创建的,该函数提供访问数据库连接和用户会话信息所需的上下文。superjson 转换器用于在序列化期间正确处理日期和其他特殊类型。

关键组件

  • createRouter():创建具有适当上下文的路由器实例的工厂函数
  • transformer(superjson):确保正确序列化复杂数据类型
  • .merge():在命名空间下合并多个路由器

来源:apps/portal/src/server/router/index.ts4 apps/portal/src/server/router/index.ts36

特定功能路由器

Offer 系统路由器

Offer 系统有多个专门的路由器

路由器名称命名空间目的
offersRouteroffers.Offer 功能的基础路由器
offersProfileRouteroffers.profile.处理 Offer 个人资料数据
offersAnalysisRouteroffers.analysis.分析和比较 Offer
offersCommentsRouteroffers.comments.管理 Offer 上的评论
offersUserProfileRouteroffers.user.profile.用户特定的 Offer 个人资料
offerAdminRouteroffers.admin.管理功能

来源:apps/portal/src/server/router/index.ts6-11 apps/portal/src/server/router/index.ts70-75

简历系统路由器

简历系统包含以下路由器

路由器名称命名空间目的
resumesRouterresumes.resume.核心简历功能
resumesResumeUserRouterresumes.resume.user.用户特定的简历操作
resumeCommentsRouterresumes.comments.管理简历上的评论
resumesCommentsVotesRouterresumes.comments.votes.处理简历评论的投票

来源:apps/portal/src/server/router/index.ts24-30 apps/portal/src/server/router/index.ts46-52

问题系统路由器

问题系统具有最复杂的路由器结构

路由器名称命名空间目的
questionsQuestionRouterquestions.questions.核心问题操作
questionsAnswerRouterquestions.answers.处理问题的答案
questionsListRouterquestions.lists.管理问题列表
questionsQuestionCommentRouterquestions.questions.comments.问题评论
questionsAnswerCommentRouterquestions.answers.comments.答案评论
questionsQuestionEncounterRouterquestions.questions.encounters.跟踪问题遭遇

来源:apps/portal/src/server/router/index.ts13-23 apps/portal/src/server/router/index.ts53-69

过程类型和实现

tRPC 支持两种主要的过程类型

  1. Queries:用于检索数据(GET 操作)
  2. Mutations:用于修改数据(POST、PUT、DELETE 操作)

每个过程通常包括

  • 使用 Zod 模式进行输入验证
  • 处理业务逻辑的解析器函数
  • 通过 Prisma 进行数据库操作

示例过程实现

.query('getComments', {
  input: z.object({
    profileId: z.string(),
  }),
  async resolve({ ctx, input }) {
    // Database access & business logic
    // Return data
  }
})
.mutation('create', {
  input: z.object({
    // Input schema
  }),
  async resolve({ ctx, input }) {
    // Create/update/delete operations
    // Return result
  }
})

来源:apps/portal/src/server/router/offers/offers-comments-router.ts8-190

输入验证

tRPC 使用 Zod 进行输入验证,确保传递给过程的所有数据在处理前都经过正确类型和验证。这提供了运行时安全和编译时类型检查。

例如,评论路由器验证输入,如

这确保了所有必需字段都存在且类型正确,同时正确处理了可选字段。

来源:apps/portal/src/server/router/offers/offers-comments-router.ts100-106

错误处理

tRPC 通过 TRPCError 类提供内置错误处理。常见的错误场景包括

  • 未经授权的访问尝试
  • 无效的输入数据
  • 未找到资源
  • 数据库错误

错误会得到正确类型化并通过相应的状态码传播到客户端

来源:apps/portal/src/server/router/offers/offers-comments-router.ts185-188

客户端使用

在客户端,React 组件使用 tRPC 生成的钩子与 API 进行交互。这提供了跨客户端-服务器边界的完整类型安全性。

关键模式

  • 使用生成的查询钩子进行数据获取
  • 使用变异钩子进行数据修改
  • 从 API 定义自动推断类型

例如,客户端组件可以使用类似 trpc.offers.profile.useQuery() 的钩子来获取数据,或使用 trpc.offers.comments.create.useMutation() 来创建新数据。

来源:apps/portal/src/pages/questions/index.tsx1-49 apps/portal/src/components/questions/filter/FilterSection.tsx1-161

类型和接口

tRPC API 层与应用程序中定义的强类型数据结构一起工作。这些类型确保客户端和服务器数据表示之间的一致性。

示例包括

类型定义在 API 层和客户端组件中都使用,从而确保整个应用程序的类型安全性。

来源:apps/portal/src/types/questions.d.ts3-15

结论

tRPC API 层为 Tech Interview Handbook 门户应用程序的客户端和服务器组件之间提供了强大、类型安全的通信机制。通过按功能组织路由器并使用分层命名空间模式,尽管 API 复杂,但它仍然易于维护。使用 Zod 进行输入验证和 Prisma 进行数据库访问,为实现特定功能业务逻辑奠定了坚实的基础。