zel_core 0.3.0

Type-safe RPC framework built on Iroh with support for methods, subscriptions, notifications, and raw streams
Documentation

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:

  1. Methods (#[method]) - Request/response RPC calls
  2. Subscriptions (#[subscription]) - Server-to-client streaming
  3. Notifications (#[notification]) - Client-to-server streaming
  4. 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 = RpcServerBuilder::new(b"app/1", endpoint)
    .with_circuit_breaker(CircuitBreakerConfig::builder()
        .failure_threshold(0.5)
        .consecutive_failures(5)
        .build())
    .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 = IrohBundle::builder(None).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