What this is about
For every model, the generator creates a REST controller with a fixed set of operations. All paths start with /api/rest followed by the model’s API path. The API path is built from the folder in the hub and the model name in lower case, for example /crm/customer.
The complete set
This is the set of a normal model with everything switched on. {base} stands for /api/rest/crm/customer.
| What you want to do | Method and path | Body |
|---|---|---|
| create | POST {base}/create | JSON |
| create, with files | POST {base}/create/upload | multipart |
| read, choose the fields | POST {base}/read/{id} | JSON with response |
| read, quick look | GET {base}/read/{id} | none, always returns * |
| replace | PUT {base}/update/{id} | JSON |
| replace, with files | PUT {base}/update/{id}/upload | multipart |
| update | PATCH {base}/update/{id} | JSON |
| update, with files | PATCH {base}/update/{id}/upload | multipart |
| delete | DELETE {base}/delete/{id} | none |
| search, filter, page | POST {base}/query | JSON with response and parameter |
| read history | POST {base}/{id}/history | JSON |
| roll back to an old revision | POST {base}/{id}/rollback/{revision} | JSON with response |
| download a file | GET {base}/{id}/file | none |
The endpoint list on the model
In the hub, a model gets a list of endpoints. Each entry has a type, and the generator turns it into operations:
| Type in the list | Generated operations |
|---|---|
| CREATE | POST /create (and /create/upload) |
| READ | POST /read/{id} and GET /read/{id}, no search |
| LIST, QUERY or SEARCH | POST /query |
| UPDATE | PUT /update/{id} and PATCH /update/{id} (each also /upload) |
| PATCH | only PATCH /update/{id} |
| DELETE | DELETE /delete/{id} |
| HISTORY_READ, HISTORY_QUERY | POST /{id}/history, audited models only |
| HISTORY_ROLLBACK | POST /{id}/rollback/{revision}, audited models only |
| DOWNLOAD | GET /{id}/file, file models only |
| UPLOAD | the /upload variants, only relevant for file models |
| unknown type | nothing; the build prints a warning |
Three more rules that are easy to overlook:
- create, read, update, patch, delete, query, upload and download are generated
- history and rollback are not, you have to add them explicitly
- READ only creates reading by
id - If you need a list, add LIST (or QUERY)
- without
auditingon the model, no history or rollback endpoints are created, whatever the list says
Each list entry can also say who may use the endpoint: a role of its own, the model’s base role, or public without sign-in. That is covered in Model roles.
The special forms
When: the usual case
The complete set as above, filtered by the endpoint list. Each object is addressed by its id in the path.
When: The model is marked as a singleton: exactly one object per scope.
The paths have no id; the server finds the one object by itself: POST /create, POST /read, GET /read, PUT /update, PATCH /update, DELETE /delete, GET /file, POST /history, POST /rollback/{revision}. There is no search. A second create fails with 400 object-already-exists|use-update, an update without an existing object with 404 no-data-exists|use-create. See Singletons.
When: The model has subtypes, e.g. customer with privatecustomer and businesscustomer.
The model gets a hub API with the same paths. It forwards each request to the API of the concrete subtype: when writing based on @type in the payload, when reading and deleting based on the type stored for the id. See Abstract models.
When: The model stores a file.
In addition there is GET /{id}/file for downloading, as soon as DOWNLOAD or READ is listed. The /upload variants exist as soon as UPLOAD, CREATE or UPDATE is listed: a file model that cannot accept a file would be useless. See Files.
Which endpoints does my model have?
-
1ClientOpen the installation's OpenAPI description. It lists every generated endpoint with its payloadIt is the authoritative answer, because it is built from the generated code.
-
2AdminLook at the model in the hub: which types are in the endpoint list? Is the model audited, a singleton, abstract, a file model?
-
3ClientTry it: the response tells you what is going onResult: 404 → the endpoint does not exist. 403 → the endpoint exists, the role is missing. 401 → the token is missing or expired.
What deliberately does not exist
| Expectation | How it is |
|---|---|
POST /save that creates or updates depending on the id | does not exist; the client chooses between create and update based on the id |
field selection via query parameter (?fields=) | the field selection is in the body, see Field selection |
search via GET with parameters in the URL | search runs through POST /query |
| bulk operations for many objects in one request | not provided; related objects can be written nested |
| an endpoint that lists all models | the OpenAPI description is that overview |