gRPC Service Migration Workflow
Introduce the gRPC service alongside REST, run both in parallel, shift consumers over using client-generation and observability, then retire the old surface.
Objective
Migrate from a REST service to gRPC without a flag day for consumers.
Environment
- A codegen pipeline for protobuf stubs
- Observability for both surfaces
Steps
1. Define the protobuf contract and generate
Define the protobuf contract and generate stubs for all languages.
Expected state: Consumers have typed clients.
2. Deploy the gRPC service in parallel
Deploy the gRPC service in parallel with the REST surface.
Expected state: Both work behind a common gateway.
3. Migrate consumers group by group
Migrate consumers group by group with feature flags.
Expected state: The shift is incremental and reversible.
4. Retire REST after usage reaches zero
Retire REST after usage reaches zero and metrics confirm gRPC parity.
Expected state: The old surface is removed deliberately.
Decision points
Keep a REST gateway permanently?
- Yes, for external clients
- No, internal only
Keep a gateway for external or unknown clients; retire it for fully controlled internal consumers.
Big-bang or phased?
- Phased by consumer
- All at once
Phase by consumer with flags; gRPC and REST have different failure and timeout semantics that need per-client validation.
Expected outcome
Consumers are on gRPC with equivalent functionality and acceptable latency, and the REST surface is retired without incidents.
Verification
Compare error rates and latency p99 between both surfaces during the overlap, and confirm REST call volume is zero before retirement.
Cleanup
Remove gateway routes and the REST implementation, and update client documentation.
Overview
Migrate from a REST service to gRPC without a flag day for consumers. Compare error rates and latency p99 between both surfaces during the overlap, and confirm REST call volume is zero before retirement.
Steps
- Define the protobuf contract and generate stubs for all languages. Expected state: Consumers have typed clients.
- Deploy the gRPC service in parallel with the REST surface. Expected state: Both work behind a common gateway.
- Migrate consumers group by group with feature flags. Expected state: The shift is incremental and reversible.
- Retire REST after usage reaches zero and metrics confirm gRPC parity. Expected state: The old surface is removed deliberately.
syntax = "proto3";
service Orders { rpc Get(GetRequest) returns (GetResponse); }
message GetRequest { string id = 1; }
message GetResponse { Order order = 1; }
Verification
- Consumers are on gRPC with equivalent functionality and acceptable latency, and the REST surface is retired without incidents.
Decision points
- Keep a REST gateway permanently? Options: Yes, for external clients; No, internal only. Recommended: Keep a gateway for external or unknown clients; retire it for fully controlled internal consumers.
- Big-bang or phased? Options: Phased by consumer; All at once. Recommended: Phase by consumer with flags; gRPC and REST have different failure and timeout semantics that need per-client validation.