Model API
This API provides comprehensive RESTful access to every element within the data model. Each element, from a high-level program down to a single field, is exposed via a unique URL. You can retrieve, create, update, and delete model elements using standard HTTP methods.
Key Concepts
Before using the API, it's important to understand these core concepts:
- Dynamic URL Structure: The API is resource-oriented. The URL for each element is dynamically generated based on its position within the model hierarchy.
- Element Data Objects: When you
GET
an element, you receive a full Data Object with all its properties and metadata. - Element Reference Objects: To keep payloads efficient, elements referenced within a Data Object's properties are represented as lightweight Reference Objects, which contain an ID, label, type, and a link to retrieve the full Data Object.
- Cascading Changes: A single modification (
PATCH
,POST
,DELETE
) can result in multiple changes. For example, deleting an element will also update any other elements that referenced it. These are all reported in the response.
1. URL Structure
Element URLs follow a consistent but dynamic pattern, reflecting the model's hierarchy.
Pattern: /{base_url}/{element_type}/{element_key}
Example Breakdown:
For the URL /model/elements/JeeApplication/bookApp/1.0.0/modules/elements/JeeComponent/books/elements/DataElement/books%3A%3ABook
- Base URL:
/model/elements/JeeApplication/bookApp/1.0.0/modules/elements/JeeComponent/books
- Element Type:
elements/DataElement
- Element Key:
books%3A%3ABook
(URL-encoded key forbooks::Book
)
The base URL itself is nested depending on the element's location:
Element Context | Base URL Pattern | Example |
---|---|---|
Program Level | /model/{program_type}/{program_key} | /model/elements/JeeApplication/bookApp/1.0.0 |
Module Level | /{program_base_url}/modules/{module_type}/{module_key} | .../modules/elements/JeeComponent/books |
2. Data Structures
The API uses two primary JSON objects to represent elements.
Element Data Object
This is the full representation of an element, returned by GET
requests.
Field | Type | Description |
---|---|---|
id | String | The unique, machine-readable key for the element. |
label | String | A non-unique, human-readable label for display purposes. |
type | String | The element's specific type. |
format | String | default or the name of a profile used for representation. |
properties | Object | A key-value map of the element's attributes and child elements. |
options | Object | A key-value map of the element's options. |
meta | Object | Additional metadata about the element, such as its origin. |
links | Object | Links for actions on this element (self , delete , etc.). |
Click to see a full Element Data Object example
{
"id": "books::Book",
"label": "Book",
"type": "elements::DataElement",
"format": "default",
"properties": {
"component": {
"id": "books",
"label": "books",
"type": "elements::Component",
"format": "reference",
"links": {
"self": "..."
}
},
"name": "Book",
"fields": [
{
"id": "books::Book::title",
"label": "title",
"type": "elements::Field",
"format": "reference",
"links": {
"self": "...",
"delete": "..."
}
}
]
},
"options": {
"includeJaxrsConnector": {
"value": "/achievements/{achievementId}",
"links": {
"type": "/data/elements%3A%3AOptionType/includeJaxrsConnector"
}
}
},
"meta": {
"origin": "file"
},
"links": {
"self": "...",
"delete": "..."
}
}
Element Reference Object
This is a lightweight pointer to another element, used inside an element's properties
.
Field | Type | Description |
---|---|---|
id | String | The unique key of the referenced element. |
label | String | The label of the referenced element. |
type | String | The type of the referenced element. |
format | String | Always reference . |
links | Object | Contains a self link to retrieve the element's full Data Object. |
Example Reference Object:
{
"id": "books",
"label": "books",
"type": "elements::Component",
"format": "reference",
"links": {
"self": "/model/elements/JeeApplication/bookApp/1.0.0/modules/elements/JeeComponent/books/elements/Component/books"
}
}
3. API Endpoints
All URLs below use the dynamic {element_url}
structure described above. All endpoints can optionally accept a ?profile
query parameter to control the data representation.
Retrieve Data (GET
)
GET /{element_url}
Retrieves the full Data Object for a single element.
- Example:
curl http://localhost:8080/model/elements/DataElement/books%3A%3ABook
- Success Response: Returns a
200 OK
with the Element Data Object in thedata
field.
GET /{element_url}/properties/{property}
Retrieves the value of a single property of an element.
- Example:
curl http://localhost:8080/model/elements/DataElement/books%3A%3ABook/properties/name
- Success Response: Returns
200 OK
. Thedata
field contains the raw value of the property (e.g., a string, number, or an array of Reference Objects).
GET /{element_url}/linked-elements
Retrieves a list of all elements that reference the target element.
- Success Response: Returns
200 OK
. Thedata
field contains a list of Element Reference Objects.
Modify Data (PATCH
, POST
, DELETE
)
Responses to modification requests return a 200 OK
(or 201 Created
for POST
) and include a changes
array detailing all resulting side-effects.
PATCH /{element_url}
Updates one or more properties of an element. The request body must contain a data
object with the properties to be changed.
Click to see an example of a PATCH request body.
{
"data": {
"properties": {
"packageName": "org.normalizedsystems.books",
"type": {
"id": "Registry",
"type": "elements::DataElementType"
},
"dataStates": [
{
"type": "elements::DataState",
"properties": {
"name": "Initial"
}
},
{
"type": "elements::DataState",
"properties": {
"name": "Indexed"
}
}
]
}
}
}
When updating composition properties, like the dataStates
property in the example, the value is overwritten.
This means that elements that are omitted will be removed.
The response may contain the following changes:
UPDATED
(likely), when the element is updated.ADDED
, when updating a composition property and one of the nested elements did not exist before.REMOVED
, when updating a composition property and one of the nested elements was omitted.IDENTITY_CHANGED
, when updating a property that is used in the element key.
In case of a IDENTITY_CHANGED
change, the response will likely also include changes for elements that were linked to the target element.
DELETE /{element_url}
Removes an element from the model.
- Example:
curl -X DELETE http://localhost:8080/model/elements/DataElement/books%3A%3ABook
The response may contain the following changes:
REMOVED
(always) for the removed element.UPDATED
for each element that had a reference to the target element and is now updated.
POST /{element_url}/properties/{property}
Adds a new element to a collection property. This only works on properties that are collections.
- Request Body: The request body should contain the Data Object of the new element to add to the collection.
- Success Response:
201 Created
.
Click to see an example of a POST request body.
{
"data": {
"type": "elements::DataElement",
"properties": {
"name": "BookComment",
"packageName": "org.normalizedsystems.books",
"type": {
"id": "Registry",
"type": "elements::DataElementType"
},
"fields": [
{
"type": "elements::Field",
"properties": {
"name": "message",
"valueField": {
"type": "elements::ValueField",
"properties": {
"type": {
"id": "MarkupString",
"type": "elements::ValueType"
}
}
}
}
}
]
}
}
}
Changes in the response may contain:
UPDATED
for the updated collection property.ADDED
for the new element and every new nested element.
4. Responses
Modification Response (changes
object)
The changes
array in PATCH
, POST
, and DELETE
responses details every change that occurred.
Field | Type | Description |
---|---|---|
change | String | The type of change: ADDED , REMOVED , UPDATED , or IDENTITY_CHANGED . |
resource | Reference | A Reference Object for the element that was changed. |
newIdentity | Reference | (For IDENTITY_CHANGED ) A Reference Object with the new element identity. |
updatedProperties | Array<String> | (For UPDATED ) A list of property names that were changed. |
Error Response
If a request fails, the server responds with an appropriate HTTP status code and an errors
array in the body.
Example Error Body:
{
"errors": [
{
"id": "3d2b47f3-0b28-4c2c-8df9-5690190fa75e",
"title": "Not found: books::Boek",
"detail": "Resource not found with id=books::Boek, type=elements::DataElement"
}
]
}
Common Status Codes:
Code | Status Text | Reason |
---|---|---|
400 | Bad Request | The request body contains invalid or malformed data. |
404 | Not Found | The resource at the specified URL does not exist. |
500 | Server Error | The server encountered an unexpected error during processing. |