API¶
EDRI’s API layer is a set of adapters that translate external client communication (HTTP/REST, WebSocket, HTML) into internal Event handling.
The API layer is optional. EDRI can run entirely with internal producers and consumers (Managers, Workers, connectors) without exposing any external interface.
The API layer is responsible for:
constructing API Events from incoming requests/messages
running API middleware
emitting the resulting events into the Router
translating responses back to the client
The API layer does not route events. Routing is handled exclusively by the Router.
API Types¶
EDRI supports multiple API types (ApiType):
REST – HTTP request/response
WS – WebSocket (bidirectional)
HTML – server-rendered templates + static assets
API types can be excluded per endpoint using exclude={...}.
REST API¶
REST endpoints use:
@api(url="/items/{item_id}", method=HTTPMethod.GET)
class ItemGet(Event):
item_id: int
response: ItemGetResponse
Key rules:
URL is decoded before matching.
Matching happens per path segment.
URL placeholders must exist as fields on the Event.
Type validation happens after matching using event field types and
inject(...).
REST is suited for request/response workflows and file upload/download.
WebSocket API¶
WebSocket endpoints use (resource defaults to kebab-case-class-name if not provided):
@api(resource="module-list")
class ModuleList(Event):
response: ModuleListResponse
Incoming WS messages contain a command key which maps to the resource.
WebSocket supports:
request/response style interactions
event subscription (
register/unregister)server → client push events
See WebSocket for full details.
HTML API¶
HTML endpoints require template and method (url defaults to /{snake_case_class_name} if not provided):
@api(url="/dashboard", template="dashboard.j2", method=HTTPMethod.GET)
class Dashboard(Event):
response: DashboardResponse
Behavior:
If no event route matches the URL, EDRI attempts to serve a static file from
EDRI_ASSETS_PATH(see Static files).If neither matches, 404 is returned.
See HTML API for full details.
Content Negotiation (Accept header)¶
Response format depends on the Accept header.
To explicitly request JSON, send:
Accept: application/json
If the event defines no HTML template, EDRI also returns JSON when the client tolerates it — the Accept list contains */* (a browser's default list qualifies) or there is no header. Only a request that demands HTML (Accept: text/html with no */*) against a template-less event fails with 406 Not Acceptable. See Content Negotiation for the full selection rules.
Middleware¶
Middleware runs on API Events.
process_request(...)runs on incoming events.process_response(...)runs on outgoing events.
Execution order:
Request: in declared order
Response: in reverse declared order (onion model)
Middleware runs after the event is created, so API metadata is already attached to the event.
Response Directives¶
Transport-specific behavior is expressed via ResponseDirective objects.
Examples:
HTTP headers
cookies
redirects
status overrides
Directives may be added by:
business logic
middleware
API helpers
Downloads¶
File download behavior (including resumable downloads via HTTP Range, and streamed downloads via SharedMemoryPipe) is documented separately:
Timeouts¶
EDRI applies an API response timeout to prevent requests from hanging indefinitely.
EDRI_API_RESPONSE_TIMEOUTtimeout (seconds) for waiting on an API response
If the timeout is reached, the API returns a timeout error response (exact directive/status depends on API type and application conventions).
Custom JSON encoder¶
EDRI supports a custom JSON encoder for REST and WebSocket payloads.
Provide it when starting the API:
edri.start_api(middlewares=[...], json_encoder=MyJSONEncoder)
See JSON encoding for encoder design, context usage, and advanced examples.
Summary¶
The API layer provides transport adapters for EDRI’s event-driven core.
It converts external communication into Events and converts Responses back to clients, while remaining independent of routing and core business logic.