CodamAIDocs
Topicdone

Create and read back: STRICT or LENIENT

After a create, CDMS reads the object back for the response. What happens when reading back fails is decided by the CreateReadMode.

Variants
STRICT (default): everything rolled backLENIENT: created, 200 with notice and idcan be overridden per requestsetting of the installationsingletons: always STRICT

What this is about

A create does not just answer “ok”, but with the created object, the way you requested it in response. To do that, CDMS reads the object back after saving it, with your permissions and filters, exactly like a normal read.

This read-back can fail even though the create succeeded. For example:

  • You lack the read role of the model. You may create, but not read.
  • The new object is filtered out by your row filters. For example, you create an order for a company that your attribute filter does not show you.
  • A READ hook throws an error while reading.

What happens then is decided by the CreateReadMode: STRICT or LENIENT.

The two modes

When reading back fails

When: Default. Create and read-back in one transaction.

  1. 1
    CDMS→Database
    creates the object, hooks, flush
  2. 2
    CDMS→Database
    reads it back, in the same transaction
  3. 3
    CDMS
    reading back fails, e.g. read role missing
  4. 4
    CDMS→Client
    error of the read, e.g. 403 missing-permission|order-read; the create is rolled back

Result: There is no new object. The response describes why reading failed.

When: Create and read-back in two transactions.

  1. 1
    CDMS→Database
    creates the object, hooks, flush
  2. 2
    CDMS→Database
    commit: the object is now permanently saved
  3. 3
    CDMS→Database
    reads it back, in a new transaction
  4. 4
    CDMS
    reading back fails
  5. 5
    CDMS→Client
    200 in error form, messageKey CDMS_CREATE_SUCCEEDED_READ_FAILED and the id of the new object

Result: The object exists. You know its id, but you do not get its fields.

If reading back succeeds, both modes behave the same: 200 with the object.

The response with LENIENT

Created, but not read back
Request
POST /api/rest/order/create
{
  "data": { "orderNr": "A-1000", "companyId": "123456" },
  "response": ["id", "orderNr"],
  "createReadMode": "LENIENT"
}
Response 200
{
  "error": "CreateSucceededReadFailedException",
  "messageKey": "CDMS_CREATE_SUCCEEDED_READ_FAILED",
  "code": "200",
  "layer": "system",
  "id": "5a2b…"
}

The response has status 200, but the shape of an error response: no data, instead error, messageKey and id. So for a create, do not check only the status, but also whether data is there. See The response format: data and meta.

Choosing the mode

Which mode applies?
createReadMode in the requestSetting of the installationMode
LENIENT–LENIENT
STRICT–STRICT
missingLENIENTLENIENT
missingSTRICT or not setSTRICT
  • Per request: "createReadMode": "LENIENT" in the body, next to data and response. This applies to POST /create, /create/upload and creating through the hub API of an abstract model.
  • For the whole installation: the setting codamai.cdms.api.create-read-mode in the application’s configuration, default STRICT.
  • Singletons always read back in STRICT mode when created.

For PUT, PATCH and rollback there is no choice: there, writing and reading back always belong to one transaction.

When which mode fits

STRICT or LENIENT?
STRICT
all or nothing
  • the client gets either the object or an error
  • no object that its creator cannot see
  • fits almost all forms
LENIENT
the create matters more than the response
  • the create should stay even if the creator may not read it
  • example: a contact form, a report, an upload into an inbox
  • the client must be able to handle 200 without data

Pitfalls

What comes next

Sources in the code and the knowledge base
  • CDMS/cdms-system-layer – AbstractSystemLayer.createObject (branch by CreateReadMode), AbstractSystemSingletonLayer.createObject, SystemSettings (codamai.cdms.api.create-read-mode)
  • CDMS/cdms-rest-api – WritePayload.createReadMode, AbstractRestApi.createObject, CdmsExceptionMapper (id for CreateSucceededReadFailedException)
  • CDMS/cdms-commons – CreateReadMode, CreateSucceededReadFailedException
  • CDMS/cdms-persistence-database – docs/adr/ADR-007-configurable-create-read-failure-semantics.md
  • documentation/30-daten-und-persistenz/02-transaktionen.md
Search