Proto-First API Design: Why We Chose Connect RPC
REST APIs are a liability at scale. You write an OpenAPI spec, then write the server that hopefully matches it, then write a client that hopefully matches both. Schema drift is inevitable — a field gets renamed on the server but the client still sends the old name, a nullable field becomes required but nobody updates the docs, an endpoint changes its response shape and three downstream services break silently. Manual validation, manual serialization, manual everything. It works until it doesn't, and then you spend days tracing why service A and service B disagree on what a "user" looks like.
Why Protocol Buffers
Protocol Buffers give you a single source of truth. You define your data structures and service methods in .proto files, and everything else is generated. TypeScript clients, Python clients, Go servers — all generated from the same schema. The types are guaranteed to match because they come from the same source. You can't have schema drift when there's only one schema. Add a field? Every client and server that uses that message gets updated in the next codegen run. Rename a field? The compiler tells you everywhere it breaks before you ship.
Connect RPC
We chose Connect RPC because it solves the gRPC adoption problem. Traditional gRPC requires HTTP/2 and a binary protocol, which means you can't call it from a browser without a proxy. Connect RPC supports three protocols in one: gRPC (binary over HTTP/2), gRPC-Web (binary over HTTP/1.1), and Connect Protocol (JSON over HTTP/1.1). Your browser can call the same service that your backend calls, with the same type safety, without any proxy layer. It also supports streaming — server-sent events, bidirectional streams — out of the box.
Our workflow is straightforward: edit the .proto file, run riven proto generate, implement the new method, ship. The codegen step produces typed clients, server stubs, and validation code. There's no manual serialization, no hand-written API clients, no Postman collections to maintain. When a new engineer joins, they read the proto files to understand every API in the system. The protos are the documentation, the contract, and the implementation guide all in one.
Results
Since adopting proto-first design across our entire platform, we've had zero schema bugs in production. When we add a new field to a service, every consumer gets type-safe access to it in minutes. Our frontend and backend teams never argue about API contracts because the contract is generated code, not a wiki page. Developer velocity increased measurably — shipping a new API endpoint went from a multi-day process of writing specs, implementing handlers, and building clients to a single proto change and a codegen run. The upfront investment in tooling paid for itself within weeks.