Microservices & Event-Driven Architecture (EDA) Mastery

Protobuf and Shared Contracts: Managing breaking changes

1 Views Updated 5/4/2026

Contract-First Development

In microservices, the Contract is your only guarantee. If you change a field name in Service A, you might break Service B, C, and D instantly. You need a strategy to manage these changes safely.

1. Protobuf and Backward Compatibility

Protobuf (Protocol Buffers) uses **Field Numbers** instead of names. You can rename a field in your C# code, but as long as the number stays the same (e.g., `string name = 1`), old services will still be able to read it. **Rule:** Never change a field number, and never delete a field (just mark it as `deprecated`).

2. The Shared Library Antipattern

Don't share a NuGet package containing your 'Domain' models. If you update the library, you force every service to redeploy at the same time—this is a 'Distributed Monolith.' Instead, share only the **Interface** or the **Protobuf file**. Let each service generate its own local models from the contract.

4. Interview Mastery

Q: "How do you handle 'Breaking' changes in a message contract?"

Architect Answer: "We use **Parallel Support**. We introduce the new field in V2, but keep sending data to V1 for 3 months. Once all consumers have migrated to V2, we deprecate and eventually delete V1. We use **Consumer Driven Contracts (Pact)** to automatically test if our changes will break any of our known consumers before we even merge the PR."

Microservices & Event-Driven Architecture (EDA) Mastery
1. Foundations of Microservices
The Monolith to Microservices transition: When and why? Domain Driven Design (DDD): Bounded Contexts and Aggregates Database Per Service: Managing data consistency Service Discovery and Health Checks in .NET
2. Communication Patterns
Synchronous Communication: HTTP/gRPC and Service Mesh Asynchronous Communication: Message Brokers (RabbitMQ/Kafka) API Gateways: YARP (Yet Another Reverse Proxy) vs Ocelot Protobuf and Shared Contracts: Managing breaking changes
3. Event-Driven Architecture (EDA)
Introduction to EDA: Producers, Consumers, and Topics The Publisher/Subscriber Pattern in .NET Event Sourcing: Capturing every state change CQRS (Command Query Responsibility Segregation) with MediatR
4. Distributed Transactions & Resiliency
The Saga Pattern: Orchestration vs Choreography The Outbox Pattern: Ensuring reliable message delivery Idempotency: Preventing duplicate message processing Distributed Locking with Redis (Redlock)
5. Observability & Monitoring
Distributed Tracing with OpenTelemetry Centralized Logging: ELK Stack (Elasticsearch, Logstash, Kibana) Metrics and Dashboards: Prometheus and Grafana Correlation IDs: Tracking requests across services
6. Security & Identity
Centralized Authentication: IdentityServer4 & Duende Identity OAuth2 and OIDC Flow for Microservices API Key Management and Rate Limiting Mutual TLS (mTLS) for Internal Service-to-Service Security
7. Infrastructure & Deployment
Containerization: Production-grade Dockerfiles Kubernetes for .NET: Pods, Services, and Ingress Helm Charts: Managing complex deployments Blue-Green and Canary Deployments in K8s
8. FAANG Microservices Case Studies
Case Study: Designing a Global Notification Engine (Reliability at Scale) Case Study: Building a High-Performance Logging Pipeline (PB/Day)