OBS/Kostenpflichtige Module/RESTServer/Endpunkte: Unterschied zwischen den Versionen

Aus OBS Wiki
Zur Navigation springen Zur Suche springen
Rademacker (Diskussion | Beiträge)
Keine Bearbeitungszusammenfassung
Rademacker (Diskussion | Beiträge)
Keine Bearbeitungszusammenfassung
Zeile 161: Zeile 161:
| '''413''' || Hochgeladene Datei überschreitet die zulässige Maximalgrösse (<code>re_upload_size</code>)
| '''413''' || Hochgeladene Datei überschreitet die zulässige Maximalgrösse (<code>re_upload_size</code>)
|-
|-
| '''429''' || Rate-Limit Überschritten; die Antwort enthÄlt den Header <code>Retry-After</code>
| '''429''' || Rate-Limit überschritten; die Antwort enthält den Header <code>Retry-After</code>
|-
| '''503''' || Eine Anfrage mit demselben <code>Idempotency-Key</code> wird gerade verarbeitet; die Antwort enthält <code>Retry-After</code>
|-
| '''409''' || Ein früherer Aufruf mit demselben <code>Idempotency-Key</code> ist ohne Ergebnis geblieben (<code>IDEMPOTENCY_UNRESOLVED</code>)
|-
| '''422''' || Derselbe <code>Idempotency-Key</code> wurde mit '''anderem''' Inhalt gesendet (<code>IDEMPOTENCY_KEY_REUSED</code>)
|}
|}
Jede Fehlerantwort enthält zusätzlich ein <code>error</code>-Objekt mit
maschinenlesbarem Code - Aufbau siehe
[[OBS/Kostenpflichtige Module/RESTServer|Übersicht]].


Daneben kann ein Endpunkt-Skript den Statuscode selbst setzen (z.B. <code>201</code>, <code>204</code>, <code>409</code>, <code>422</code>) sowie Response-Header wie <code>ETag</code> oder <code>Location</code> - siehe [[OBS/Kostenpflichtige Module/RESTServer/Scripting|Scripting]].
Daneben kann ein Endpunkt-Skript den Statuscode selbst setzen (z.B. <code>201</code>, <code>204</code>, <code>409</code>, <code>422</code>) sowie Response-Header wie <code>ETag</code> oder <code>Location</code> - siehe [[OBS/Kostenpflichtige Module/RESTServer/Scripting|Scripting]].
== Idempotenz ==
Schickt ein Konsument bei <code>POST</code>, <code>PUT</code>, <code>PATCH</code>
oder <code>DELETE</code> den Header <code>Idempotency-Key</code>, sorgt der Server
selbst dafür, dass eine wiederholte Sendung '''keine Zweitwirkung''' hat. Das gilt
für '''jeden''' Endpunkt - es muss weder am Endpunkt etwas eingestellt noch im
Skript etwas programmiert werden.
{| class="wikitable"
! Situation !! Antwort des Servers
|-
| Erster Aufruf || Endpunkt läuft normal, das Ergebnis wird zum Schlüssel gespeichert
|-
| Wiederholung, gleicher Inhalt || '''Gespeicherte Antwort''' (gleicher Statuscode, gleicher Body, gleiche Header) plus Header <code>Idempotent-Replay: true</code>. Das Skript läuft '''nicht'''
|-
| Wiederholung, anderer Inhalt || '''422''' <code>IDEMPOTENCY_KEY_REUSED</code> - derselbe Schlüssel für einen anderen Inhalt ist ein Client-Fehler
|-
| Erster Aufruf läuft noch || '''503''' <code>IDEMPOTENCY_IN_PROGRESS</code> mit <code>Retry-After</code>. Beim nächsten Versuch liegt die gespeicherte Antwort vor
|-
| Früherer Aufruf ohne Ergebnis || '''409''' <code>IDEMPOTENCY_UNRESOLVED</code>. Der Dienst wurde zwischen Verarbeitung und Festschreiben unterbrochen; ob die Buchung stattgefunden hat, ist unbekannt und von Hand zu klären
|}
Wichtig für die Auslegung eines Endpunkts:
* Antwortet das Skript mit '''2xx''', wird die Antwort gespeichert und bei einer Wiederholung erneut ausgeliefert.
* Antwortet das Skript mit '''4xx''' (fachliche Ablehnung), wird der Schlüssel wieder '''freigegeben''' - der Konsument darf ihn nach Korrektur erneut verwenden. Sonst würde ein einziger Validierungsfehler den Schlüssel dauerhaft blockieren.
* Endet die Verarbeitung mit '''5xx''' oder einem Skript-Fehler, bleibt der Schlüssel belegt und der Fall wird protokolliert. Das ist Absicht: lieber ein Fall für den Support als eine mögliche Doppelbuchung.
Der Schlüssel gilt je '''Zugang, Methode und Pfad'''. Derselbe
<code>Idempotency-Key</code> an einem anderen Endpunkt ist damit ein eigener
Vorgang - der Konsument muss ihn nicht global eindeutig vergeben, aber pro Vorgang
'''stabil wiederverwenden''' (also nicht bei jedem Wiederholversuch neu erzeugen).
Die Einträge stehen in <code>RESTSRV_IDEMPOTENCY</code> und werden nach 30 Tagen
automatisch aufgeräumt. Einträge ohne Ergebnis werden '''nicht''' automatisch
gelöscht, sondern im Protokoll gemeldet.


== WebHooks ==
== WebHooks ==
Zeile 171: Zeile 218:
erfolgreichen Aufruf wird die Antwort in der Tabelle <code>REMOTE_HOOK_URL</code>
erfolgreichen Aufruf wird die Antwort in der Tabelle <code>REMOTE_HOOK_URL</code>
gespeichert und der Endpunkt anschließend automatisch gelöscht.
gespeichert und der Endpunkt anschließend automatisch gelöscht.
Typischer Einsatz: OBS stösst einen Vorgang bei einem Fremdsystem an (Bezahldienst,
Versanddienstleister) und gibt diesem eine Rückruf-Adresse mit, die nur '''ein
einziges Mal''' gültig ist. Damit kann die Adresse nicht später erneut - oder von
jemand anderem - benutzt werden.
Ablauf:
# OBS legt einen Eintrag in <code>REMOTE_HOOK_URL</code> an und dazu einen Endpunkt, dessen Feld '''WebHook''' (<code>re_webhook</code>) auf diesen Eintrag zeigt. Ein Skript wird für diesen Endpunkt nicht gepflegt.
# Die Adresse dieses Endpunkts wird dem Fremdsystem als Callback-URL übergeben.
# Das Fremdsystem ruft die Adresse auf. Der Server legt den übergebenen Inhalt in <code>REMOTE_HOOK_URL.hu_response</code> ab, antwortet mit <code>{"status": "ok"}</code> und '''löscht den Endpunkt'''.
# Der weiterverarbeitende OBS-Prozess findet die Rückmeldung in <code>hu_response</code>.
{{Hinweis|Ein zweiter Aufruf derselben Adresse läuft ins Leere: Der Endpunkt
existiert nicht mehr, die Antwort ist 404. Das ist gewollt - ein WebHook ist keine
dauerhafte Schnittstelle. Für eine dauerhaft erreichbare Rückmelde-Adresse einen
normalen Endpunkt mit Skript anlegen.}}

Version vom 17. August 2026, 07:50 Uhr

Kostenpflichtige Module

Internet-Shop
UPS
IMS Professional
SMS
Mehrlager-Verwaltung
Mehrsprachen Modul
Multilanguage Modul
EVA Marketing Tool
Termin-Projekte
Edifact-Schnittstelle
Backup Überwachung Email
OBS Geo Daten
DeliSprint / DPD
Filialen
Cashback
Moebelschnittstelle
Dokumenten Manager
DocuWare-Schnittstelle
OFML-Kalkulation
Versicherungsschaden
Gutschriftsanzeigen
Kameraverwaltung
DataInOut
OpenMasterData / IDS
Sammelpositionen



Endpunkte

Ein Endpunkt stellt eine Adresse bereit, über die der REST-Server konkrete Funktionen anbietet. Jeder Endpunkt wird durch ein OBS-Skript oder einen WebHook realisiert und ist genau einem Server-Profil zugeordnet.

Routing über Pfad-Templates

Das Routing erfolgt über die Spalte Pfad-Template (re_pathtemplate). Ein Template beschreibt den vollständigen Pfad nach dem Host und kann Platzhalter enthalten:

  • Statische Segmente müssen exakt übereinstimmen (Groß-/Kleinschreibung wird ignoriert).
  • Platzhalter in geschweiften Klammern – z. B. {uid} – passen auf einen beliebigen Wert und werden als Pfad-Parameter erfasst.

Beispiele für gültige Templates:

Template Passt auf Pfad-Parameter
/orders /orders
/orders/{uid} /orders/4711 uid = 4711
/orders/{uid}/modules/{code} /orders/4711/modules/A1 uid = 4711, code = A1
/kalender/v1 /kalender/v1

Präzedenz bei mehreren Treffern

Passen mehrere Templates auf denselben Pfad, gewinnt das spezifischste – also das mit den meisten statischen Segmenten. So schlägt /orders/summary das Template /orders/{uid}, während /orders/4711 auf /orders/{uid} matcht.

Hauptfelder eines Endpunkts

Feld Spalte Zweck
Pfad-Template re_pathtemplate Maßgeblich fürs Routing. Vollständiger Pfad mit Platzhaltern, z. B. /orders/{uid}/modules/{code}
Server re_server Zuordnung zum Server-Profil (erforderlich)
Aktiv re_aktiv Statusflag; inaktive Endpunkte liefern 404
Skript re_script DwScript-Quelltext des Handlers (siehe Scripting)
WebHook re_webhook optional: Verweis auf einen Einmal-Endpunkt statt Skript
Info Dokumentations-Freitext
Datei-Upload re_upload Erlaubt Datei-Uploads an diesem Endpunkt (0 = aus, 1 = an). Ohne Freigabe werden Upload-Anfragen mit 415 abgelehnt.
Max. Upload-Grösse re_upload_size Maximale Dateigrösse in MB. Leer/0 = Standard 25 MB. Überschreitung wird mit 413 abgelehnt.

Pfad-Parameter im Skript

Die aus den Platzhaltern erfassten Werte stehen im Endpunkt-Skript als reservierte Parameter mit Präfix _OBS_PATH_ zur Verfügung:

function Get(oParams: TStrings; oBody: TJSONObject): string;
var cUid: string;
begin
    cUid := oParams.Values['_OBS_PATH_uid'];   // aus /orders/{uid}
    // ...
end;

Da der Präfix _OBS_ für von außen gelieferte Header/Query-Parameter gesperrt ist, können diese Werte nicht durch den Client überschrieben werden.

Datei-Uploads

Ein Endpunkt nimmt Datei-Uploads nur entgegen, wenn er dafür freigeschaltet ist (re_upload = 1). Andernfalls werden Upload-Anfragen mit 415 Unsupported Media Type abgelehnt und das Skript wird nicht ausgeführt.

Die maximal zulässige Dateigrösse wird pro Endpunkt über re_upload_size (in MB) festgelegt; ohne Angabe gilt der Standard von 25 MB. Wird das Limit überschritten, antwortet der Server mit 413 Payload Too Large. Für Uploads gilt nicht das JSON-Body-Limit (10 MB), sondern dieses Endpunkt-Limit. Der Originalname (beim resumable Upload über den Header Upload-Metadata) ist Pflicht; fehlt er, wird der Upload mit 413/400 abgelehnt. Dem Skript stehen Pfad, Name und Content-Type als _OBS_UPLOAD_*-Parameter zur Verfügung (Details: Scripting).

Unterstützt werden zwei Übertragungsarten:

  • Einfacher Upload per multipart/form-data (eine Datei pro Request).
  • Resumable/Chunked Upload per Content-Range (grosse Dateien, fortsetzbar nach Abbruch).

Der Server legt die hochgeladene Datei in einem temporären Verzeichnis ab und übergibt dem Endpunkt-Skript den Pfad. Was mit der Datei geschieht (Ablage, DMS-Verknüpfung, Weiterverarbeitung), entscheidet allein das Skript. Details und Beispiele: Scripting.

HTTP-Methode

Welche Funktion aufgerufen wird, ergibt sich aus dem HTTP-Verb: Der Server ruft die gleichnamige Skript-Methode auf (Get/Post/Put/Delete/Patch). Ein Template entspricht damit einem Endpunkt-Skript; unterschiedliche Pfad-Formen (z. B. /orders vs. /orders/{uid}) sind eigene Endpunkt-Einträge mit eigenem Skript und eigener Berechtigung.

URL-Struktur

http://[Host][:Port][Pfad-Template]

Beispiele:

Versionierung

Da es kein eigenes Versions-Feld mehr gibt, wird die Version als statisches Segment ins Template aufgenommen, z. B. /orders/v1 oder /v1/orders/{uid}. Änderung ohne Breaking Change:

  1. Bestehenden Endpunkt unverändert lassen.
  2. Neuen Endpunkt mit gleichem Ressourcennamen, aber neuem Versions-Segment im Template anlegen.
  3. Berechtigungen für neue Konsumenten setzen.
  4. Alten Endpunkt deaktivieren, wenn die Migration abgeschlossen ist.

Zugriffskontrolle

Endpunkte sind Server-Profilen zugeordnet; ein Zugang benötigt eine explizite Berechtigung (Tabelle RESTSRV_ACCESS), um einen Endpunkt nutzen zu dürfen. Weil jede Pfad-Form ein eigener Endpunkt-Eintrag ist, lässt sich der Zugriff pro Pfad-Form granular vergeben (z. B. Lesen von /orders/{uid} erlauben, aber das ändernde PUT /orders/{uid}/modules/{code} nicht).

Caching

Die Endpunkt-Definitionen werden pro Server-Profil zwischengespeichert (TTL, Standard 60 s). Neue oder geänderte Endpunkte/Templates werden daher erst nach Ablauf des Caches (bzw. nach einer Cache-Invalidierung) wirksam – nicht zwingend sofort.

HTTP-Fehlercodes

Code Ursache
404 Kein Template passt zum Pfad, Endpunkt inaktiv oder falsches Server-Profil
403 Zugang fehlt in der Berechtigungsliste
401 API-Key ungültig/fehlend oder JWT abgelaufen
500 Skript- oder Syntax-Fehler (Details in RESTSRV_PROTO)
415 Datei-Upload an einen Endpunkt, der dafür nicht freigeschaltet ist (re_upload = 0)
413 Hochgeladene Datei überschreitet die zulässige Maximalgrösse (re_upload_size)
429 Rate-Limit überschritten; die Antwort enthält den Header Retry-After
503 Eine Anfrage mit demselben Idempotency-Key wird gerade verarbeitet; die Antwort enthält Retry-After
409 Ein früherer Aufruf mit demselben Idempotency-Key ist ohne Ergebnis geblieben (IDEMPOTENCY_UNRESOLVED)
422 Derselbe Idempotency-Key wurde mit anderem Inhalt gesendet (IDEMPOTENCY_KEY_REUSED)

Jede Fehlerantwort enthält zusätzlich ein error-Objekt mit maschinenlesbarem Code - Aufbau siehe Übersicht.

Daneben kann ein Endpunkt-Skript den Statuscode selbst setzen (z.B. 201, 204, 409, 422) sowie Response-Header wie ETag oder Location - siehe Scripting.

Idempotenz

Schickt ein Konsument bei POST, PUT, PATCH oder DELETE den Header Idempotency-Key, sorgt der Server selbst dafür, dass eine wiederholte Sendung keine Zweitwirkung hat. Das gilt für jeden Endpunkt - es muss weder am Endpunkt etwas eingestellt noch im Skript etwas programmiert werden.

Situation Antwort des Servers
Erster Aufruf Endpunkt läuft normal, das Ergebnis wird zum Schlüssel gespeichert
Wiederholung, gleicher Inhalt Gespeicherte Antwort (gleicher Statuscode, gleicher Body, gleiche Header) plus Header Idempotent-Replay: true. Das Skript läuft nicht
Wiederholung, anderer Inhalt 422 IDEMPOTENCY_KEY_REUSED - derselbe Schlüssel für einen anderen Inhalt ist ein Client-Fehler
Erster Aufruf läuft noch 503 IDEMPOTENCY_IN_PROGRESS mit Retry-After. Beim nächsten Versuch liegt die gespeicherte Antwort vor
Früherer Aufruf ohne Ergebnis 409 IDEMPOTENCY_UNRESOLVED. Der Dienst wurde zwischen Verarbeitung und Festschreiben unterbrochen; ob die Buchung stattgefunden hat, ist unbekannt und von Hand zu klären

Wichtig für die Auslegung eines Endpunkts:

  • Antwortet das Skript mit 2xx, wird die Antwort gespeichert und bei einer Wiederholung erneut ausgeliefert.
  • Antwortet das Skript mit 4xx (fachliche Ablehnung), wird der Schlüssel wieder freigegeben - der Konsument darf ihn nach Korrektur erneut verwenden. Sonst würde ein einziger Validierungsfehler den Schlüssel dauerhaft blockieren.
  • Endet die Verarbeitung mit 5xx oder einem Skript-Fehler, bleibt der Schlüssel belegt und der Fall wird protokolliert. Das ist Absicht: lieber ein Fall für den Support als eine mögliche Doppelbuchung.

Der Schlüssel gilt je Zugang, Methode und Pfad. Derselbe Idempotency-Key an einem anderen Endpunkt ist damit ein eigener Vorgang - der Konsument muss ihn nicht global eindeutig vergeben, aber pro Vorgang stabil wiederverwenden (also nicht bei jedem Wiederholversuch neu erzeugen).

Die Einträge stehen in RESTSRV_IDEMPOTENCY und werden nach 30 Tagen automatisch aufgeräumt. Einträge ohne Ergebnis werden nicht automatisch gelöscht, sondern im Protokoll gemeldet.

WebHooks

WebHooks sind Einmal-Endpunkte für asynchrone Callbacks. Beim ersten erfolgreichen Aufruf wird die Antwort in der Tabelle REMOTE_HOOK_URL gespeichert und der Endpunkt anschließend automatisch gelöscht.

Typischer Einsatz: OBS stösst einen Vorgang bei einem Fremdsystem an (Bezahldienst, Versanddienstleister) und gibt diesem eine Rückruf-Adresse mit, die nur ein einziges Mal gültig ist. Damit kann die Adresse nicht später erneut - oder von jemand anderem - benutzt werden.

Ablauf:

  1. OBS legt einen Eintrag in REMOTE_HOOK_URL an und dazu einen Endpunkt, dessen Feld WebHook (re_webhook) auf diesen Eintrag zeigt. Ein Skript wird für diesen Endpunkt nicht gepflegt.
  2. Die Adresse dieses Endpunkts wird dem Fremdsystem als Callback-URL übergeben.
  3. Das Fremdsystem ruft die Adresse auf. Der Server legt den übergebenen Inhalt in REMOTE_HOOK_URL.hu_response ab, antwortet mit {"status": "ok"} und löscht den Endpunkt.
  4. Der weiterverarbeitende OBS-Prozess findet die Rückmeldung in hu_response.
HINWEIS: Ein zweiter Aufruf derselben Adresse läuft ins Leere: Der Endpunkt

existiert nicht mehr, die Antwort ist 404. Das ist gewollt - ein WebHook ist keine dauerhafte Schnittstelle. Für eine dauerhaft erreichbare Rückmelde-Adresse einen

normalen Endpunkt mit Skript anlegen.