gRPC Crate
The mockforge-grpc crate provides comprehensive gRPC protocol support for MockForge, featuring dynamic service discovery, runtime protobuf parsing, and HTTP bridge capabilities. It enables automatic mocking of gRPC services without code generation, supporting all streaming patterns and providing rich introspection features.
Architecture Overview
graph TD
A[gRPC Server] --> B[Dynamic Service Discovery]
B --> C[Proto Parser]
C --> D[Service Registry]
D --> E[Dynamic Service Generator]
A --> F[gRPC Reflection]
F --> G[Reflection Proxy]
G --> H[Descriptor Pool]
A --> I[HTTP Bridge]
I --> J[REST API Generator]
J --> K[OpenAPI Spec]
A --> L[Streaming Support]
L --> M[Unary RPC]
L --> N[Server Streaming]
L --> O[Client Streaming]
L --> P[Bidirectional Streaming]
Core Components
Dynamic Service Discovery
The gRPC crate’s core innovation is runtime service discovery and mocking without code generation:
Proto Parser
#![allow(unused)] fn main() { // Parse protobuf files at runtime let mut parser = ProtoParser::new(); parser.parse_directory("./proto").await?; // Extract services and methods let services = parser.services(); let descriptor_pool = parser.into_pool(); }
Service Registry
#![allow(unused)] fn main() { // Create registry with parsed services let mut registry = ServiceRegistry::with_descriptor_pool(descriptor_pool); // Register dynamic service implementations for (name, proto_service) in services { let dynamic_service = DynamicGrpcService::new(proto_service, config); registry.register(name, dynamic_service); } }
gRPC Reflection
Reflection Proxy
Enables runtime service discovery and method invocation:
#![allow(unused)] fn main() { let proxy_config = ProxyConfig::default(); let mock_proxy = MockReflectionProxy::new(proxy_config, registry).await?; // Server supports reflection queries // grpcurl -plaintext localhost:50051 list // grpcurl -plaintext localhost:50051 describe MyService }
Descriptor Management
- Descriptor Pool: In-memory protobuf descriptor storage
- Dynamic Resolution: Runtime method and message resolution
- Schema Introspection: Full protobuf schema access
HTTP Bridge
REST API Generation
Automatically converts gRPC services to REST endpoints:
#![allow(unused)] fn main() { let config = DynamicGrpcConfig { enable_http_bridge: true, http_bridge_port: 8080, generate_openapi: true, ..Default::default() }; // gRPC: MyService/GetUser → HTTP: POST /api/myservice/getuser }
OpenAPI Generation
- Automatic OpenAPI 3.0 spec generation from protobuf definitions
- REST endpoint documentation
- Request/response schema documentation
Streaming Support
All Streaming Patterns
The crate supports all four gRPC streaming patterns:
- Unary RPC: Simple request-response
- Server Streaming: Single request, streaming response
- Client Streaming: Streaming request, single response
- Bidirectional Streaming: Streaming in both directions
Streaming Implementation
#![allow(unused)] fn main() { // Server streaming async fn list_users( &self, request: Request<ListUsersRequest>, ) -> Result<Response<Self::ListUsersStream>, Status> { // Return stream of User messages } // Bidirectional streaming async fn chat( &self, request: Request<Streaming<ChatMessage>>, ) -> Result<Response<Self::ChatStream>, Status> { // Handle bidirectional message stream } }
Key Modules
dynamic/
Core dynamic service functionality:
proto_parser.rs
- Runtime protobuf file parsing
- Service and method extraction
- Message descriptor generation
service_generator.rs
- Dynamic service implementation generation
- Mock response synthesis
- Streaming method handling
http_bridge/
- REST API conversion logic
- OpenAPI specification generation
- HTTP request/response mapping
reflection/
gRPC reflection protocol implementation:
mock_proxy.rs
- Reflection service implementation
- Dynamic method invocation
- Response generation
client.rs
- Reflection client for service discovery
- Dynamic RPC calls
- Connection pooling
smart_mock_generator.rs
- AI-powered response generation
- Schema-aware data synthesis
- Contextual mock data
registry.rs
Service registration and management:
#![allow(unused)] fn main() { pub struct GrpcProtoRegistry { services: HashMap<String, ProtoService>, descriptor_pool: DescriptorPool, } }
Configuration
DynamicGrpcConfig
#![allow(unused)] fn main() { #[derive(Debug, Clone)] pub struct DynamicGrpcConfig { pub proto_dir: String, // Proto file directory pub enable_reflection: bool, // Enable gRPC reflection pub excluded_services: Vec<String>, // Services to skip pub http_bridge: Option<HttpBridgeConfig>, // HTTP bridge settings pub max_message_size: usize, // Max message size } }
HTTP Bridge Config
#![allow(unused)] fn main() { pub struct HttpBridgeConfig { pub enabled: bool, // Enable HTTP bridge pub port: u16, // HTTP server port pub generate_openapi: bool, // Generate OpenAPI specs pub cors_enabled: bool, // Enable CORS } }
Advanced Data Synthesis
Intelligent Field Inference
The crate uses field names and types to generate realistic mock data:
message User {
string id = 1; // Generates UUIDs
string email = 2; // Generates email addresses
string phone = 3; // Generates phone numbers
repeated string tags = 4; // Generates string arrays
}
Referential Integrity
Maintains relationships between messages:
- Foreign key relationships
- Consistent ID generation
- Cross-message data consistency
Deterministic Seeding
#![allow(unused)] fn main() { // Reproducible test data let config = MockConfig { seed: Some(42), ..Default::default() }; }
Performance Features
Connection Pooling
- Efficient gRPC connection management
- Connection reuse and lifecycle management
- Load balancing across connections
Caching
- Descriptor caching for performance
- Response caching for repeated requests
- Schema compilation caching
Async Processing
- Tokio-based async runtime
- Streaming data processing
- Concurrent request handling
Integration Points
Core Dependencies
mockforge-core: Base mocking functionalitymockforge-data: Advanced data generationmockforge-observability: Metrics and tracing
External Libraries
- Tonic: gRPC framework for Rust
- Prost: Protocol buffer implementation
- Prost-reflect: Runtime protobuf reflection
- Tokio: Async runtime
Observability
Metrics Collection
- Request/response counts
- Method execution times
- Error rates by service/method
- Streaming metrics
Tracing Integration
- OpenTelemetry tracing support
- Distributed tracing across services
- Request correlation IDs
Logging
- Structured logging for all operations
- Debug logging for request/response payloads
- Performance logging
Testing Support
Integration Tests
- End-to-end gRPC testing
- HTTP bridge validation
- Reflection service testing
- Streaming functionality tests
Mock Data Generation
- Deterministic test data
- Schema-compliant mock generation
- Custom data providers
Error Handling
gRPC Status Codes
- Proper gRPC status code mapping
- Detailed error messages
- Error correlation IDs
Recovery Mechanisms
- Connection retry logic
- Graceful degradation
- Fallback responses
Build System
Proto Compilation
The crate uses tonic-prost-build for compile-time proto generation:
// build.rs fn main() -> Result<(), Box<dyn std::error::Error>> { tonic_build::compile_protos("proto/greeter.proto")?; Ok(()) }
Feature Flags
data-faker: Enable advanced data synthesis- Default features include data faker for rich mock data
Usage Examples
Basic gRPC Server
use mockforge_grpc::start; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { // Auto-discovers services from ./proto directory start(50051).await?; Ok(()) }
With HTTP Bridge
#![allow(unused)] fn main() { use mockforge_grpc::{start_with_config, DynamicGrpcConfig}; let config = DynamicGrpcConfig { proto_dir: "./proto".to_string(), enable_reflection: true, http_bridge: Some(HttpBridgeConfig { enabled: true, port: 8080, generate_openapi: true, }), ..Default::default() }; start_with_config(50051, None, config).await?; }
Client Usage
# List services
grpcurl -plaintext localhost:50051 list
# Describe service
grpcurl -plaintext localhost:50051 describe MyService
# Call method
grpcurl -plaintext -d '{"id": "123"}' localhost:50051 MyService/GetUser
# HTTP bridge
curl -X POST http://localhost:8080/api/myservice/getuser \
-H "Content-Type: application/json" \
-d '{"id": "123"}'
Future Enhancements
- Advanced Streaming: Enhanced bidirectional streaming support
- Service Mesh Integration: Istio and Linkerd integration
- Schema Evolution: Automatic handling of protobuf schema changes
- Load Testing: Built-in gRPC load testing capabilities
- Code Generation: Optional compile-time service generation