Zel RPC Framework
A type-safe RPC framework built on Iroh! Out of the box support for methods, subscriptions (server to client stream), notifications (client to server stream), and raw bidirectional streams.
Table of Contents
Architecture Overview
Zel RPC provides four types of endpoints:
- Methods (
#[method]) - Request/response RPC calls - Subscriptions (
#[subscription]) - Server-to-client streaming - Notifications (
#[notification]) - Client-to-server streaming - Raw Streams (
#[stream]) - Bidirectional custom protocols (BYOP)
All endpoints receive a RequestContext providing access to:
- The underlying Iroh connection
- Three-tier extension system (server/connection/request)
- Remote peer information
Iroh Integration
Connection Lifecycle
sequenceDiagram
participant C as Client
participant S as Server<br/>(ALPN: myapp/1)
participant SVC as Service: users
participant RES as Resource: create
Note over C,S: Connection Setup
C->>S: connect(peer_id, "myapp/1")
S->>S: accept connection
Note over C,RES: Request Flow
C->>S: open_bi() stream
S->>S: accept_bi() → spawn handler
C->>S: Request { service: "users", resource: "create", body: {...} }
S->>SVC: Route to service "users"
SVC->>RES: Route to resource "create"
RES->>RES: Handle with RequestContext
RES->>S: Response
S->>C: Response
Note over C,S: Each request gets own stream
RequestContext & Extensions
Server Extensions (Shared)
- Database connection pools
- Configuration
- Shared caches
- Metrics collectors
Connection Extensions (Isolated)
- User sessions
- Authentication state
- Per-peer metrics
Request Extensions (Unique)
- Distributed trace IDs
- Request timing
- Per-call context
See examples/context_extensions_demo.rs for complete implementation
Extension Lifecycle
sequenceDiagram
participant User as User Code
participant Builder as RpcServerBuilder
participant Server as RpcServer
participant ConnHandler as Connection Handler
participant ReqHandler as Request Handler
User->>Builder: with_extensions(db_pool)
Note over Builder: Server extensions stored
User->>Builder: with_connection_hook(auth_hook)
Note over Builder: Hook registered
User->>Builder: with_request_middleware(tracer)
Note over Builder: Middleware registered
Builder->>Server: build()
loop For each connection
Server->>ConnHandler: New connection
ConnHandler->>ConnHandler: Call connection_hook()
Note over ConnHandler: Creates connection_extensions
loop For each request
ConnHandler->>ReqHandler: New request
Note over ReqHandler: Creates RequestContext with:<br/>- server_extensions<br/>- connection_extensions<br/>- empty request_extensions
ReqHandler->>ReqHandler: Apply middleware chain
Note over ReqHandler: Each middleware enriches<br/>request_extensions
ReqHandler->>User: Handler(ctx, params)
User->>User: Access extensions via ctx
end
end
Connection Hooks
Run once per connection before any requests are processed. Used for authentication, session setup, etc.
Request Middleware
Run for every request in a chain. Used for tracing, logging, timing, etc.
See examples/context_extensions_demo.rs for implementation patterns
Service Definition
Methods
Request/response RPC - handler receives RequestContext as first parameter
Subscriptions
Server-to-client streaming - handler receives RequestContext and typed sink
Notifications
Client-to-server streaming - handler receives RequestContext, receive stream, and ack sender
Raw Streams
Custom bidirectional protocols - handler receives RequestContext, SendStream, RecvStream
See examples/macro_service_example.rs and examples/notification_example.rs for complete service definitions
Examples
Explore the zel_core/examples/ directory for working examples:
context_extensions_demo.rs- Three-tier extension system with database pools, sessions, and tracingmacro_service_example.rs- Service definition with methods and subscriptionsmulti_service_example.rs- Multiple services on single servernotification_example.rs- Client-to-server streamingraw_stream_example.rs- Custom bidirectional protocol (file transfer)