Worum es geht
Ein Datei-Modell ist ein Modell, zu dem genau eine Datei gehört: ein Anhang, ein Logo, ein Vertrag als PDF. Es besteht aus zwei Teilen, die an zwei verschiedenen Orten liegen:
- dem Datensatz in der Datenbank: Dateiname, Größe, Dateityp und deine eigenen Felder, etwa
titleodercategory, - dem Inhalt, also den Bytes der Datei, im Dateispeicher.
Für den Client ist beides ein Objekt. Er liest und sucht den Datensatz wie jedes andere Objekt und holt den Inhalt über einen eigenen Endpunkt.
Zwei Speicherorte, ein Objekt
flowchart LR
C["Client"] -->|"Datensatz lesen, suchen"| D["CDMS"]
C -->|"GET /{id}/file"| D
D --> DB[("Datenbank<br/>id, name, mimeType,<br/>fileSize, fileId, fileVersion,<br/>eigene Felder")]
D --> F[("Dateispeicher<br/>Inhalt unter der fileId")]
DB -. "fileId" .-> F
Die Felder eines Datei-Modells
Neben den Systemfeldern id, _createdOn und _updatedOn hat jedes Datei-Modell diese Felder:
| Feld | Bedeutung | Wer setzt es? |
|---|---|---|
name | Dateiname, wie ihn der Benutzer sieht, z. B. Vertrag.pdf | der Client |
mimeType | Dateityp, z. B. application/pdf; abgeleitet aus der Endung von name | der Server beim Speichern des Inhalts |
fileSize | Größe in Byte | der Server beim Speichern des Inhalts |
fileId | Kennung des Inhalts im Dateispeicher | der Server, einmal beim ersten Speichern |
fileVersion | Kennung des aktuellen Inhalts; ändert sich mit jedem neuen Upload | der Server beim Speichern des Inhalts |
Dazu kommen deine eigenen Felder aus dem Modell. Beim Anlegen im Hub sind name und die Dateifelder schon vergeben, ein eigenes Feld mit diesem Namen lehnt der Hub ab. Siehe Modellieren im Hub.
Wer welchen Teil verwaltet
- lesen, suchen, filtern wie jedes Modell
- Rechte, Zeilenfilter, Validierung, Hooks
- Historie, wenn das Modell auditiert ist
- Teil der Transaktion der Anfrage
- nur über
GET /{id}/filelesbar - getrennt nach Mandant, siehe Ablage
- alte Stände als Versionen, wenn das Modell auditiert ist
- nicht Teil der Transaktion, siehe Dateien und Transaktion
Eigenständig oder als Kind
Ein Datei-Modell kann für sich stehen oder an einem anderen Modell hängen:
Wann: Die Datei ist selbst das Objekt, etwa ein Dokument in einer Ablage.
Du legst es direkt an: POST /document/create/upload. Es hat seine eigenen Endpunkte zum Lesen, Suchen, Ändern, Löschen und Herunterladen.
Wann: Die Datei gehört zu einem anderen Objekt, etwa Company.logo (1:1) oder Dossier.attachments (1:n).
Du schreibst sie verschachtelt mit dem Elternobjekt: POST /company/create/upload mit dem Logo in data und seiner Datei im selben Request. Dafür bekommen auch Modelle ohne eigene Datei die /upload-Varianten. Herunterladen geht über die Endpunkte des Datei-Modells.
Ergebnis: Ob die Datei beim Löschen des Elternobjekts mitgeht, entscheidet das DELETE-Flag. Siehe Datei-Modelle löschen.
Die Endpunkte
| Endpunkt | wofür |
|---|---|
POST {basis}/create/upload | anlegen mit Datei, Multipart |
PUT {basis}/update/{id}/upload | ersetzen mit Datei, Multipart |
PATCH {basis}/update/{id}/upload | ändern mit Datei, Multipart |
POST /create, PUT und PATCH /update/{id} | ebenso möglich, die Datei steht dann als Base64 im JSON |
GET {basis}/{id}/file?access_token=… | Inhalt herunterladen |
Alle anderen Endpunkte (lesen, suchen, löschen, Historie) arbeiten mit dem Datensatz wie bei jedem Modell. Siehe Welche Endpunkte ein Modell hat.
Voraussetzung
Die Anwendung braucht einen Dateispeicher: das lokale Dateisystem (FILESYSTEM), ein Verzeichnis auf dem Server oder einem Volume. Ohne Speicher scheitert jede Anfrage, die einen Inhalt schreibt oder liest, mit file-storage-not-configured. Siehe Speicher-Backends.
Wie es weitergeht
- Eine Datei hochladen: Hochladen
- Eine Datei holen: Herunterladen
- Alte Stände: Dateiversionen