ConnectRPC: Generate Typed SDKs from Your GraphQL API - WunderGraph
The Multi-Protocol Problem: Why GraphQL APIs Are Hard to Expose as REST or gRPC
You've built a federated GraphQL API. Your internal teams use it daily. The schema is well-governed, the subgraphs are cleanly separated, and the router handles composition and execution.
Then the requests start coming in. An external partner wants REST with an OpenAPI spec. A mobile team wants typed SDKs with compile-time safety. A backend service wants gRPC with binary encoding. Some consumers have hard platform constraints — a Roku box or embedded device can't run a GraphQL client library, needs minimal payload sizes, and may only support simple HTTP/JSON or binary protocols. These are platform limitations.
Today, you maintain separate API layers for each of these consumers. Separate codebases, separate contracts, separate deployment pipelines. Each one drifts from the others. The platform team becomes a bottleneck because every new consumption pattern requires a new integration layer.
Protocol Choice Is a Deployment Concern, Not an Implementation Problem
Your GraphQL schema already defines the data model, and your named operations define the access patterns. The missing piece is an intermediate representation that can target multiple protocols from that same source of truth.
Protocol Buffers are that intermediate representation, and they solve some of the hard problems: stable field numbering for wire compatibility, cross-language code generation through the Buf ecosystem, binary encoding for performance, and idempotency annotations for HTTP caching. While GraphQL solves the other half: schema governance, federation composition, and operation-level access control.
ConnectRPC bridges the two. GraphQL is the design layer where you model your data and curate your API surface, and Protocol Buffers are the compilation target that unlocks multi-protocol serving and typed SDK generation. The router handles the translation at runtime.
No More BFF Sprawl: Why Everything Downstream Is Generated
Everything downstream of the operations is deterministic. The same operations against the same schema always produce the same proto, the same SDKs, the same OpenAPI spec. There's no hand-written glue code, no one-off adapters, nothing to maintain. The only creative work is deciding what data to expose, in what shape, for which consumer.
That's the design problem.
Introducing Cosmo ConnectRPC
ConnectRPC is a protocol translation layer built into the Cosmo Router. It compiles GraphQL operations to Protocol Buffer definitions and serves them as multi-protocol APIs — gRPC, REST/HTTP, and typed client SDKs — turning what would be a multi-team, multi-month integration effort into a build-time generation step.
ConnectRPC is available today in Cosmo Router v0.283.0 and on Cosmo Cloud. It works with any Cosmo-managed federated graph, no schema changes or subgraph modifications required.
How ConnectRPC Turns GraphQL Operations into gRPC, REST, and Typed SDKs
At build time, you compile named GraphQL operations into Protocol Buffer definitions. The Buf toolchain then generates typed SDKs and OpenAPI specs from those protos.
Operations as API Contracts
API surfaces are defined as named GraphQL operations. There is one per file, each version-controlled as a persisted operation (also known as named operations or trusted documents). This is API design: each operation is an intentional choice about what data to expose, in what shape, and for which consumers. Consumers can only call these curated operations; there's no way to construct arbitrary queries or discover the underlying schema.
From Operations to Proto Definitions
A single CLI command compiles operations and schema into a Protocol Buffer service definition.
This produces service.proto and service.proto.lock.json. The generated proto for the operations follows proto3 conventions.
- GraphQL types become proto messages
- Fields get snake_case naming
- Nullable scalars use wrapper types, so nullability semantics are preserved
- Enums get a type prefix and an
_UNSPECIFIEDzero value.
API evolution is where most multi-protocol systems break. The lock file makes this a non-issue: commit it alongside your proto, and field numbers stay stable no matter how your operations evolve.
Router Configuration
Enabling ConnectRPC in the Cosmo Router is a configuration change. You point it at your services directory, and it will serve a ConnectRPC endpoint alongside your existing GraphQL endpoint.
SDK Generation via Buf
With a proto in hand, the Buf toolchain generates typed clients for any language.
One command. Go client, TypeScript client, and OpenAPI spec — all generated from the same proto.
What Consumers See
Consumers pick their protocol. The router handles the rest.
Why ConnectRPC Replaces Separate API Layers
Persisted operations as the API design surface. ConnectRPC treats named GraphQL operations as the API contract — each operation is an intentional design decision: which data to expose, in what shape, for which consumer.
Lock file for backward-compatible evolution. The service.proto.lock.json file tracks field number assignments across regenerations. When you modify an operation's selection set, existing field numbers are preserved and removed fields have their numbers reserved.
Idempotency annotations for HTTP caching. Query operations automatically get idempotency_level = NO_SIDE_EFFECTS in the proto definition.
Atomic hot reload. The router watches the services directory and picks up proto and operation changes without restarts.
One source of truth. Your GraphQL schema is the data model. Your named operations are the contracts. The proto is derived, the SDKs are derived, and the OpenAPI spec is derived. There is no drift because there is nothing to drift from.
| Without ConnectRPC | With ConnectRPC | |
|---|---|---|
| Protocol surfaces | Separate codebase per protocol | One set of operations, multiple outputs |
| Contract drift | Manual synchronization across layers | Derived from a single source — impossible to drift |
| API evolution | Coordinate changes across REST, gRPC, and GraphQL layers | Update operations, regenerate, lock file preserves compatibility |
| Team bottleneck | Platform team builds each adapter | Platform team curates operations; SDKs are generated |
| Security surface | Each layer has its own auth and validation | One execution path, one authorization model |
Use Cases: Partner APIs, Mobile SDKs, and Platform Governance
Extensive details on how to manage API for external partners and mobile SDK integration using ConnectRPC.
Performance Characteristics of ConnectRPC
ConnectRPC runs on Protocol Buffers — binary payloads are smaller than JSON and faster to serialize/deserialize.
Design Principle: Protocol Translation Belongs in Infrastructure
ConnectRPC is built on the belief that protocol translation belongs in infrastructure, not in application code.
What's on the ConnectRPC Roadmap
We’re exploring several directions based on early adopter feedback, including streaming support and API reference documentation.
Get Started with ConnectRPC
ConnectRPC is available now. The documentation covers configuration, CLI reference, and SDK generation in detail.
Frequently Asked Questions (FAQ)
What is Cosmo ConnectRPC? ConnectRPC is a protocol translation layer built into the Cosmo Router.
How does ConnectRPC differ from Cosmo Connect? Cosmo Connect lets backend teams implement gRPC services, while ConnectRPC exposes operations through gRPC, REST, and typed SDKs for downstream consumers.
What protocols does ConnectRPC support? ConnectRPC supports gRPC, REST/HTTP, and more.
How does the proto lock file work? The lock file tracks field number assignments.
Can I use ConnectRPC with an existing federated GraphQL API? Yes.
What languages are supported for SDK generation? SDK generation uses the Buf ecosystem, allowing support for multiple languages.