Skip to Content
🎉 gRPCity 3.0 is released. Read more →
gRPCity 3.0 — 已正式发布

以更好的方式去创建
您的 gRPC 客户端和服务端。

一套小而克制的框架,封装 @grpc/grpc-js 与 @grpc/proto-loader,让你用十几行代码就能交付带类型的服务或客户端。

$

npm i grpcity

import { loader } from './loader.js'

class Greeter {
  async sayGreet(call) {
    return { message: `hello, ${call.request.name}` }
  }
}

await loader.init()
const server = await loader.initServer()
server.add('helloworld.Greeter', new Greeter())
await server.listen('127.0.0.1:9099')
特性

从第一天起就为生产打磨。

每个 gRPCity 版本都默认启用下列特性,并保持稳定 API。

四种流式 RPC

unary、client stream、server stream、bidi 全都可以 for await 消费。Handler 中 throw 会以 status 形式抵达客户端。

AbortSignal 全链路

任何 RPC 都可以传 AbortSignal 取消。调用前 abort 会短路;调用中 abort 会立刻取消,并以 CANCELLED 抛出。

客户端 / 服务端中间件

客户端和服务端都用 Koa 风格的 (ctx, next)——日志、追踪、重试、metadata 改写都不用动调用处。

内建 gRPC 反射

loader.initReflection() 返回一个可以 inject() 给 server 的服务,grpcurl 与 Postman 直接可用。

三行配齐 mTLS

makeServerCredentials / makeClientCredentials 把样板代码全藏起来,几个调用就能完整 mTLS。

配置 typo 当场报错

Loader、client、server 选项都通过 zod 在运行时校验,typo 会响亮地失败而不是静默吞掉。

TypeScript 一等公民

全程 TypeScript 实现。MetadatacredentialsChannelCredentialsStatusObject 等类型都从主入口重新导出。

Promise 与 callback

默认 await 一切;保留 callback 形式给历史集成与事件驱动热路径。

对比

为什么用 gRPCity,而不是直接用 @grpc/grpc-js?

gRPCity 是 @grpc/grpc-js 之上的薄封装,不是替代品。封装的目的,是把你每天要写的部分变短、把你容易忘的部分变安全。

@grpc/grpc-js
gRPCity
启动一个服务
20+ 行 proto 加载与方法绑定
3 行:loader → server → listen
取消进行中的 RPC
手动 call.cancel(),没有 AbortSignal 集成
任意 RPC 传 signal 即可——调用前 abort、调用中 abort 都开箱可用
流式消费
事件 emitter + 手动背压
到处都是 for await (const m of call.readAll())
错误处理
Error 负载,没有类型化形态
GrpcClientError 携带 code / details / metadata
反射 / mTLS / 中间件
各自是独立包或手写
内置、默认启用、共用同一个 loader