使用 tRPC 和 Deno 构建类型安全 API:恐龙数据示例

作者:API传播员 · 2025-10-16 · 阅读时间:5分钟

在本教程中,我们将使用 tRPCDeno 构建一个简单的类型安全 API,用于管理和查询恐龙信息。通过本教程,您将掌握 tRPC 的基本用法,并了解如何在 Deno 环境中实现类型安全的 API 开发。


一. 安装依赖

Deno 支持直接使用 npm 包。我们需要安装以下依赖:

  • @trpc/server:用于创建 tRPC 服务器;
  • @trpc/client:用于创建客户端调用 API;
  • zod:用于输入数据验证;
  • @std/path:用于路径操作。

运行以下命令安装:

deno install npm:@trpc/server@next npm:@trpc/client@next npm:zod jsr:@std/path

二. 设置 tRPC 服务器

1. 初始化 tRPC

server/trpc.ts 中创建 tRPC 路由器和程序生成器:

import { initTRPC } from "@trpc/server";
import { z } from "zod";

const t = initTRPC.create();

export const router = t.router;
export const publicProcedure = t.procedure;
  • publicProcedure 用于创建无需身份验证的 API 端点。

2. 创建数据层

server/db.ts 中创建简单的数据层,基于 JSON 文件存储恐龙信息:

import { readJson, writeJson } from "https://deno.land/std/fs/mod.ts";
import { join } from "@std/path";

const DATA_FILE = join(Deno.cwd(), "data.json");

export async function getAllDinos() {
  return await readJson(DATA_FILE) as Array<{ name: string; description: string }>;
}

export async function addDino(dino: { name: string; description: string }) {
  const dinos = await getAllDinos();
  dinos.push(dino);
  await writeJson(DATA_FILE, dinos, { spaces: 2 });
  return dino;
}

3. 提供示例数据

在项目根目录创建 data.json

[
  {
    "name": "Tyrannosaurus Rex",
    "description": "A large carnivorous dinosaur."
  }
]

4. 定义主服务器文件

server/index.ts 中定义路由和端点:

import { router, publicProcedure } from "./trpc.ts";
import * as db from "./db.ts";
import { z } from "zod";
import { serve } from "https://deno.land/std@0.203.0/http/server.ts";
import { createHTTPHandler } from "@trpc/server/adapters/standalone";

const appRouter = router({
  dino: router({
    list: publicProcedure.query(async () => await db.getAllDinos()),
    create: publicProcedure.input(z.object({
      name: z.string(),
      description: z.string()
    })).mutation(async ({ input }) => await db.addDino(input))
  })
});

export type AppRouter = typeof appRouter;

const handler = createHTTPHandler({ router: appRouter });
serve(handler, { port: 3000 });
console.log("Server running on http://localhost:3000");
  • dino.list 返回所有恐龙;
  • dino.create 创建新恐龙。

三. 设置 tRPC 客户端

client/index.ts 创建客户端:

import { createTRPCProxyClient, httpBatchLink } from "@trpc/client";
import type { AppRouter } from "../server/index.ts";

const trpc = createTRPCProxyClient<AppRouter>({
  links: [
    httpBatchLink({ url: "http://localhost:3000" })
  ]
});

async function main() {
  console.log(await trpc.dino.list.query());

  const newDino = await trpc.dino.create.mutate({
    name: "Denosaur",
    description: "A friendly Deno-powered dinosaur."
  });

  console.log(newDino);
}

main();

1. 类型安全特性

客户端通过 AppRouter 类型继承服务器的类型定义:

  • 所有 API 调用都有类型提示;
  • 任何类型错误(例如 description: number)将在编译时或运行时抛出错误。

四. 启动与测试

1. 配置 deno.json

{
  "tasks": {
    "start": "deno -A server/index.ts",
    "client": "deno -A client/index.ts"
  }
}

2. 启动服务器

deno task start

3. 运行客户端

deno task client
  • 输出显示所有恐龙列表;
  • 创建新恐龙并返回数据。

五. 验证类型安全

尝试传递错误类型:

await trpc.dino.create.mutate({
  name: "Denosaur",
  description: 12345 // 错误类型
});
  • tRPC 将抛出 invalid_type 错误;
  • 确保客户端与服务器数据保持类型一致。

六. 总结

本教程展示了如何使用 tRPC + Deno 构建类型安全 API:

  • 从安装依赖到创建服务器与客户端;
  • 使用 JSON 文件模拟数据库;
  • 验证类型安全,防止类型错误;
  • 可以轻松扩展,添加更多端点或集成真实数据库。

通过 tRPC,Deno 开发者可以轻松构建类型安全、高效的 API。

原文链接: https://deno.com/blog/build-typesafe-apis-trpc