25 KiB
25 KiB
StellaOps Router Architecture
This document describes the internal architecture of the StellaOps Router framework.
Core Components
1. Router Gateway
The Gateway is the HTTP ingress point that accepts client requests and routes them to appropriate microservices.
┌─────────────────────────────────────────────┐
│ Router Gateway │
│ │
HTTP Request ──────►│ ┌────────────────────────────────────────┐ │
│ │ Middleware Pipeline │ │
│ │ ├─ Authentication │ │
│ │ ├─ Authorization │ │
│ │ └─ Rate Limiting │ │
│ └────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────┐ │
│ │ Route Resolution │ │
│ │ - Path matching │ │
│ │ - Service discovery │ │
│ │ - Load balancing │ │
│ └────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────┐ │
│ │ Request Dispatch │ │
│ │ - Serialize to binary │ │
│ │ - Send via transport │ │
│ │ - Await response │ │
│ └────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────┐ │
│ │ Response Processing │ │
│ │ - Deserialize from binary │ │
│ │ - Transform headers │ │
│ │ - Stream body │ │
│ └────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────┘
│
▼ Binary Protocol
┌─────────────────────────────────────────────┐
│ Microservices │
└─────────────────────────────────────────────┘
Key Classes:
RouterGatewayMiddleware- ASP.NET Core middleware for request handlingServiceRegistry- Tracks registered microservices and their endpointsRouteResolver- Matches incoming paths to service endpointsRequestDispatcher- Sends requests via appropriate transport
2. Microservice SDK
The SDK provides the programming model for building microservices with typed endpoints.
┌──────────────────────────────────────────────────────────────────┐
│ Microservice Process │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Endpoint Handlers (User Code) │ │
│ │ │ │
│ │ [StellaEndpoint("POST", "/orders")] │ │
│ │ class CreateOrderEndpoint : IStellaEndpoint<Req, Res> │ │
│ │ │ │
│ │ [StellaEndpoint("GET", "/stream", SupportsStreaming=true)]│ │
│ │ class StreamEndpoint : IRawStellaEndpoint │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ EndpointDescriptorProvider (Source Generated) │ │
│ │ - Collects all [StellaEndpoint] in assembly │ │
│ │ - Provides routing metadata at startup │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ MicroserviceHost │ │
│ │ - Connects to gateway │ │
│ │ - Registers endpoints │ │
│ │ - Dispatches incoming requests to handlers │ │
│ │ - Manages heartbeat and reconnection │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Transport Client │ │
│ │ (InMemory, TCP, TLS, RabbitMQ, etc.) │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────┘
Key Classes:
StellaEndpointAttribute- Marks endpoint classes with routing metadataIStellaEndpoint<TRequest, TResponse>- Typed endpoint interfaceIRawStellaEndpoint- Raw/streaming endpoint interfaceMicroserviceHost- Manages service lifecycle and gateway connection
3. Transport Layer
The transport layer provides pluggable communication protocols.
┌────────────────────────────────────────────────────────────────────┐
│ Transport Abstraction │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ ITransportServer / ITransportClient │ │
│ │ - ConnectAsync / AcceptAsync │ │
│ │ - SendAsync / ReceiveAsync │ │
│ │ - Disconnect / Dispose │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ InMemory │ │ TCP/TLS │ │ RabbitMQ │ │
│ │ Transport │ │ Transport │ │ Transport │ │
│ │ │ │ │ │ │ │
│ │ - Zero-copy │ │ - Binary │ │ - Async │ │
│ │ - Dev/test │ │ - Framing │ │ - Pub/Sub │ │
│ │ │ │ - Backpress │ │ - Durable │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ UDP │ │ Valkey │ │ PostgreSQL │ │
│ │ Transport │ │ Transport │ │ Transport │ │
│ │ │ │ │ │ │ │
│ │ - Broadcast │ │ - Streams │ │ - LISTEN/ │ │
│ │ - Fire&Forg │ │ - Consumer │ │ NOTIFY │ │
│ │ │ │ Groups │ │ - Txn queue │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
Transport Selection Guidelines:
| Scenario | Recommended Transport |
|---|---|
| Development/Testing | InMemory |
| Same-datacenter services | TCP |
| Cross-datacenter secure | TLS with mTLS |
| High-volume async | RabbitMQ |
| Broadcast notifications | UDP |
| Distributed with replay | Valkey Streams |
| Transactional messaging | PostgreSQL |
4. Binary Protocol
All transports use a common binary frame format:
┌────────────────────────────────────────────────────────────────┐
│ Frame Header (24 bytes) │
├────────────┬────────────┬────────────┬────────────┬────────────┤
│ Magic (4) │ Version(2) │ Type (2) │ Flags (4) │ Length (8) │
├────────────┴────────────┴────────────┴────────────┴────────────┤
│ Correlation ID (4) │
├─────────────────────────────────────────────────────────────────┤
│ Frame Payload │
│ │
│ For Request: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Method (1) │ Path Length (2) │ Path (variable) │ │
│ ├─────────────────────────────────────────────────────────┤ │
│ │ Header Count (2) │ Headers (key-length-key-val pairs) │ │
│ ├─────────────────────────────────────────────────────────┤ │
│ │ Body (remaining bytes) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ For Response: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Status Code (2) │ Header Count (2) │ Headers (...) │ │
│ ├─────────────────────────────────────────────────────────┤ │
│ │ Body (remaining bytes) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Frame Types:
0x01- Request0x02- Response0x03- Heartbeat0x04- Registration0x05- Acknowledgment0x10- Stream Chunk0x11- Stream End
5. Source Generator
The StellaOps.Microservice.SourceGen package generates code at compile time:
// Input: User-defined endpoint
[StellaEndpoint("POST", "/orders")]
public sealed class CreateOrderEndpoint : IStellaEndpoint<CreateOrderRequest, CreateOrderResponse>
{
// ...
}
// Generated: Endpoint descriptor
[GeneratedCode("StellaOps.Microservice.SourceGen", "1.0.0")]
internal static class StellaEndpointDescriptors
{
public static IEnumerable<EndpointDescriptor> GetDescriptors()
{
yield return new EndpointDescriptor
{
Method = HttpMethod.Post,
Path = "/orders",
TimeoutSeconds = 30,
SupportsStreaming = false,
HandlerType = typeof(CreateOrderEndpoint),
RequestType = typeof(CreateOrderRequest),
ResponseType = typeof(CreateOrderResponse)
};
}
}
// Generated: JSON Schema provider (if [ValidateSchema] present)
[GeneratedCode("StellaOps.Microservice.SourceGen", "1.0.0")]
internal static class CreateOrderRequestSchemaProvider
{
public static JsonSchema GetSchema() => JsonSchema.FromText("""
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"customerId": { "type": "string" },
"amount": { "type": "number" }
},
"required": ["customerId", "amount"]
}
""");
}
Request Flow
1. Service Registration
Microservice Gateway
│ │
│─────── Connect ─────────────►│
│ │
│─────── Register ────────────►│
│ (service name, version, │ ┌───────────────┐
│ endpoint descriptors) │ │ ServiceReg │
│ │ │ Registry │
│◄────── Ack ─────────────────│ └───────────────┘
│ │
│◄─────► Heartbeat ───────────►│ (every 30s)
│ │
2. Request Dispatch
Client Gateway Microservice
│ │ │
│── HTTP Req ──►│ │
│ │ │
│ │── Route Resolve ─► │
│ │ (path matching) │
│ │ │
│ │── Binary Frame ───────────►│
│ │ (via transport) │
│ │ │
│ │ │── Handle
│ │ │ Request
│ │ │
│ │◄── Binary Response ────────│
│ │ │
│◄─ HTTP Resp ──│ │
│ │ │
3. Streaming
Client Gateway Microservice
│ │ │
│── HTTP POST ─►│ │
│ (chunked) │ │
│ │── Stream Start ───────────►│
│ │ │
│ ┌─ chunk 1 ─►│── Stream Chunk ───────────►│
│ │ │ │
│ │ chunk 2 ─►│── Stream Chunk ───────────►│
│ │ │ │
│ └ chunk N ─►│── Stream End ─────────────►│
│ │ │
│ │◄── Response ───────────────│
│◄─ HTTP 200 ──│ │
│ │ │
Configuration Loading
┌─────────────────────────────────────────────────────────────────┐
│ Configuration Sources │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ YAML Files │ │ Environment │ │ IConfiguration │ │
│ │ │ │ Variables │ │ (ASP.NET) │ │
│ │ - router.yaml│ │ │ │ │ │
│ │ - microserv. │ │ STELLA_* │ │ appsettings.json │ │
│ │ .yaml │ │ │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
│ │ │ │ │
│ └────────────────┬────────────────────┘ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ RouterConfig │ │
│ │ Provider │ │
│ │ │ │
│ │ - Hot reload │ │
│ │ - Validation │ │
│ │ - Defaults │ │
│ └──────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
Error Handling
Transport Errors
- Connection failures trigger automatic reconnection with exponential backoff
- Failed requests are retried based on idempotency metadata
- Circuit breaker prevents cascading failures
Request Errors
- Timeout errors return 504 Gateway Timeout
- Validation errors return 400 Bad Request with details
- Handler exceptions return 500 with sanitized message
Resilience Patterns
// Retry policy (configured in microservice.yaml)
retryPolicy:
maxAttempts: 3
initialDelay: 100ms
maxDelay: 5s
retryableStatuses: [502, 503, 504]
// Circuit breaker (configured in router.yaml)
circuitBreaker:
failureThreshold: 5
samplingDuration: 10s
breakDuration: 30s
Security
Transport Security
- TLS 1.3 for encrypted communication
- mTLS for mutual authentication
- Certificate validation with configurable CA trust
Gateway Security
- Integration with Authority module for OAuth/OIDC
- Claims-based authorization at route level
- Rate limiting per client/tenant
Message Security
- Optional message signing for integrity
- Tenant isolation in multi-tenant deployments
- Audit logging of all requests
Performance Characteristics
| Metric | InMemory | TCP | TLS | RabbitMQ |
|---|---|---|---|---|
| Latency (p50) | < 0.1ms | < 1ms | < 2ms | < 5ms |
| Latency (p99) | < 0.5ms | < 5ms | < 10ms | < 20ms |
| Throughput | 500K rps | 100K rps | 80K rps | 50K rps |
| Memory/conn | N/A | 2KB | 8KB | 16KB |
Benchmarks run on AMD EPYC with 10GB network, small payloads (<1KB)