Skip to content

feat(router): Add ConnectRPC protocol support for gRPC subgraphs #2664

@fengyuwusong

Description

@fengyuwusong

Component(s)

router

Is your feature request related to a problem? Please describe.

Currently, the Cosmo Router only supports native gRPC (HTTP/2 + Protobuf) for communicating with gRPC-based subgraphs. This requires HTTP/2 end-to-end, which creates friction in environments where:

  • Infrastructure (load balancers, API gateways, CDNs) doesn't fully support HTTP/2 or gRPC pass-through
  • Teams want to use JSON encoding for easier debugging and observability
  • Services are built with the ConnectRPC framework, which serves both Connect and gRPC protocols on the same port

There is no way to configure the router to use the Connect protocol (HTTP/1.1 + Protobuf/JSON) as an alternative transport for gRPC subgraphs.

Describe the solution you'd like

Add a grpc_protocol configuration section that allows users to choose between native gRPC and ConnectRPC on a per-subgraph basis:

grpc_protocol:
  default: grpc              # "grpc" | "connectrpc" (default: "grpc")
  default_encoding: proto    # "proto" | "json" (default: "proto")
  subgraphs:
    my-connect-service:
      protocol: connectrpc
      encoding: json

Key design points:

  1. Transport layer only — Connect subgraphs reuse the existing gRPC planning/compilation pipeline (RPCExecutionPlan, Mapping, Compiler). Only the transport is replaced.
  2. RPCTransport interface — Introduce an abstraction in graphql-go-tools (grpc_datasource.RPCTransport) so both native gRPC and Connect share the same interface.
  3. HTTP client reuse — Connect transports reuse the router's existing per-subgraph HTTP clients, inheriting TrafficShaping configuration (timeouts, retries, circuit breakers).
  4. Backward compatible — When no grpc_protocol config is provided, behavior is identical to today (native gRPC).
  5. Per-subgraph override — Global defaults with per-subgraph overrides for protocol and encoding.

This requires changes in two repositories:

  • graphql-go-tools: Add RPCTransport interface, ConnectTransport implementation, and NewFactoryConnect constructor
  • cosmo (router): Add grpc_protocol config, transport builder, and integration in factory resolver

Describe alternatives you've considered

  1. Adapt grpc.ClientConnInterface — Implement a custom ClientConn that speaks Connect under the hood. Rejected because it forces Connect's HTTP semantics into gRPC's streaming-oriented interface, adding unnecessary complexity.
  2. Sidecar proxy — Run a Connect-to-gRPC proxy alongside the router. Rejected because it adds operational overhead and latency.
  3. Middleware approach — Intercept at the HTTP layer and rewrite requests. Rejected because it's fragile and doesn't integrate with the planning pipeline.

Additional context

We have a working implementation that we'd like to contribute:

  • graphql-go-tools changes: ~500 lines (transport abstraction + Connect implementation + tests)
  • cosmo/router changes: ~200 lines (config + factory resolver integration)

The implementation has been validated in our production environment with mixed gRPC and Connect subgraphs. We'll submit PRs to both repositories referencing this issue.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions