# API EDRI’s API layer is a set of **adapters** that translate external client communication (HTTP/REST, WebSocket, HTML) into internal {doc}`/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: ```python @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): ```python @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 {doc}`/websocket` for full details. --- ## HTML API HTML endpoints require `template` and `method` (`url` defaults to `/{snake_case_class_name}` if not provided): ```python @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 {doc}`/static_files`). * If neither matches, 404 is returned. See {doc}`/html` 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 {doc}`/api_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: * {doc}`/api_download` * {doc}`/shared_memory_pipe` --- ## Timeouts EDRI applies an API response timeout to prevent requests from hanging indefinitely. * `EDRI_API_RESPONSE_TIMEOUT` * timeout (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: ```python edri.start_api(middlewares=[...], json_encoder=MyJSONEncoder) ``` See {doc}`/json_encoder` 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.