Data authority endpoint use
Using the Data Authority Endpoint (REST API)¶
This document provides a guide on how to interact with a Data Authority endpoint from a REST API perspective. Data Authority endpoints offer a standardized way to manage bitemporal entities, including CRUD operations and advanced querying capabilities.
Let’s assume we have a Data Authority endpoint for an entity named MyResource deployed under the base path /v1/my-app/myresource.
Common Headers¶
For most requests, you’ll need to include:
Authorization: Bearer token for authentication.- Example:
Authorization: Bearer your_api_key_or_jwt_token
- Example:
Content-Type: For POST and PUT requests, typicallyapplication/json.- Example:
Content-Type: application/json
- Example:
Accept: To specify the desired response format, typicallyapplication/json.- Example:
Accept: application/json
- Example:
X-Tenant-ID(or similar): Often required for multi-tenant systems, usually a UUID. The exact header name might vary.- Example:
X-Tenant-ID: 123e4567-e89b-12d3-a456-426614174000
- Example:
Standard Error Responses¶
Data Authority endpoints use standard HTTP status codes for errors:
400 Bad Request: Invalid request payload, malformed JSON, missing required parameters.401 Unauthorized: Missing or invalid authentication token.403 Forbidden: Authenticated user does not have permission to perform the action.404 Not Found: The requested resource or entity ID does not exist.409 Conflict: The request could not be processed because of a conflict in the current state of the resource, such as an edit conflict (e.g. trying to update an older version).500 Internal Server Error: An unexpected error occurred on the server.
Error responses typically include a JSON body with more details:
{
"error": "Short error code or type",
"message": "Detailed error message",
"requestId": "unique-request-id-for-logging"
}
CRUD Operations¶
These are the basic operations for creating, reading, updating, and deleting individual entities.
1. Create Entity¶
- Endpoint:
POST /v1/my-app/myresource - Description: Creates a new
MyResourceentity. - Request Body: JSON object representing the entity’s payload and any required creation metadata. The exact structure depends on the
MyResourceInputPayloadand howretrieveMetadatais configured for the endpoint. - Query Parameters:
effectiveAsOf(Optional, Long): Unix timestamp (milliseconds) for when this version of the entity becomes effective. Defaults to the current time if not provided.
- Successful Response (200 OK or 201 Created): JSON object representing the
EntityRecordof the newly created entity.
Example Request:
// POST /v1/my-app/myresource?effectiveAsOf=1678886400000
// Headers: Authorization, Content-Type, X-Tenant-ID
{
"name": "New Resource Name",
"description": "Optional description for the new resource.",
"customField": "Some value"
}
Example Response (EntityRecord<MyResourcePayload, MyResourceMetadata>):
{
"id": "generated-entity-uuid-1",
"asOf": {
"effective": 1678886400000,
"recorded": 1678886405123 // Server-generated recorded time
},
"payload": {
"id": "generated-entity-uuid-1", // Same as outer id
"name": "New Resource Name",
"description": "Optional description for the new resource.",
"customField": "Some value"
},
"metadata": {
"tenantId": "123e4567-e89b-12d3-a456-426614174000",
"version": 1
},
"previousRecordId": null,
"retired": false
}
2. Read Entity¶
- Endpoint:
GET /v1/my-app/myresource/{id} - Description: Retrieves a specific
MyResourceentity by its ID. - Path Parameter:
{id}: The unique identifier of the entity.
- Query Parameters:
effectiveAsOf(Optional, Long): Unix timestamp (milliseconds). Retrieves the version of the entity effective at this time. Defaults to the current time.recordedAsOf(Optional, Long): Unix timestamp (milliseconds). Retrieves the version of the entity as it was recorded at this time (for historical/audit views). Defaults to the current time.
- Successful Response (200 OK): JSON object representing the
EntityRecord.
Example Request:
GET /v1/my-app/myresource/generated-entity-uuid-1?effectiveAsOf=1678887000000&recordedAsOf=1678887000000
Headers: Authorization, Accept, X-Tenant-ID
Example Response (same structure as create response):
{
"id": "generated-entity-uuid-1",
"asOf": {
"effective": 1678886400000, // Effective time of the record found
"recorded": 1678886405123
},
"payload": {
"id": "generated-entity-uuid-1",
"name": "New Resource Name",
"description": "Optional description for the new resource.",
"customField": "Some value"
},
"metadata": {
"tenantId": "123e4567-e89b-12d3-a456-426614174000",
"version": 1
},
// ...
}
3. Update Entity¶
- Endpoint:
PUT /v1/my-app/myresource/{id} - Description: Updates an existing
MyResourceentity. - Path Parameter:
{id}: The unique identifier of the entity to update.
- Request Body: JSON object with the fields to be updated.
- Query Parameters:
effectiveAsOf(Optional, Long): Unix timestamp for when this update becomes effective.
- Successful Response (200 OK): JSON object representing the
EntityRecordof the updated entity (new version).
Example Request:
// PUT /v1/my-app/myresource/generated-entity-uuid-1?effectiveAsOf=1678887200000
// Headers: Authorization, Content-Type, X-Tenant-ID
{
"description": "Updated description for the resource."
// Only fields to be changed/updated are typically needed, but depends on EP.ip2Payload logic
}
Example Response (note the incremented version and new asOf times):
{
"id": "new-record-uuid-for-update", // A new record ID is generated for the update
"asOf": {
"effective": 1678887200000,
"recorded": 1678887205456
},
"payload": {
"id": "generated-entity-uuid-1", // Entity ID remains the same
"name": "New Resource Name", // Unchanged field from previous version
"description": "Updated description for the resource.", // Updated field
"customField": "Some value"
},
"metadata": {
"tenantId": "123e4567-e89b-12d3-a456-426614174000",
"version": 2 // Version typically increments
},
"previousRecordId": "old-record-uuid", // Points to the previous version's record ID
"retired": false
}
4. Delete Entity¶
- Endpoint:
DELETE /v1/my-app/myresource/{id} - Description: Logically deletes an entity (marks it as retired). Data is not physically removed to maintain history.
- Path Parameter:
{id}: The unique identifier of the entity to delete.
- Query Parameters:
effectiveAsOf(Optional, Long): Unix timestamp for when this deletion becomes effective.
- Successful Response (200 OK): JSON object representing the
EntityRecordof the “deleted” (retired) entity.
Example Request:
DELETE /v1/my-app/myresource/generated-entity-uuid-1?effectiveAsOf=1678887500000
Headers: Authorization, X-Tenant-ID
Example Response (note retired: true):
{
"id": "new-record-uuid-for-delete",
"asOf": {
"effective": 1678887500000,
"recorded": 1678887505888
},
"payload": { // Payload is often preserved
"id": "generated-entity-uuid-1",
"name": "New Resource Name",
"description": "Updated description for the resource.",
"customField": "Some value"
},
"metadata": {
"tenantId": "123e4567-e89b-12d3-a456-426614174000",
"version": 3 // Version typically increments
},
"previousRecordId": "record-uuid-before-delete",
"retired": true // Entity is now marked as retired
}
Query Operations¶
The Data Authority provides powerful querying capabilities to list and filter entities.
1. Initiate a Query / List Entities¶
- Endpoint:
POST /v1/my-app/myresource/query - Description: Lists entities based on specified filters, sorting, and pagination. The query is performed against the state of data as of the specified
effectiveAsOfandrecordedAsOftimes. - Query Parameters (Optional):
effectiveAsOf(Long): Unix timestamp in milliseconds. Filters entities based on their state effective at this time. Defaults to the current system timestamp if omitted.recordedAsOf(Long): Unix timestamp in milliseconds. Filters entities based on their state as recorded at this time (useful for historical/audit views). Defaults to the current system timestamp if omitted.
-
Request Body: A JSON
Queryobject.Structure of the
Queryobject (seecards.arda.common.lib.lang.query.Query):{ "filter": { // Optional: A Filter object (e.g., {"EQ": {"locator": "status", "value": "ACTIVE"}}) // See Filter data classes (True, False, Not, And, Or, Eq, Neq, Gt, Gte, Lt, Lte, In, IsNull, Like, Contains, StartsWith, EndsWith) "EQ": { "locator": "status", "value": "ACTIVE" } }, "sort": [ // Optional: List of Sort objects { "field": "name", "direction": "ASC" }, // ASC or DESC { "field": "createdAt", "direction": "DESC" } ], "paginate": { // Optional: Pagination object "index": 0, // 0-based page index "size": 20 // Number of results per page // thisPage, nextPage, previousPage are typically not sent in the initial query request body; // they are part of the response and used for subsequent page navigation. } }filter: AFilterobject defining the criteria. Supported types include logical operators (And,Or,Not) and comparison operators (Eq,Neq,Gt,Gte,Lt,Lte,In,IsNull,Like,Contains,StartsWith,EndsWith). Thelocatorrefers to a field inMyResourcePayloadorMyResourceMetadata.sort: An array ofSortobjects, each specifying afieldanddirection(ASCorDESC).paginate: APaginationobject specifying theindex(0-based) of the page and thesize(number of items per page).
- Successful Response (200 OK): A
PageResultobject.
-
Example Request:
// POST /v1/my-app/myresource/query?effectiveAsOf=1678886400000&recordedAsOf=1678887000000 // Headers: Authorization, Content-Type, X-Tenant-ID { "filter": { "AND": [ { "EQ": { "locator": "customField", "value": "Some value" } }, { "EQ": { "locator": "status", "value": "ACTIVE" } } ] }, "sort": [ { "field": "name", "direction": "ASC" } ], "paginate": { "index": 0, "size": 10 } }
-
Example Response (
PageResult<MyResourcePayload, MyResourceMetadata>):{ "thisPage": "opaquePageTokenForPage1", // Token representing the current page's query state "nextPage": "opaquePageTokenForPage2", // Token to fetch the next page, or empty/null if no next page "previousPage": null, // Token to fetch the previous page, or null if this is the first page "results": [ { "id": "entity-uuid-A", "asOf": { "effective": 1678886400000, "recorded": 1678886405123 }, "payload": { "id": "entity-uuid-A", "name": "Alpha Resource", "customField": "Some value", "status": "ACTIVE" }, "metadata": { "tenantId": "123e4567-e89b-12d3-a456-426614174000", "version": 1 } // ... other fields ... }, { "id": "entity-uuid-B", "asOf": { "effective": 1678800000000, "recorded": 1678800005123 }, "payload": { "id": "entity-uuid-B", "name": "Bravo Resource", "customField": "Some value", "status": "ACTIVE" }, "metadata": { "tenantId": "123e4567-e89b-12d3-a456-426614174000", "version": 2 } // ... other fields ... } // ... up to 'pageSize' results ] }
2. Navigate to Other Pages¶
- Endpoint:
GET /v1/my-app/myresource/query/{page} - Description: Retrieves a specific page of query results using a page token obtained from a previous
PageResult. The query is performed against the state of data as of the specifiedeffectiveAsOfandrecordedAsOftimes. - Path Parameter:
{page}: The opaque page token (e.g., the value fromnextPageorpreviousPageof aPageResult). This token typically encodes the necessary query and pagination state.
- Query Parameters (Optional):
effectiveAsOf(Long): Unix timestamp in milliseconds. Filters entities based on their state effective at this time. Defaults to the current system timestamp if omitted.recordedAsOf(Long): Unix timestamp in milliseconds. Filters entities based on their state as recorded at this time. Defaults to the current system timestamp if omitted.
- Successful Response (200 OK): A
PageResultobject for the requested page.
-
Example Request (using
nextPagetoken from previous example):
-
Example Response (another
PageResult):
-
Using
PageResultfor Navigation:thisPage: A token representing the state of the query for the current page. Could be used to “refresh” the current view if needed, though typically the client would hold onto the results.nextPage: If not null or empty, use this token with the GET/query/{page}endpoint to fetch the next set of results.previousPage: If not null, use this token to fetch the previous set of results.results: An array ofEntityRecordobjects for the current page.