zel_core 0.5.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](https://iroh.computer/)! Out of the box support for methods, subscriptions (server to client stream), notifications (client to server stream), and raw bidirectional streams.

## Quick Start

```toml
# Cargo.toml
[dependencies]
zel_core = "0.3.2"
# Note: No need to add zel_types or zel_macros - everything is re-exported!
```

```rust
// Import everything with the prelude
use zel_core::prelude::*;

// Define your service
#[zel_service(name = "math")]
trait Math {
    #[method(name = "add")]
    async fn add(&self, a: i32, b: i32) -> Result<i32, ResourceError>;
}

// Implement it
#[derive(Clone)]
struct MathService;

#[async_trait]
impl MathServer for MathService {
    async fn add(&self, ctx: RequestContext, a: i32, b: i32)
        -> Result<i32, ResourceError>
    {
        Ok(a + b)
    }
}
```

## Table of Contents

- [Architecture Overview]#architecture-overview
- [Iroh Integration]#iroh-integration
  - [Connection Lifecycle]#connection-lifecycle
  - [Stream Types]#stream-types
- [RequestContext & Extensions]#requestcontext--extensions
  - [Three-Tier Extension System]#three-tier-extension-system
  - [Extension Lifecycle]#extension-lifecycle
  - [Connection Hooks]#connection-hooks
  - [Request Middleware]#request-middleware
- [Service Definition]#service-definition
  - [Methods]#methods
  - [Subscriptions]#subscriptions
  - [Notifications]#notifications
  - [Raw Streams]#raw-streams
- [Examples]#examples

---

## 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

```mermaid
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`](doc_more/EXTENSIONS.MD)**

**💡 For working examples, see [`examples/context_extensions_demo.rs`](zel_core/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`](zel_core/examples/macro_service_example.rs) and [`examples/notification_example.rs`](zel_core/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**:

```rust
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`](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**:

```rust
let bundle = IrohBundle::builder(None).await?.finish().await;
bundle.wait_online().await;  // Wait for holepunching/relays
```

## Examples

See [`zel_core/examples/README.md`](zel_core/examples/README.md) for full list/table.

**Quick Start**: [`macro_service_example.rs`](zel_core/examples/macro_service_example.rs)