README.md

# Wade

**Keep your socks dry.**

HTTP client-server for Erlang.

---

## Quick Start (HTTP/1.1)

```erlang
%% Start server
wade_app:start(8080).

%% Add route
wade:route(get, "/hello/[name]", fun(Req) ->
    Name = wade:param(Req, name),
    "Hello " ++ Name ++ "!"
end, []).
```

Visit `http://localhost:8080/hello/world`

---

## API

**One function rules them all:**

```erlang
wade:route(Method, Path, Handler, RequiredParams, RequiredHeaders).
```

**Helpers:**
- `wade:param(Req, Key)` - URL parameters
- `wade:query(Req, Key)` - Query string
- `wade:body(Req, Key)` - POST data
- `wade:method(Req)` - HTTP method

---

## Examples

```erlang
%% Simple route
wade:route(get, "/", fun(_) -> "Hello!" end, []).

%% URL parameters
wade:route(get, "/user/[id]", fun(Req) ->
    wade:param(Req, id)
end, []).

%% POST with validation
wade:route(post, "/api", Handler, [name, email]).

%% Any HTTP method
wade:route(any, "/api/[resource]", Handler, []).

%% JSON response
wade:route(get, "/json", fun(_) ->
    {200, "{\"ok\": true}", [{"Content-Type", "application/json"}]}
end, []).
```

No XML. No complex routing. No wet socks.

---

# Server-Sent Events (SSE)

Wade includes built-in support for Server-Sent Events (SSE) — a lightweight HTTP streaming protocol for sending real-time event updates from the server to connected clients. SSE enables one-way communication (server → client) over a persistent connection, ideal for live notifications, progress updates, and continuous data streams. With Wade’s simple API, you can register SSE routes and stream custom events in just a few lines of code, without needing complex WebSocket setups.


# QUIC / HTTP/3

Wade QUIC is a pure Erlang implementation of QUIC (RFC 9000) and HTTP/3 (RFC 9114).

## Features

- QUIC transport (UDP, packet parsing, connection state machine)
- TLS 1.3 handshake and key derivation
- Streams (bidirectional and unidirectional)
- Flow control per-connection and per-stream
- HTTP/3 frame handling (HEADERS, DATA, SETTINGS)
- QPACK static table support
- Unified API with Wade routes (same as HTTP/1.1)

## Usage

### Start QUIC server

```erlang
wade:start_quic(8443, #{
    certfile => "cert.pem",
    keyfile => "key.pem"
}).

wade:route(get, "/hello", fun(Req) ->
    wade:reply(Req, 200, <<"Hello HTTP/3!">>)
end, []).
```

### Dual mode (HTTP/1.1 + HTTP/3)

```erlang
{ok, #{http := HTTPPid, quic := QUICPid}} =
    wade:start_quic(8080, 8443, #{
        certfile => "cert.pem",
        keyfile => "key.pem"
    }).
```

Routes apply to both protocols.

## Testing

```bash
# Generate test certificate
openssl req -x509 -newkey rsa:2048     -keyout priv/key.pem -out priv/cert.pem     -days 365 -nodes -subj '/CN=localhost'

# Test with curl (HTTP/3)
curl --http3-only -k https://localhost:8443/hello
```

---

## Install

Add to `rebar.config`:

```erlang
{deps, [wade]}.
```