CRUD
Die CRUD-Operationen werden über folgende HTTP-Verben unterstützt:
- Create: POST
- Read: GET oder HEAD
- Update: PUT
- Delete: DELETE
Die zu verwendenden URIs entsprechen dem Objektmodell: rest.i-ag.ch/{Klasse}. Folgendes ist zu beachten:
- Jedes Objekt ist im Kontext der Klasse mit einer eindeutigen Id identifizierbar: rest.i-ag.ch/{Klasse}/{ID}.
- Beim Update (PUT) und Löschen (DELETE) ist die Syntax mit der ID zwingend.
- Beim Insert (POST) ist keine ID erlaubt, es kann jedoch kann ein Vater-Objekt angegeben werden, um Kind-Elemente anzufügen: rest.i-ag.ch/{Klasse}/{ID}/{Klasse}.
- Nutzdaten werden beim Insert (POST) und Update (PUT) im Body übergeben.
- Lesend (GET) kann die komplette Baumstruktur des Objektmodells verwendet werden: rest.i-ag.ch/{Klasse}/{ID}/{Kind-Klasse}/{ID}/…
Bsp. Mehrwertsteuerdetails zum Aufwandkonto der Adresse mit der Id 123: ./Adresse/123/KontoAufwand/MWSTToOne.
Beispiele
Lese Land 1
GET auf http://rest.i-ag.ch/Land/1
Einfügen neues Land
POST auf http://rest.i-ag.ch/Land
DELETE auf http://rest.i-ag.ch/Land/10
Antwort: 200 Ok ohne Body
Queries auf Klassen
Beim Lesen (GET-Operation) besteht die Möglichkeit, Daten über Filterparameter einzuschränken:
Rückgabefelder:
Operation | Syntax |
---|---|
Filter auf Feldnamen | ?fields={csv attribut} |
Datenfilter:
(Tipp: Alle Ungleich-Filter beginnen mit ne = not equal)
Operation | Syntax | Verwendung in Klassen | Verwendung in Views |
---|---|---|---|
Gleichheit | ?{attribut}={wert} | x | x |
Ungleichheit | ?{attribut}-ne={wert} | x | |
Grösser | ?{attribut}-max={wert} | x | |
Kleiner | ?{attribut}-min={wert} | x | |
Teil-String, enthält | ?{attribut}-part={wert} | x | |
Teil-String, enthält nicht | ?{attribut}-nepart={wert} | x | |
Max. Anzahl Zeilen | ?maxrows={wert} | x | x |
Gleich Null | ?{attribut}-null | x | x |
Ungleich Null | ?{attribut}-nenull | x | x |
Alle obigen Einschränkungen lassen sich kombinieren, wobei unter den Filtern immer der UND-Operator angewandt wird. Wird bei der Gleichheit ein Feld mehrfach angegeben, wird unter den Werten eine ODER Verknüpfung angewandt, was in SQL einem IN entspricht.
Bsp: ….?feld1=1&feld1=2&feld2-max=77 -> (feld1 = 1 OR feld1 = 2) AND feld2 <= 77
Sortierung:
Operation | Syntax |
---|---|
Sortierung |
|
Besipiel: rest.i-ag.ch/Land?fields=Id,Bezeichnung&id-min=1&id-max=100
Dies gibt von alle Einträgen der Ländertabelle von ID 1 bis ID 100 die Felder ID und Bezeichnung zurück.
Views
Für komplexe Fälle reicht dies aber nicht mehr. In einem solchen Fall wird die View näher spezifiziert:
- rest.i-ag.ch/view/{view}?{parameter}={wert}&…
- rest.i-ag.ch/{Klasse}/view/{view}?{parameter}={wert}&…
- rest.i-ag.ch/{Klasse}/{id}/view/{view}?{parameter}={wert}&…
In diesem Fall wird eine im Modell benannte View verwendet. Diese lässt sich auch Kunden-spezifisch in einer Modell-Erweiterung definieren.
Die einzusetzenden Parameter sind von der View vordefiniert und können über die Metadaten-Syntax abgefragt werden (rest.i-ag.ch/view/{view}/model).
Parameter mit mehrfacher Auswahl werden entsprechend mehrfach angegeben, analog zum Gleichheits-Datenfilter in der Query auf Klassen.
Je nach View ist es auch möglich, diese ganz wegzulassen, wenn keine Einschränkung auf den Parameter erwünscht ist. Dies ist in den Metadaten im Parameter-Attribut Kardinalität mit dem Wert 2147483647 angegeben.
Die Attribute „sort" und „fields" sind erlaubt. Es können unter Umständen Einschränkungen bestehen, wenn Felder nicht eindeutig nur über ihren Name bestimmbar sind. Z.B. ein Feld „Bezeichnung" kann in mehreren Unterstrukturen vorkommen.
Views können komplexe Datenbäume zurückgeben. Die hierarchische Verknüpfung der Datensätze wird in den Meta-Daten analog mit dem Attribut links ausgedrückt. Details siehe Abschnitt Struktur der Übergabeformate.
Eine Paging-Funktionalität ist nicht implementiert. Eine analoge Funktionalität kann mit den Sortier-Optionen und einer Einschränkung auf die maximale Anzahl Datensätze erreicht werden.
Datentypen (interne Info)
Bei berechneten Felder kann der Datentyp nicht ohne zusätzliche Information in der Abfrage bestimmt werden. Standardmässig werden alle berechneten Felder als String ausgegeben.
Wird der genaue Datentyp benötigt, so kann dieser mit Hilfe von Makro-Direktiven in der Abfrage angegeben werden (von „aussen" nicht steuerbar).
Die Syntax lautet:
{$define <FeldName> <Datantyp>}
<FeldName> bezieht sich auf eine Feldbezeichnung innerhalb der Abfrage.
<Datentyp> muss eine gültige Bezeichnung aus aAtValueType sein.
Beispiel AQL:
->Unittestparent.grouped(
TextVal groupby;
nb := group.count(TextVal); {$define nb vtInteger1}
bv := group.avg(BoolVal); {$define bv vtBoolean}
dv := group.min(DateVal); {$define dv vtDateTime}
iv := group.min(IntVal); {$define iv vtInteger2}
cv := group.min(CurVal); {$define cv vtFloat8}
);