What this is about
The history is the list of all revisions of an object, newest first. You read it with an endpoint of its own, which only exists for audited models and only if it is listed in the model’s endpoint list.
Request and response
POST /api/rest/order/7e1…/history
{
"response": ["orderNr", "price"],
"parameter": { "page": 0, "limit": 2 }
}{ "data": [
{ "revision": { "id": "7e1…", "orderNr": "A-1000", "price": 99.0 },
"revisionMeta": { "ref": 51, "ts": 1790000300000, "username": "Ben Beispiel", … },
"revisionType": "MOD" },
{ "revision": { "id": "7e1…", "orderNr": "A-1000", "price": 120.5 },
"revisionMeta": { "ref": 42, "ts": 1790000200000, "username": "Anna Muster", … },
"revisionType": "MOD" }
],
"meta": { "error": false, "totalCount": 0, "currentPage": 0, … } }Every entry in data is a revision with three parts: revision (the state of the object), revisionMeta (who, when, from where) and revisionType (ADD, MOD, DEL). The fields of revisionMeta are explained in What a revision records.
What the request controls
| Part of the request | Effect in the history |
|---|---|
response | Required. Which simple fields each revision shows. + and * return all simple fields you may read. A field with a read role of its own is missing from every revision without this role, see Protected values. |
references and lists in response | are not expanded. The history only shows the fields of the object itself. |
parameter.page, parameter.limit | Paging. Without limit all revisions come at once. |
filters and sorting in parameter | are not evaluated. The order is always: newest revision first. |
+ and * do not bring the system fields _createdOn and _updatedOn in the history. You read the time of a revision from revisionMeta.ts. See Audit is not the same as system fields.
The checks
-
CDMSEndpointIs the model audited, and is the history endpoint in its endpoint list?↳ no The endpoint does not exist
-
CDMSRead roleDoes the person have the read role of the model?↳ no 403
-
CDMSHistory roleDoes the person have the history role of the model?↳ no 403
-
CDMSVisibilityWould the person have been allowed to read the object – owner filter and attribute filters?↳ no 404
- The revisions for the
idare returned, newest first
Both roles are defined in the model. Their names are explained in Model roles. In strict mode the error is missing-permission|<role>, without strict mode missing-read-role or missing-history-role. See Strict mode.
The roles say whether someone may read histories of this model – not which ones. That is decided by the same row filters as reading and searching: the owner filter and the attribute filters. Whoever cannot read an object does not get its history either.
For a deleted object there is no row left to check this against. CDMS uses the last revision before the deletion instead: it still carries the owner and the attribute values, and the filters are applied to it. The DEL revision is of no use for this, its fields are empty.
If a model has neither an owner nor an attribute filter, there is nothing to check – there the two roles decide on their own.
The variants
When: POST /{base}/{id}/history for an existing object
All revisions of the object, newest first. The first one is an ADD, followed by MOD revisions, including those of a rollback.
When: POST /{base}/history, without id in the path
-
1Client→CDMSsends
POST /api/rest/tenant/preferences/historywithresponse -
2CDMSlooks for the one object that belongs to the person or the tenant
-
3CDMS→Clientno object → 404
data-not-found -
4CDMS→Clientobject exists → checks the roles and returns its history like for a normal modelResult: See Singletons: exactly one object.
When: POST /{base}/{id}/history with the id of a deleted object
The history stays readable – for those who were allowed to read the object. CDMS decides that on the last revision before the deletion, because the row itself is gone. The newest revision is a DEL. It states person and time of the deletion, its fields are empty except the id. You find the last content in the revision before it. This does not work for a singleton: without an object CDMS finds no id and answers with 404.
Result: See What remains after a delete.
When: The person has the read role, but not the history role.
403. Nothing is returned, not even partially. The same applies without the read role.
Decision table
| Endpoint exists? | Read role? | History role? | Visible? | Revisions for the id? | Response |
|---|---|---|---|---|---|
| no | – | – | – | – | The endpoint does not exist. Audit the model and list the endpoint. |
| yes | no | – | – | – | 403 |
| yes | yes | no | – | – | 403 |
| yes | yes | yes | no | – | 404 missing-object |
| yes | yes | yes | no filter | no | 200, data is an empty list. On a model without a filter, an unknown id does not result in 404. |
| yes | yes | yes | yes | yes | 200 with the revisions, newest first |
On a model with a filter, an unknown id cannot be told apart from a hidden one: both result in 404. Otherwise the difference between the answers would tell a caller which foreign ids exist.
Paging
With page and limit you fetch the history in pages, just like a search. page starts at 0. If you leave out limit, all revisions come at once.
Unlike a search, the history does not fill meta: totalCount, currentPage and currentLimit are always 0. So you do not learn the total in advance. Keep paging until a page has fewer entries than limit.
-
1Client→CDMS
page: 0, limit: 20→ 20 entries -
2Client→CDMS
page: 1, limit: 20→ 20 entries -
3Client→CDMS
page: 2, limit: 20→ 7 entriesResult: Fewer than 20, so this is the last page. 47 revisions in total.
Pitfalls
What comes next
- Restoring a state: Rolling back to an old state
- The response in detail: The response format
- How the endpoints are created: Which endpoints a model has