What this is about
A file model is a model that has exactly one file: an attachment, a logo, a contract as a PDF. It has two parts that live in two different places:
- the record in the database: file name, size, file type and your own fields, such as
titleorcategory, - the content, that is the bytes of the file, in the file storage.
For the client, both are one object. It reads and searches the record like any other object and fetches the content through an endpoint of its own.
Two storage locations, one object
flowchart LR
C["Client"] -->|"read, search record"| D["CDMS"]
C -->|"GET /{id}/file"| D
D --> DB[("Database<br/>id, name, mimeType,<br/>fileSize, fileId, fileVersion,<br/>own fields")]
D --> F[("File storage<br/>content under the fileId")]
DB -. "fileId" .-> F
The fields of a file model
Besides the system fields id, _createdOn and _updatedOn, every file model has these fields:
| Field | Meaning | Who sets it? |
|---|---|---|
name | file name as the user sees it, e.g. Contract.pdf | the client |
mimeType | file type, e.g. application/pdf; derived from the extension of name | the server when it stores the content |
fileSize | size in bytes | the server when it stores the content |
fileId | identifier of the content in the file storage | the server, once at the first save |
fileVersion | identifier of the current content; changes with every new upload | the server when it stores the content |
On top of that come your own fields from the model. When you create the model in the hub, name and the file fields are already taken, and the hub rejects an own field with that name. See Modeling in the hub.
Who manages which part
- read, search, filter like any model
- permissions, row filters, validation, hooks
- history if the model is audited
- part of the request's transaction
- readable only through
GET /{id}/file - separated per tenant, see Storage layout
- old states as versions if the model is audited
- not part of the transaction, see Files and transaction
Standalone or as a child
A file model can stand on its own or hang on another model:
When: The file itself is the object, such as a document in a filing system.
You create it directly: POST /document/create/upload. It has its own endpoints for reading, searching, changing, deleting and downloading.
When: The file belongs to another object, such as Company.logo (1:1) or Dossier.attachments (1:n).
You write it nested with the parent: POST /company/create/upload with the logo in data and its file in the same request. For this, models without a file of their own also get the /upload variants. Downloading goes through the endpoints of the file model.
Result: Whether the file goes along when the parent is deleted is decided by the DELETE flag. See Deleting file models.
The endpoints
| Endpoint | purpose |
|---|---|
POST {basis}/create/upload | create with file, multipart |
PUT {basis}/update/{id}/upload | replace with file, multipart |
PATCH {basis}/update/{id}/upload | change with file, multipart |
POST /create, PUT and PATCH /update/{id} | also possible, the file is then Base64 in the JSON |
GET {basis}/{id}/file?access_token=… | download the content |
All other endpoints (read, search, delete, history) work with the record like for any model. See Which endpoints a model has.
Prerequisite
The application needs a file storage: the local file system (FILESYSTEM), a directory on the server or on a volume. Without a storage, every request that writes or reads content fails with file-storage-not-configured. See Storage backends.
What comes next
- Uploading a file: Uploading
- Fetching a file: Downloading
- Old states: File versions