8.4 KiB
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 |
No suffix (e.g., /v3/crud/journal/) |
| Nested Path | Not supported in URL | Supported (e.g., /v3/crud/journal/{id}/journal_entry/) |
| View Selection | tbl_alt, mdl_alt |
view parameter (e.g., ?view=enriched) |
| Complex Search | Limited to GET jp |
POST /search (Unlimited size + Hybrid params) |
| Full-Text Search | Manual column names | Reserved q property in SearchQuery |
2. Implementing V3 CRUD Functions
A. List & Single Object (GET)
Support for view selection allows fetching richer data models when needed.
// Example: Get enriched journal details
// GET /v3/crud/journal/{id}?view=enriched
export async function get_ae_obj_v3({ api_cfg, obj_type, obj_id, view = 'default' }) {
const endpoint = `/v3/crud/${obj_type}/${obj_id}`;
return await get_object({ api_cfg, endpoint, params: { view } });
}
B. Advanced & Hybrid Search (POST)
The /search endpoint combines the power of complex logical bodies with the simplicity of query parameters.
export async function search_ae_obj_v3({
api_cfg,
obj_type,
search_query, // { q: "search term", and: [...] }
enabled = 'enabled',
view = 'default',
for_obj_type,
for_obj_id
}) {
const endpoint = `/v3/crud/${obj_type}/search`;
// Standard filters can be passed as query params
const params: any = { enabled, view };
if (for_obj_type) params.for_obj_type = for_obj_type;
if (for_obj_id) params.for_obj_id = for_obj_id;
return await post_object({
api_cfg,
endpoint,
params,
data: search_query
});
}
C. Standardized Global Search
Use the q property in your search body for a general keyword search across indexed columns.
// POST /v3/crud/journal/search
{
"q": "Annual Meeting",
"and": [
{ "field": "enable", "op": "eq", "value": true }
]
}
D. Supported Search Operators
The op property in a SearchFilter supports the following values:
| Operator | SQL equivalent | Description |
|---|---|---|
eq |
= |
Equal to |
ne |
!= |
Not equal to |
gt |
> |
Greater than |
gte |
>= |
Greater than or equal to |
lt |
< |
Less than |
lte |
<= |
Less than or equal to |
in |
IN (...) |
Matches any value in a provided list |
is_null |
IS NULL |
Field is null (ignores value) |
is_not_null |
IS NOT NULL |
Field is not null (ignores value) |
like |
LIKE |
Standard SQL LIKE (requires manual % in value) |
contains |
LIKE %val% |
Wraps value in % automatically |
startswith |
LIKE val% |
Appends % to value automatically |
endswith |
LIKE %val |
Prepends % to value automatically |
3. Create, Update, & Delete (POST, PATCH, DELETE)
V3 supports both top-level operations and nested parent/child operations.
A. Create (POST)
When creating objects, V3 strictly validates the incoming JSON against the mdl_in Pydantic model.
// POST /v3/crud/{obj_type}/
// POST /v3/crud/journal/
export async function create_ae_obj_v3({ api_cfg, obj_type, data }) {
const endpoint = `/v3/crud/${obj_type}/`;
return await post_object({ api_cfg, endpoint, data });
}
// POST /v3/crud/{parent_obj_type}/{parent_obj_id}/{child_obj_type}/
// POST /v3/crud/journal/EIAC-40-76-82/journal_entry/
// Note: Parent ID is automatically injected into the child record.
export async function create_nested_obj_v3({ api_cfg, parent_type, parent_id, child_type, data }) {
const endpoint = `/v3/crud/${parent_type}/${parent_id}/${child_type}/`;
return await post_object({ api_cfg, endpoint, data });
}
B. Update (PATCH)
V3 uses PATCH for partial updates. Only the fields provided in the body will be modified in the database.
// PATCH /v3/crud/{obj_type}/{obj_id}
export async function update_ae_obj_v3({ api_cfg, obj_type, obj_id, data }) {
const endpoint = `/v3/crud/${obj_type}/${obj_id}`;
return await patch_object({ api_cfg, endpoint, data });
}
// PATCH /v3/crud/{parent_type}/{parent_id}/{child_type}/{child_id}
// Verification: The backend ensures the child actually belongs to the parent before updating.
export async function update_nested_obj_v3({ api_cfg, parent_type, parent_id, child_type, child_id, data }) {
const endpoint = `/v3/crud/${parent_type}/${parent_id}/${child_type}/${child_id}`;
return await patch_object({ api_cfg, endpoint, data });
}
C. Delete (DELETE)
The DELETE method is used for removal. The backend may implement soft-delete (hide/disable) depending on the configuration.
// DELETE /v3/crud/{obj_type}/{obj_id}
export async function delete_ae_obj_v3({ api_cfg, obj_type, obj_id }) {
const endpoint = `/v3/crud/${obj_type}/${obj_id}`;
return await delete_object({ api_cfg, endpoint });
}
4. Specialized & Context Endpoints
A. Initial Context Resolution (FQDN)
Path: GET /crud/site/domain/{fqdn}?use_alt_table=true&use_alt_base=true
This is a critical public endpoint used by the Svelte frontend during initial load.
- Requirement: Does NOT require
X-Account-IDheader (it resolves it). - Purpose: Returns the
account_idand site configuration associated with the current URL. - Backend: Currently routed via legacy V1/V2
api_crud.pyfor maximum compatibility.
// Example: resolve context from current location
const fqdn = window.location.host;
const endpoint = `/crud/site/domain/${fqdn}`;
const context = await get_object({
api_cfg,
endpoint,
params: { use_alt_table: true, use_alt_base: true }
});
// result includes account_id and account_id_random
B. Schema Discovery
Path: GET /v3/crud/{obj_type}/schema
Used for developer tools or dynamic UI builders to understand the structure of an AE object. Returns:
- Database column names and SQL types.
- Pydantic model field names, aliases, and TypeScript-compatible types.
// GET /v3/crud/account/schema
export async function get_obj_schema_v3({ api_cfg, obj_type }) {
const endpoint = `/v3/crud/${obj_type}/schema`;
return await get_object({ api_cfg, endpoint });
}
5. Advanced Search Logic
A. Standardized Global Search (q)
Use the q property in your search body for a keyword search.
- Wildcard Support: Setting
q: "%"will bypass all text filtering and return all records (respecting only logical filters likeenable). - Fallback: If the table lacks a
default_qry_strcolumn, the API automatically performs aLIKEsearch across all searchable fields.
{
"q": "%",
"and": [{ "field": "enable", "op": "eq", "value": true }]
}
6. Authentication in V3
V3 supports multiple authentication methods. The backend resolves these automatically.
A. Standard Requests (Header)
For most API calls, use the standard Bearer token in the Authorization header.
// Example: Setting the JWT in headers
headers: {
"Authorization": `Bearer ${user_jwt_token}`
}
B. Secure File Downloads (URL Parameter)
Crucial for hosted_file and event_file: To allow browsers to download files without complex header modifications, you can pass the JWT directly in the URL.
// Example: Creating a secure download link
// GET /v3/crud/hosted_file/{id}/?jwt={token}
const downloadUrl = `${BASE_URL}/hosted_file/${fileId}/?jwt=${jwtToken}`;
C. Legacy Fallback (X-Account-ID)
For development and backward compatibility, the X-Account-ID header is still supported but should be phased out in favor of JWT.
5. Best Practices for V3
- Use
viewfor Rich Data: Instead of manually joining data in separate calls, use?view=enrichedor?view=detailif defined in the backend. - Hybrid Search: Use query parameters for simple toggles (enabled/hidden) and the POST body for complex logic.
- Global Search: Always prefer the
qproperty for text search instead of manually targetingdefault_qry_str. - Singular Nouns: Always use singular names for
obj_type(e.g.,journal).