Files
poimen-memory/tasks/M3.5.1-http-server.md

83 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M3.5.1 — HTTP server + router, Kong auth hook, metrics
| Field | Value |
|---|---|
| Phase | M3.5 — Distributed API Layer |
| Size | M — 13 days |
| Status | ✅ Done |
| Flags | — |
| Spec | inlined below |
| Blocks | M3.5.2, M3.5.3, M3.5.5, M3.5.6 |
## Goal
HTTP facade for homelab gateway. Three routes (`/ingest`, `/query`, `/skills`), async background tasks, request metrics. Auth hook validates Kong `apikey:` header. Stateless — no business logic here, just request demultiplexing.
## Architecture
```
Kong (api.riotpiao.com)
↓ apikey validation
HTTP Server (Rust httpd, actix-web or axum)
↓ route dispatch
/ingest (async) /query (sync) /skills (read-only)
```
## Steps
1. `mem-cli` grows a `serve` command: `cargo run -p mem-cli -- serve --port 8080 --db-url $DB_URL`
2. Choose framework: **actix-web** (stable, high perf) or **axum** (newer, composable). Decision required — pick one and document the choice.
3. Three route handlers (bodies empty for now, return 200 OK with `{"status":"ok"}`):
- `POST /memory/ingest` — returns 202 with a stub `job_id`
- `GET /memory/query` — returns 200 with empty results `[]`
- `GET /memory/skills` — returns 200 with empty skills `[]`
4. Request logger middleware — every request logs method, path, status, latency in one line (not pretty-printed).
5. Metrics middleware — track latency histogram per route (p50/p95/p99 in microseconds), request count, error count.
6. Kong auth hook:
- Extract `apikey:` header (case-insensitive header name, exact value match against stored key)
- If missing or unrecognized → 401 with `{"error":"unauthorized","reason":"missing apikey header"}`
- Pass apikey to request context so handlers can log which key made the request
7. CORS: disable (agents are internal cluster; no browser requests expected)
8. Health check: `GET /health` returns 200 `{"status":"ok","uptime_seconds":N}`
## Acceptance
- Server starts without errors
- Health check responds
- Three routes defined and callable
- Auth middleware rejects missing apikey (401)
- Request logger emits latency per request
- Metrics collected (observable via endpoint or in-process)
## Verify
**Harness:** Integration tests against a live server instance started in each test.
**Integration test**`tests/it_http_server.rs`:
1. `a1_server_starts``HttpServer::new(...).run()` succeeds, port is open.
2. `a2_health_check` — GET /health returns 200 and body contains `"ok"`.
3. `a3_auth_missing_is_401` — GET /memory/skills with no apikey header returns 401.
4. `a4_auth_wrong_is_401` — GET /memory/skills with `apikey: wrong` returns 401.
5. `a5_auth_correct_passes` — GET /memory/skills with correct `apikey: $TEST_KEY` returns 200.
6. `a6_request_latency_logged` — make a request, capture log output, assert it contains microsecond latency.
7. `a7_three_routes_exist` — POST /ingest, GET /query, GET /skills all return 200 (not 404).
8. `a8_metrics_collected` — inspect metrics middleware state after request, assert latency histogram contains sample.
**Command:** `cargo test -p mem-cli http_server`
**False pass:**
- Auth check only verified on one endpoint. Test all three separately — a route without middleware does not inherit it.
- Metrics collected but never asserted. A metrics middleware that silently fails still compiles.
- Latency logged in milliseconds. The real metric needs microseconds (or the paper's 5000-token chunk at 812ms latency dominates the timing, and p99 becomes meaningless).
## Traps
- Actix-web's `.service()` does not inherit middleware registered outside a scope; scope middleware applies only to routes inside that scope.
- Header name case matters for Kong's key-auth; `apikey:` is lowercase.
- `tokio::runtime::Runtime::new()` in tests blocks on network if used naively — use test utilities from `actix-web` or `axum` that spawn the server in a background thread.
- Metrics registered at startup are easy to forget to increment. Middleware must actually call the metrics update, not just define it.
---
Background: [DESIGN.md § Distributed API Layer](../DESIGN.md#distributed-api-layer-homelab-frontend)