跳转至

ConnectRPC:下一代 Protobuf RPC 框架——当 gRPC 遇见现代 Web 开发

为什么我们需要"更好的 gRPC"?

自 2016 年 Google 开源 gRPC 以来,它凭借 Protocol Buffers 的高效序列化和 HTTP/2 的多路复用,迅速成为微服务间通信的事实标准。然而,随着云原生架构的演进和前后端分离开发的普及,gRPC 的一些设计局限日益凸显:

  • 浏览器兼容性:gRPC 依赖 HTTP/2 的底层特性,浏览器无法直接调用,必须借助 grpc-web + Envoy 代理
  • 调试困难:二进制协议让 curl 和浏览器开发者工具束手无策
  • 部署复杂:需要特殊的负载均衡器支持 HTTP/2 trailers
  • 代码冗长:生成的客户端代码模板化严重,与现代开发体验脱节

ConnectRPC(简称 Connect)正是 Buf 团队为解决这些痛点而打造的现代化 RPC 框架。它不仅完全兼容 gRPC 生态,更带来了浏览器原生支持、HTTP/1.1 回退、以及 REST 般的调试体验。

核心架构:三协议合一的设计哲学

ConnectRPC 最显著的特点是单一服务端同时支持三种协议,通过 Content-Type 头自动识别:

协议 适用场景 特性
Connect 通用场景、浏览器调用、调试 基于 HTTP/1.1 或 HTTP/2,支持 JSON 和二进制 Protobuf,可使用标准 HTTP 工具调试
gRPC 后端微服务间高性能通信 完整兼容官方 gRPC 协议,支持所有流式 RPC
gRPC-Web 浏览器直接调用 无需代理,前端可直接连接服务端

这种设计让服务端一次部署,即可服务从传统微服务到现代 Web 应用的所有客户端。

ConnectRPC = gRPC 的类型安全 + REST 的调试便利 + 浏览器的原生支持

协议协商示例

# 使用 Connect 协议(JSON,HTTP/1.1 友好)
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"sentence": "Hello Connect"}' \
  https://demo.connectrpc.com/connectrpc.eliza.v1.ElizaService/Say

# 使用标准 gRPC 协议(同一服务端)
grpcurl -d '{"sentence": "Hello gRPC"}' \
  demo.connectrpc.com:443 \
  connectrpc.eliza.v1.ElizaService/Say

与 gRPC 的深度对比

多维度能力矩阵

维度 官方 gRPC ConnectRPC 典型场景胜出方
传输协议 仅 HTTP/2 HTTP/1.1、HTTP/2、HTTP/3 Connect(边缘计算/K8s)
浏览器支持 需 grpc-web + 代理 原生支持(Connect/gRPC-Web) Connect 完胜
调试体验 grpcurl 等专用工具 curl/Postman/浏览器 DevTools Connect 大胜
代码生成 冗长模板代码 简洁现代(尤其 Go/TS) Connect 更舒适
服务端复杂度 需完整 gRPC 运行时 单包集成,兼容 Gin/Echo Connect 更轻量
序列化选项 仅二进制 Protobuf Protobuf + JSON 开箱即用 Connect 更灵活
存量兼容 标准本身 可作为 gRPC 服务器运行 Connect 平滑迁移
生态成熟度 非常成熟 快速增长,已入 CNCF gRPC 仍占主流

2026 年多语言支持现状

语言 gRPC 支持 ConnectRPC 支持 推荐选择
Go ★★★★★ ★★★★★(官方 connect-go) Connect
TypeScript/JS ★★★☆☆(需 grpc-web) ★★★★★(connect-es 2.0) Connect
Kotlin/Java ★★★★★ ★★★★☆(connect-kotlin) gRPC 更全
Python ★★★★☆ ★★★☆☆(社区版推进中) gRPC 更稳
Swift (iOS) ★★★★☆ ★★★★☆(connect-swift 1.0) 持平
Dart (Flutter) ★★★☆☆ ★★★★☆(connect-dart) Connect
Rust ★★★★☆ ★★☆☆☆(社区早期) gRPC 胜出
C++ ★★★★★ ★☆☆☆☆(几乎无) gRPC 完胜

实战:从定义到部署的极简体验

1. 定义服务(标准 Protobuf)

// user/v1/user.proto
syntax = "proto3";

package user.v1;

message User {
  string id = 1;
  string name = 2;
  string email = 3;
}

service UserService {
  rpc GetUser(GetUserRequest) returns (GetUserResponse);
  rpc ListUsers(ListUsersRequest) returns (stream User); // 服务端流式
}

message GetUserRequest { string id = 1; }
message GetUserResponse { User user = 1; }
message ListUsersRequest { int32 page_size = 1; }

2. Go 服务端实现(connect-go)

package main

import (
    "context"
    "log"
    "net/http"

    "connectrpc.com/connect"
    userv1 "example/gen/user/v1"
    "example/gen/user/v1/userv1connect"
)

type UserServer struct{}

func (s *UserServer) GetUser(
    ctx context.Context,
    req *connect.Request[userv1.GetUserRequest],
) (*connect.Response[userv1.GetUserResponse], error) {
    // 简洁的错误处理,自动映射 HTTP 状态码
    if req.Msg.Id == "" {
        return nil, connect.NewError(connect.CodeInvalidArgument, 
            errors.New("user ID is required"))
    }

    user := fetchUser(req.Msg.Id) // 业务逻辑
    return connect.NewResponse(&userv1.GetUserResponse{User: user}), nil
}

func (s *UserServer) ListUsers(
    ctx context.Context,
    req *connect.Request[userv1.ListUsersRequest],
    stream *connect.ServerStream[userv1.User],
) error {
    // 服务端流式:自动处理 gRPC/Connect 协议差异
    for _, user := range fetchUsers(req.Msg.PageSize) {
        if err := stream.Send(user); err != nil {
            return err
        }
    }
    return nil
}

func main() {
    // 标准 net/http 集成,可与任何中间件配合
    mux := http.NewServeMux()
    path, handler := userv1connect.NewUserServiceHandler(
        &UserServer{},
        connect.WithInterceptors(loggingInterceptor()),
    )
    mux.Handle(path, handler)

    log.Fatal(http.ListenAndServe(":8080", mux))
}

3. TypeScript 前端调用(connect-es)

import { createPromiseClient } from "@connectrpc/connect";
import { createConnectTransport } from "@connectrpc/connect-web";
import { UserService } from "./gen/user/v1/user_connect";

const transport = createConnectTransport({
  baseUrl: "https://api.example.com",
  // 开发调试时可切换为 JSON 格式
  useBinaryFormat: process.env.NODE_ENV === 'production', 
});

const client = createPromiseClient(UserService, transport);

// 浏览器原生 fetch 调用,无需代理
const user = await client.getUser({ id: "123" });
console.log(user.name);

// 流式调用同样原生支持
for await (const user of client.listUsers({ pageSize: 10 })) {
  console.log(user.email);
}

4. 用 curl 调试 gRPC 服务

# 获取用户(JSON 格式,HTTP/1.1)
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"id": "123"}' \
  http://localhost:8080/user.v1.UserService/GetUser

# 或使用 Connect 的 GET 支持(可缓存的幂等查询)
curl -H "Content-Type: application/connect+json" \
  "http://localhost:8080/user.v1.UserService/GetUser?id=123"

生产环境的核心优势

1. 渐进式迁移策略

ConnectRPC 服务端天然兼容 gRPC 客户端,这让迁移风险降至最低:

// 场景:已有 Java/Python gRPC 客户端,想引入 Go Connect 服务端
// 无需修改任何客户端代码,Connect 服务端直接响应 gRPC 请求

// Java 客户端(保持原样)
ManagedChannel channel = ManagedChannelBuilder
    .forAddress("localhost", 8080)
    .usePlaintext()
    .build();
UserServiceGrpc.UserServiceBlockingStub stub = 
    UserServiceGrpc.newBlockingStub(channel);
// 这个 gRPC 客户端可以无缝调用 Connect-Go 服务端!

推荐迁移路径:新服务用 Connect 构建 → 开启 gRPC 协议兼容 → 逐步替换旧 gRPC 服务端。

2. 云原生部署友好

场景 gRPC 挑战 Connect 解决方案
AWS ALB 需 HTTP/2 专用目标组,CORS 预检失败 HTTP/1.1 原生支持,标准 HTTP 目标组
Kubernetes Ingress 需特殊配置支持 trailers 任何七层负载均衡器开箱即用
边缘计算/无服务器 HTTP/2 支持不稳定 HTTP/1.1 回退保证可用性
CDN 缓存 不可缓存 Connect GET 请求支持 CDN 缓存

3. 可观测性集成

Connect-Go 提供 OpenTelemetry 官方支持:

import "connectrpc.com/otelconnect"

otelInterceptor, _ := otelconnect.NewInterceptor()
handler := userv1connect.NewUserServiceHandler(
    &UserServer{},
    connect.WithInterceptors(otelInterceptor),
)
// 自动追踪 RPC 调用、指标采集、分布式追踪

2026 年的生态与选型建议

新项目选型决策树

团队主要技术栈?
├─ Go / TypeScript / Kotlin / Swift / Dart
│  └─ 强烈推荐 ConnectRPC(开发体验最优)
├─ Java / Python / C# / C++ / Rust
│  └─ 推荐 gRPC(生态更成熟)
└─ 多语言混合(>5 种)
   └─ 折中方案:Connect 服务端 + gRPC 协议兼容
      (现代语言用 Connect 客户端,其他用标准 gRPC 客户端)

2024-2025 关键里程碑

  • CNCF 入驻:ConnectRPC 正式加入云原生计算基金会,承诺长期社区治理
  • Connect-ES 2.0:TypeScript 实现全面 GA,支持 Protobuf-ES 2.0 反射 API
  • Connect-Swift 1.0:iOS 开发进入稳定期
  • 协议一致性测试套件:开源的 connectconformance 工具验证多语言实现正确性,已发现 Google gRPC 实现中的 22+ 个兼容性问题

生产环境采用现状

据 Buf 官方披露,ConnectRPC 已在以下规模企业落地:

  • CrowdStrike(端点安全)
  • PlanetScale(数据库平台)
  • Chick-fil-A(餐饮数字化)
  • BlueSky(去中心化社交)
  • Dropbox(云存储)

总结

ConnectRPC 并非要取代 gRPC,而是在保持 gRPC 核心优势(类型安全、高性能、流式支持)的基础上,消除其与现代开发流程的摩擦

选择 ConnectRPC 的场景

  • 需要浏览器、移动端、后端共享同一 API 定义
  • 重视开发者体验(调试、测试、文档生成)
  • 基础设施对 HTTP/2 支持不完善(边缘节点、遗留负载均衡器)
  • 希望逐步现代化存量 gRPC 服务

继续选择官方 gRPC 的场景

  • 纯后端微服务且追求极致性能调优
  • 需要 10+ 种编程语言的官方支持(尤其 C++、Rust、PHP)
  • 团队已深度投入 gRPC 生态(自定义负载均衡、服务网格等)

ConnectRPC 代表了 RPC 框架的进化方向:协议标准化与实现现代化的分离。正如 HTTP/2 并未完全取代 HTTP/1.1,Connect 与 gRPC 将在长期共存,而 Connect 的"三协议合一"设计,让它成为连接过去与未来的桥梁。

资源链接

评论