# Aether API V3 Frontend Integration Guide (Svelte/TypeScript) This guide explains how to update or create frontend functions to interact with the new **Aether API V3 CRUD** endpoints. V3 introduces a nested URL structure, a powerful POST-based search, and improved performance. --- ## 1. Key Differences (V2 vs V3) | Feature | CRUD V2 (Legacy) | CRUD V3 (Modern) | | --- | --- | --- | | **Base Prefix** | `/v2/crud` | `/v3/crud` | | **List Suffix** | Uses `/list` (e.g., `/v2/crud/journal/list`) | **No suffix** (e.g., `/v3/crud/journal/`) | | **Nested Path** | Not supported in URL path | **Supported** (e.g., `/v3/crud/journal/{id}/journal_entry/`) | | **Order By** | Passed in **Headers** (`order_by_li`) | Passed as **Query Parameter** (`order_by_li`) | | **Complex Search**| Limited to GET `jp` (~2KB limit) | **POST `/search`** (Unlimited size) | | **Latency Simulation**| Not standardized | `X-Delay-ms` (Header) or `delay_ms` (Query) | --- ## 2. Implementing V3 CRUD Functions ### A. List Top-Level Objects (GET) Use this for simple lists or filtering by a parent via query parameters. ```ts export async function get_ae_obj_li_v3({ api_cfg, obj_type, for_obj_type, for_obj_id, enabled = 'enabled', hidden = 'not_hidden', limit = 100, offset = 0, order_by_li = null, // e.g., {"created_on": "DESC"} delay_ms = 0 }) { // 1. Build V3 Endpoint (Note: No /list suffix) const endpoint = `/v3/crud/${obj_type}/`; // 2. Build Query Params const params: any = { enabled, hidden, limit, offset }; if (for_obj_type) params.for_obj_type = for_obj_type; if (for_obj_id) params.for_obj_id = for_obj_id; if (order_by_li) params.order_by_li = JSON.stringify(order_by_li); if (delay_ms) params.delay_ms = delay_ms; return await get_object({ api_cfg, endpoint, params }); } ``` ### B. Access Nested Objects (GET) V3 allows you to enforce parent-child relationships directly in the URL. ```ts // Example: Get all entries for a specific journal // GET /v3/crud/journal/{journal_id}/journal_entry/ export async function get_nested_obj_li_v3({ api_cfg, parent_type, parent_id, child_type, limit = 100 }) { const endpoint = `/v3/crud/${parent_type}/${parent_id}/${child_type}/`; return await get_object({ api_cfg, endpoint, params: { limit } }); } ``` ### C. Advanced Search (POST) Use the new `/search` endpoint for complex logic (AND/OR, LIKE, IN) that would exceed URL length limits. ```ts export async function search_ae_obj_v3({ api_cfg, obj_type, search_query, // Complex SearchQuery object order_by_li = null }) { const endpoint = `/v3/crud/${obj_type}/search`; const params: any = {}; if (order_by_li) params.order_by_li = JSON.stringify(order_by_li); // Note: search_query is sent in the BODY via POST return await post_object({ api_cfg, endpoint, params, data: search_query }); } /** * Example search_query usage: * { * "and": [ * { "field": "enable", "op": "eq", "value": true }, * { * "or": [ * { "field": "name", "op": "like", "value": "%Meeting%" }, * { "field": "priority", "op": "gt", "value": 5 } * ] * } * ] * } */ ``` --- ## 3. Best Practices for V3 1. **Stop using Headers for Sorting**: In V2, we used `headers['order_by_li']`. In V3, always use `params['order_by_li']`. 2. **Prefer `/search` for Filters**: If your query involves more than a simple `for_obj_id`, use the `POST .../search` endpoint. It is safer, more readable, and bypasses the 2083-character URL limit. 3. **Non-Blocking UI**: Use the `delay_ms` parameter during development to test how your Svelte components handle loading states and skeleton screens. 4. **Singular Nouns**: Always use singular names for `obj_type` (e.g., `journal`, not `journals`), following the backend's `obj_type_kv_li` registry. --- ## 4. Special Case: Account Context V3 strictly enforces account context. Ensure your `api_cfg` logic correctly sets the `X-Account-ID` header. * If a request doesn't need an account (e.g., public site data), set the `X-No-Account-ID: bypass` header. * If using a temporary token, use the `x_no_account_id_token` query parameter.