# 14. gRPC Adoption Strategy **Date:** 2026-04-05 **Status:** Accepted **Authors:** Arcodange Team ## Context The DanceLessonsCoach project currently uses REST/JSON for all API communication. As the project evolves, we need to determine when and how to adopt gRPC for performance-critical and internal communication scenarios. ## Decision Drivers * **Current Needs**: Simple API with good REST support * **Future Growth**: Potential for mobile apps and microservices * **Performance**: Current REST performance is adequate * **Complexity**: gRPC adds significant architectural complexity * **Team Expertise**: Strong REST/JSON experience, limited gRPC experience * **Ecosystem**: Existing tooling and documentation for REST ## Considered Options ### Option 1: Immediate Full gRPC Adoption **Description:** Replace all REST endpoints with gRPC immediately **Pros:** - Future-proof architecture - Best performance from day one - Clean slate design **Cons:** - Significant development effort - Steep learning curve - Breaking changes for existing clients - Overkill for current needs ### Option 2: Hybrid Approach (Recommended) **Description:** Keep REST for public API, add gRPC for internal/services **Pros:** - Backward compatibility maintained - Gradual learning curve - Performance where needed - Flexibility for future growth **Cons:** - More complex architecture - Need to maintain both protocols - Gateway translation overhead ### Option 3: REST Only **Description:** Continue with REST/JSON only **Pros:** - Simple and well-understood - Good tooling and debugging - No architectural changes needed **Cons:** - May limit future scalability - Performance ceiling - Harder to add real-time features ### Option 4: gRPC for New Features Only **Description:** Use REST for existing, gRPC for new features **Pros:** - No breaking changes - Learn gRPC gradually - Performance for new features **Cons:** - Inconsistent API surface - Complex migration path - Harder to maintain coherence ## Decision Outcome **Chosen option:** **Option 2 - Hybrid Approach** ### Implementation Strategy **Phase 1: Preparation (Current)** - ✅ Document gRPC adoption strategy (this ADR) - ✅ Implement OpenAPI/Swagger for REST (ADR-0013) - ✅ Continue REST development - ✅ Monitor performance metrics **Phase 2: Foundation (When Needed)** ```bash # Add gRPC dependencies go get google.golang.org/grpc go get google.golang.org/protobuf # Create proto directory mkdir -p proto/greet # Add basic protobuf definition cat > proto/greet/greet.proto << 'EOF' syntax = "proto3"; package greet.v1; service GreetService { rpc Greet (GreetRequest) returns (GreetResponse); } message GreetRequest { string name = 1; } message GreetResponse { string message = 1; } EOF ``` **Phase 3: Internal Services (Future)** ```go // When adding internal services: // User Service <--gRPC--> Greet Service // Analytics Service <--gRPC--> Greet Service func (s *Server) startGRPC() { if s.config.GRPC.Enabled { lis, err := net.Listen("tcp", s.config.GRPC.Address) if err != nil { log.Error().Err(err).Msg("Failed to listen for gRPC") return } grpcServer := grpc.NewServer() proto.RegisterGreetServiceServer(grpcServer, s.grpcHandler) log.Info().Str("address", s.config.GRPC.Address).Msg("Starting gRPC server") if err := grpcServer.Serve(lis); err != nil { log.Error().Err(err).Msg("gRPC server failed") } } } ``` **Phase 4: Mobile Clients (Future)** ```bash # When adding mobile apps: # iOS/Android App --gRPC--> DanceLessonsCoach # Generate mobile clients protoc --plugin=protoc-gen-grpc=`which grpc_swift_plugin` \ --grpc_swift_out=. \ proto/greet/greet.proto ``` ## Consequences ### Positive 1. **Backward Compatibility**: Existing REST clients continue working 2. **Performance**: gRPC available when needed for critical paths 3. **Flexibility**: Can choose right protocol for each use case 4. **Gradual Learning**: Team can learn gRPC at appropriate pace 5. **Future-Proof**: Architecture ready for growth ### Negative 1. **Complexity**: More moving parts to maintain 2. **Overhead**: Gateway translation between protocols 3. **Learning Curve**: Team needs to learn gRPC eventually 4. **Build Complexity**: Additional build steps for protobuf ### Mitigations 1. **Documentation**: Comprehensive gRPC guides and examples 2. **Training**: Gradual team education on gRPC concepts 3. **Tooling**: Automate protobuf generation in CI/CD 4. **Monitoring**: Track protocol usage and performance ## Verification ### Success Criteria 1. ✅ REST API remains fully functional 2. ✅ gRPC can be enabled via configuration 3. ✅ No performance regression in REST paths 4. ✅ Clear documentation for both protocols 5. ✅ CI/CD supports both REST and gRPC testing ### Test Plan ```bash # Test REST still works curl http://localhost:8080/api/v1/greet/John # Expected: {"message":"Hello John!"} # Test gRPC can be disabled by default export DLC_GRPC_ENABLED=false ./bin/server # Expected: Only REST server starts # Test configuration validation DLC_GRPC_ENABLED=true DLC_GRPC_PORT=invalid ./bin/server # Expected: Configuration error, clean exit ``` ## Related Decisions - [ADR-0002: Chi Router](adr/0002-chi-router.md) - Current routing framework - [ADR-0013: OpenAPI/Swagger](adr/0013-openapi-swagger-toolchain.md) - REST documentation - [ADR-0010: API v2 Feature Flag](adr/0010-api-v2-feature-flag.md) - Versioning strategy ## Future Triggers **Consider implementing gRPC when any of these occur:** 1. **Mobile App Development**: Need for efficient mobile communication 2. **Microservices**: Adding internal services that need gRPC 3. **Performance Issues**: REST becomes bottleneck at scale 4. **Real-time Features**: Need for streaming/bidirectional communication 5. **Team Readiness**: Team comfortable with gRPC concepts ## Revision History - **1.0 (2026-04-05)**: Initial decision - **1.1 (2026-04-05)**: Added implementation phases and triggers ## References - [gRPC Documentation](https://grpc.io/docs/) - [Protocol Buffers](https://developers.google.com/protocol-buffers) - [gRPC vs REST Comparison](https://grpc.io/blog/grpc-vs-rest) - [Hybrid API Design](https://cloud.google.com/blog/products/api-management/designing-hybrid-apis) **Approved by:** Arcodange Team **Effective Date:** 2026-04-05 ## Configuration Reference ```yaml # config.yaml example for future gRPC support grpc: enabled: false # Set to true to enable gRPC server host: "0.0.0.0" port: "50051" reflection: true # Enable for development max_msg_size: 4194304 # 4MB max message size rest: enabled: true # REST remains enabled host: "0.0.0.0" port: "8080" ``` ## Migration Checklist - [ ] Add gRPC dependencies to go.mod - [ ] Create proto directory structure - [ ] Add basic greet.proto definition - [ ] Implement gRPC server (disabled by default) - [ ] Add configuration options - [ ] Update CI/CD for protobuf generation - [ ] Add gRPC health checks - [ ] Document gRPC usage - [ ] Performance benchmarking - [ ] Gradual rollout to production ## Monitoring Metrics **Recommended metrics to track:** ```prometheus # REST metrics rest_requests_total{endpoint="/api/v1/greet", status="200"} rest_response_time_seconds{quantile="0.95"} # gRPC metrics (when enabled) grpc_server_handling_seconds{grpc_method="Greet", grpc_code="OK"} grpc_server_started_total{grpc_method="Greet"} # Comparison metrics api_latency_comparison{protocol="rest", endpoint="/greet"} api_latency_comparison{protocol="grpc", endpoint="/greet"} ```