MIT License

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

oRPC 深度解析:当类型安全不再意味着生态绑架

项目背景与痛点

TypeScript 全栈开发里有一个长期未解的矛盾。tRPC 用泛型把「前后端类型一致」做到了极致——调用远程方法像调用本地函数,重构时编译器替你兜底。代价同样明显:tRPC 客户端本质上是一段 TypeScript 代码,非 TS 用户(移动端、Go/Python 服务、第三方合作伙伴)无从消费;它也没有 OpenAPI 文档,API 网关、SDK 生成器、Postman 全都插不上手。

另一端是 REST/OpenAPI。接口天然跨语言,工具链成熟,却要靠 codegen 才能获得类型。生成的类型与真实实现之间隔着一层代码,改一处 schema 忘了重跑生成器,类型和运行时悄悄错位,这就是很多人对 codegen 的疲惫感。

middleapi/orpc 的切入点是:把契约(contract)定义成唯一真相源,让类型安全从类型推导中自然涌现,同时把 OpenAPI 规范作为副产物输出。换句话说,它试图同时兑现 tRPC 的开发体感和 REST 的互操作能力,而不是让开发者在两者之间二选一。

核心技术揭秘

oRPC 的结构可以概括为「契约 → 处理层 → 双通道出口」。程序(procedure)用 schema 声明输入输出,router 把程序组织成树,然后在同一个 contract 之上挂载 RPCHandler 与 OpenAPIHandler 两种处理器,前者服务于原生客户端,后者负责把结构化调用翻译成符合 OpenAPI 3.1 的 REST 语义。

graph TD A[契约定义 contract] --> B[Procedure 输入输出 Schema] B --> C[Router 组装] C --> D[Handler 分发层] D -->|"RPC 调用"| E[RPCHandler] D -->|"REST 调用"| F[OpenAPIHandler] E --> G[Fetch Request/Response 适配] F --> G F --> H[生成 OpenAPI 3.1 文档] G --> I[客户端 Proxy] I --> J[中间件与插件链] J --> K[端到端类型推断]

类型推导的关键在客户端一侧。oRPC 的客户端不是 codegen 出来的对象,而是基于 Proxy 构建的递归代理:访问属性时不断累积路径,最终把 router 的类型结构映射为调用签名。这里的技术难点在于 TypeScript 层面的深度递归映射——它必须处理嵌套 router、可选输入、中间件注入的上下文,同时还要避免类型实例化过深导致编辑器卡顿。这类实现通常要借助条件类型与类型级缓存(对已解析的节点做记忆化),否则一个中等规模的 API 树就足以让 IDE 变慢。

传输层刻意贴着 Web 标准走。请求与响应建立在实际的 Request/Response 对象上,而不是自造框架协议。好处是运行时无关性:Node、Bun、Deno、Cloudflare Workers、边缘函数都能用同一份 handler,只要环境提供 fetch。这也让文件上传这类「tRPC 的老大难」变得自然——基于 FormData 流式处理即可,不必再为二进制单独设计通道。

schema 验证被抽象成适配层,zod、valibot、arktype 等都可以接入。校验发生在 handler 入口,错误以结构化形式抛出,客户端侧可复用同一份定义做前置校验,避免无效请求往返。中间件链则承担鉴权、日志、限流等横切关注点,并能在类型层面把上下文(如当前用户)注入到后续 procedure,这是「类型安全」从数据扩展到执行环境的体现。

功能亮点与差异

  • 零 codegen 的双向兼容:这不是「先写 RPC 再导出文档」的补丁方案,而是同一份 contract 直接生成 OpenAPI 规范。契约变更后文档自动跟随,消除了生成器与实现之间的漂移。
  • REST 语义可精细控制:程序可映射为不同 HTTP 方法与路径,RPC 风格的「一方法一动作」和资源风格的「路径 + 动词」能在同一个 router 里共存。
  • 性能路径可选:在 RPC 通道上可以脱离 HTTP 语义做批处理或长连接式优化;需要通用性时再切回标准 HTTP,不用重建整个服务。
  • 生态不锁定:非 TS 客户端通过 OpenAPI 即可接入,这一点是 tRPC 结构性缺失的能力。

应用场景与落地建议

最适合的场景是「TS 前端 + 多方消费」的产品型项目、BFF 层、以及需要在 Web 与边缘运行时同时部署的服务。内部微服务之间用 RPC 通道享受类型红利,对外开放接口走 OpenAPI 通道,一个代码库两套出口,治理成本低。

落地时有几处需要留神:一是 schema 库的选择要一次性定好,中途换库意味着所有 contract 都要改写,虽然适配层抽象得不错,但迁移仍是体力活;二是 OpenAPI 自动生成的文档质量取决于 contract 的元信息(描述、示例、错误码),别指望零配置就产出可交付的文档;三是类型推导的编译开销要实测,大 router 建议按业务域拆分,避免单文件类型膨胀;四是错误契约需显式设计,跨语言的消费方不理解 TS 异常,必须收敛为可枚举的错误码。

综合评价

oRPC 的价值不在「又一个 RPC 框架」,而在于它把类型安全从「TS 生态内的私有红利」重新定义为「契约驱动、可对外导出」的公共资产。Proxy 推导 + 标准 fetch + OpenAPI 副产物这三件事组合起来,指向一个清晰的工程答案:你不必为了互操作性牺牲开发体验,也不必为了类型安全把系统锁死在单一语言里。

短板也真实存在:它仍处在快速迭代阶段,API 稳定性不如已被大量生产验证的 tRPC;自动生成的 OpenAPI 在复杂场景(多态响应、精细的 header 契约)下仍需手工补足;对非 TS 团队,收益主要落在服务端一侧,客户端依旧是标准 HTTP 消费,谈不上魔法。如果你的团队以 TypeScript 为主、又需要对外开放接口,它值得认真评估;如果你只需要内部类型安全且永远不涉及第二语言,tRPC 的成熟度仍是更稳的选择。

关于

GitHub 原始描述(英文)

Typesafe APIs Made Simple 🪄

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

语言占比

Astro
CSS
HTML
JavaScript
MDX
TypeScript

Release

README

oRPC - Typesafe APIs Made Simple 🪄

oRPC is a TypeScript framework for building end-to-end typesafe APIs. Write your API once as plain TypeScript functions, and oRPC gives you a fully typed client, a REST API with an OpenAPI document, and MCP tools for AI agents, with no code generation. It runs on Node.js, Bun, Deno, Cloudflare Workers, and more.

Define procedures on the server and serve them with an RPC handler:

import { os } from '@orpc/server'
import * as z from 'zod'

export const router = {
  planet: {
    find: os
      .input(z.object({ id: z.number() }))
      .handler(({ input }) => ({ id: input.id, name: 'Earth' })),
  },
}

Then call them from a client that knows every input and output, without generating anything:

import { createORPCClient } from '@orpc/client'
import { RPCLink } from '@orpc/client/fetch'
import type { RouterClient } from '@orpc/server'

import type { router } from './router'

const link = new RPCLink({ origin: 'http://localhost:3000', url: '/rpc' })
const client: RouterClient<typeof router> = createORPCClient(link)

const planet = await client.planet.find({ id: 1 }) // { id: number, name: string }

Documentation

Read the full documentation at orpc.dev, starting with the Getting Started guide.

Packages

Core

Package Purpose Docs
@orpc/contract Define API contract as the single source of truth. Procedure Contract, Contract Router, Implementation, Generate from OpenAPI
@orpc/server Build APIs or implement contracts. Procedure, Router, Middleware, Context, RPC Handler
@orpc/client Consume APIs with end-to-end type safety. Client-Side Clients, Server-Side Clients, RPC Link, Error Handling
@orpc/openapi Add OpenAPI compatibility to APIs. OpenAPI Handler, OpenAPI Link, Specification, Scalar

Schema validation

Package Purpose Docs
@orpc/zod JSON Schema converter for Zod. Zod
@orpc/valibot JSON Schema converter for Valibot. Valibot
@orpc/arktype JSON Schema converter for ArkType. ArkType

Built-in features

Package Purpose Docs
@orpc/publisher Pub/Sub with memory, Redis, and Upstash adapters. Publisher
@orpc/ratelimit Rate limiting with memory, Redis, and Upstash adapters. Rate Limit
@orpc/experimental-lock Locking with memory, Redis, and Upstash adapters. Lock
@orpc/hibernation Leverage Hibernation APIs like Cloudflare’s Hibernation WebSocket. Hibernation
@orpc/json-schema Smart coercion for OpenAPI requests. Smart Coercion

Framework & ecosystem integrations

Package Purpose Docs
@orpc/next Integrate with Next.js Server Functions. Next.js
@orpc/ai-sdk Turn contracts and procedures into AI SDK tools. AI SDK
@orpc/mcp Expose procedures as MCP tools. MCP
@orpc/tanstack-query Integrate with TanStack Query. TanStack Query
@orpc/pinia-colada Integrate with Pinia Colada. Pinia Colada
@orpc/swr Integrate with SWR. SWR
@orpc/msw Mock procedures with Mock Service Worker. MSW
@orpc/effect Integrate with Effect. Effect
@orpc/nest Implement your contract with NestJS. NestJS
@orpc/node Node.js plugins for static file serving and large uploads. Static File, Tmp File Upload, Batch Response Compression
@orpc/bun Adapters for Bun’s Redis. Publisher, Rate Limit, Lock
@orpc/cloudflare Adapters for Cloudflare Workers. Publisher, Rate Limit, Lock, Traces
@orpc/trpc Reuse existing tRPC routers within oRPC. tRPC

Observability

Package Purpose Docs
@orpc/opentelemetry Integrate with OpenTelemetry for distributed tracing. OpenTelemetry
@orpc/pino Integrate with Pino for logging. Pino
@orpc/evlog Integrate with Evlog for logging. Evlog

Sponsors

Like what we build over at middleapi? You can help keep it going through GitHub Sponsors or Open Collective. Every bit helps! 🚀

ScreenshotOne.comScreenshotOne.com
The screenshot API for developers
YuzuYuzu
We're hiring NYC based engineers
MisskeyHQMisskeyHQ
Decentralized microblogging SNS born on Earth

Organization Sponsors

LN Markets
LN Markets

Sponsors

Reece McDonald
Reece McDonald
あわわわとーにゅ
あわわわとーにゅ
nk
nk
supastarter
supastarter
herrfugbaum
herrfugbaum
Ryota Murakami
Ryota Murakami
David Cramer
David Cramer
Valerii Petryniak
Valerii Petryniak
Valerii Strilets
Valerii Strilets
Kyle Mistele
Kyle Mistele
christ12938
christ12938
Ryan Soderberg
Ryan Soderberg
shota
shota
Nicholas
Nicholas
Ellis Driscoll
Ellis Driscoll
Hoang Nguyen
Hoang Nguyen
Orestis Ioannou
Orestis Ioannou
Stefan Smiljkovic
Stefan Smiljkovic

Backers

David Walsh
David Walsh
IPv4Addr
IPv4Addr
Robbe Vaes
Robbe Vaes
Aidan Sunbury
Aidan Sunbury
soonoo
soonoo
Kevin Porten
Kevin Porten
Denis
Denis
Christopher Kapic
Christopher Kapic
Tom Ballinger
Tom Ballinger
Sam
Sam
Titoine
Titoine
Igor Makowski
Igor Makowski
hanayashiki
hanayashiki
Lev Dubinets
Lev Dubinets
Kelly Peilin Chan
Kelly Peilin Chan
Guy Ariely
Guy Ariely
PaulSenon
PaulSenon
Alex
Alex
Andrey Gubanov
Andrey Gubanov

With thanks to 40 past sponsors who helped get oRPC here.

Open Source Programs

middleapi is supported by these open source programs:

Claude
Claude
Pullfrog
Pullfrog

References

oRPC is inspired by existing solutions that prioritize type safety and developer experience. Special acknowledgments to:

  • tRPC: For pioneering the concept of end-to-end type-safe RPC and influencing the development of type-safe APIs.
  • ts-rest: For its emphasis on contract-first development and OpenAPI integration, which have greatly inspired oRPC’s feature set.

License

Distributed under the MIT License. See LICENSE for more information.

评论

暂无评论