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
Zel uses a three-tier extension system to share context across different scopes:
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
📚 For complete documentation, see doc_more/EXTENSIONS.MD
💡 For working examples, see examples/context_extensions_demo.rs
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
P2P Resilience
Zel provides a few resilience tools out of the box:
- Per-Peer Circuit Breakers: Isolate sketchy peers (
RpcServerBuilder::with_circuit_breaker(CircuitBreakerConfig::builder().failure_threshold(0.5).build())). - Automatic Retries: Exponential backoff/jitter on client (
RpcClient::builder().with_retry_config(RetryConfig::builder().max_attempts(3).build())). - Error Classification: Infra errors (network/timeout) trip breakers; app errors (validation) don't.
- Monitoring:
RequestContext::remote_id(),connection_rtt(),connection_stats().
Example:
let server = new
.with_circuit_breaker
.build;
See doc_more/P2P-RESILIENCE.md for complete details.
Advanced Iroh Integration
Beyond transport, leverage:
IrohBundle::watch_addr(): Subscribe to EndpointAddr changes (NAT rebinding via netwatch).IrohBundle::notify_network_change(): Trigger addr refresh.IrohBundle::wait_online()/is_online(): Ensure node ready before RPCs.
P2P Quickstart Extension:
let bundle = builder.await?.finish.await;
bundle.wait_online.await; // Wait for holepunching/relays
Examples
See zel_core/examples/README.md for full list/table.
Quick Start: macro_service_example.rs