Overview
Silky adopts a classic microservice architecture built around:
- Service isolation: Each service owns its own database and is independently deployable
- RPC communication: Inter-service calls via DotNetty TCP (binary protocol)
- Service discovery: Centralized registry (Zookeeper / Nacos / Consul)
- Unified gateway: Single external entry point via a dedicated gateway host
Architecture Diagram

The typical deployment topology:
External Clients (Web, Mobile, Third-party)
│
▼
┌───────────────────┐
│ Gateway Host │ Routes HTTP requests to internal RPC calls
└───────────────────┘
│
┌─────┴──────┐
│ Registry │ (Zookeeper / Nacos / Consul)
└─────┬──────┘
│ service discovery
┌─────┴─────────────────────────┐
│ Internal Services │
│ ┌──────────┐ ┌──────────┐ │
│ │ Service A│ │ Service B│ │
│ │ (RPC) │ │ (RPC) │ │
│ └──────────┘ └──────────┘ │
└───────────────────────────────┘
│
┌─────┴──────────────────────────┐
│ Infrastructure │
│ Redis │ DB │ MQ │ ... │
└─────────────────────────────────┘
Project Structure Convention
A standard Silky microservice solution follows a layered project structure:
MySolution/
MySolution.sln
src/
GatewayHost/ # Gateway
OrderService/
OrderService.Host/ # Startup host
OrderService.Application/ # Application service implementations
OrderService.Application.Contracts/ # Interfaces & DTOs (shared)
OrderService.Domain/ # Entities, domain services
OrderService.Domain.Shared/ # Enums, constants, shared types
OrderService.EntityFrameworkCore/ # DbContext, migrations
The Application.Contracts project contains only interfaces and DTOs and is referenced by both the service implementation and by clients (other services that call it).
Communication Patterns
RPC (Inter-Service)
Service A ──RPC──▶ Service B
- DotNetty TCP binary protocol
- Address resolved via registry at startup
- Load balancing from local cache
- Governance applied (timeout, circuit break, retry)
HTTP (External → Gateway)
External Client ──HTTP──▶ Gateway ──RPC──▶ Internal Service
- Gateway maps REST endpoints to service entry IDs
- Swagger aggregation for API documentation
- JWT authentication on the gateway layer
Message Queue (Async)
Service A ──Publish──▶ MassTransit ──Consume──▶ Service B
- Use
Silky.MassTransitfor event-driven integration - Suitable for non-blocking or cross-domain events
Multi-Tenant & Cross-Cutting Concerns
Silky propagates the following through the RpcContext automatically:
| Concern | How |
|---|---|
| User Identity | JWT claims extracted at gateway, propagated in RpcContext |
| Tenant ID | Propagated via RpcContext attachments |
| Trace ID | SkyAPM / correlation ID from the outer HTTP context |
| Request Metadata | Custom RpcContext attachments |
Domain-Driven Design Alignment
Silky is designed to complement DDD:
| DDD Layer | Silky Mapping |
|---|---|
| Interfaces (API) | IXxxxAppService + [ServiceRoute] |
| Application | XxxxAppService implementations |
| Domain | Entities, domain services, repositories |
| Infrastructure | EFCore DbContext, cache, message bus |
