Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 11 Next »

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

Antwort: 200 OK mit
{
    "resource": [{
        "type": "object",
        "meta": {
            "name": "Land",
            "description": "",
            "properties": [
            {
                "name": "ID",
                "description": "",
                "primary": true,
                "required": true,
                "type": "number"
            },{
                "name": "Bezeichnung",
                "description": "Name",
                "type": "string"
            },{
                "name": "Landadressierung",
                "description": "Darstellung Land \/ PLZ \/ Ort",
                "type": "string"
            }]
        },
       "data": [[1,"Schweiz","CH"]]
    }]

}

 

Update Bezeichnung von auf Land mit der ID 1
Body in JSON:
{
        "Bezeichnung": "neue Bezeichnung"
}
Antwort: wie beim GET
 

Einfügen neues Land

POST auf http://rest.i-ag.ch/Land

Body in JSON:
{
        "Bezeichnung": "Landes-Bezeichnung"
}
Antwort: wie beim GET
 
Löschen von Land mit der ID 10

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:

OperationSyntax
Filter auf Feldnamen?fields={csv attribut}

 

Datenfilter:

OperationSyntax
Gleichheit?{attribut}={wert}
Grösser?{attribut}-max={wert}
Kleiner?{attribut}-min={wert}
Teil-String, enthält?{attribut}-part={wert}
Max. Anzahl Zeilen?maxrows={wert}

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:

OperationSyntax
Sortierung 
  • ?sort={attribut1},{attribut2-asc},{attribut3-desc},…

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:

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}
);

Methoden auf Klassen

Ressourcen können Methoden beinhalten. Hier folgen wir den REST-Konventionen mit der Erweiterung ‚method':

Ersteres ist eine allgemeine Method, z.B. Nachrechnen aller Lagerbestände. Zweites ist eine Methode auf einem bestimmten Datenobjekt mit der ID <id>, also z.B. das Verbuchen einer bestimmten Rechnung.

Methoden können über GET, POST und PUT aufgerufen werden. Aktuell wird nur nach sicheren (es werden keine Daten verändert) und unsicheren Methoden (mit Datenänderung) unterschieden.

Die Struktur der Antwort ist identisch zu derjenigen der CRUD-Operationen. Einziger Unterschied ist, dass die "properties"-Sektion durch eine "parameters"-Sektion ersetzt ist.

Gemäss http-Standards wird für die sicheren Methoden ein GET-Aufruf verlangt, allfällige Parameter werden in der URL mitgegeben.

Unsichere Methoden werden über POST und PUT aufgerufen, die Parameter werden im Body analog zum Update und Create übergeben.

Der Einfachheit halber wird aktuell nicht nach Idempotenz unterschieden, POST und PUT werden in der API gleich behandelt.

Parameterübergabe

Die Parameter können in folgenden Varianten übergeben werden:

  • GET: In der URL form-encoded
  • PUT/POST: 
    • Form-encoded: Im Content 
    • JSON: als einfaches Objekt (ab Rev. 28507). 

Mehrfacher Methoden-Aufruf in einem REST-Aufruf 

Zur Leistungsoptimierung können Methoden mit unterschiedlichen Argumenten in einem Aufruf mehrfach aufgerufen werden, indem die Argumente mehrfach übergeben werden. Die Resultate werden in der Data-Sektion der Antwort in derselben Reihenfolge ausgegeben wie die Argumente übergeben worden sind.

Folgende Varianten sind möglich:

  • URL & form-encoded: Wiederholung der Parameter-Sets mit identischen Namen:  
        "paramA=1&paramB=2&paramA=3&paramB=5" 
  • URL & form-encoded: Wiederholung der Parameter-Sets mit indizierten Namen (ab Rev. 28507):  
        "paramA-0=1&paramB-0=2&paramA-1=3&paramB-1=5"
  • JSON: Die Parameter-Sets werden als Objekte in einem Array übergeben (ab Rev. 28507):
        [ 
            {
              "paramA": 1,
              "paramB": 2 
            },
            { 
              "paramA": 3,
              "paramB": 5 
            }
        ] 

Beispiel: Berechnung der VK-Preise von 2 Artikeln in einem Aufruf:

Url: http://localhost:8084/rest2/ArtikelMethods/method/GetArtPriceSell?ArticleID=8&CustomerID=0&Quantity=1&Date=2015-07-01&ArticleID=3&CustomerID=0&Quantity=1&Date=2015-07-01

Antwort:

{
    "resource": [{
        "type": "object",
        "meta": {
            "name": "GetArtPriceSell",
            "description": "",
            "parameters": [{
                "name": "Price",
                "desciption": "",
                "required": true,
                "type": "number",
                "cardinality": 1,
                "direction": "out"
            },
            {
                "name": "PriceType",
                "desciption": "",
                "required": true,
                "type": "number",
                "cardinality": 1,
                "direction": "out"
            }]
        },
        "data": [[4.9,40],[38,40]]
    }]
}

Meta-Daten

Die Meta-Daten, also Feldnamen und Feldtypen lassen sich über die folgende URI abfragen:


Dasselbe gilt für Views und Methoden, wobei hier Informationen über Aufrufparameter und Rückgabewerte zurückgegeben werden:


Das Format der Metadaten wird analog zu den Nutzdaten von Client angefordert. 
Beispiel JSON: Tabelle Adresse: rest.i-ag.ch/Adresse/model 
{
    "resource": [{
        "meta": {
            "name": "Adresse",
            "description": "",
            "type": "object",
            "properties": [
            {
                "name": "ID",
                "description": "",
                "primary": true,
                "required": true,
                "type": "number"
            },{
                "name": "ABCEinteilung",
                "description": "ABC-Einteilung",
                "type": "number"
            },{
                "name": "AbladevorschriftID",
                "description": "Abladevorschrift",
                "type": "number",
                "links": [
                {
                    "name": "Abladevorschrift",
                    "resource": "Abladevorschrift",
                    "cardinality": 1
                }]
        },{
            "name": "AdresseIDNachfolger",
            ...
            ...    


Die Metadaten werden so weit als möglich nach Draft 04 von json-schema.org aufgebaut, eine Norm existiert zurzeit noch nicht.

Rückgabestatus und Fehlercodes

Jede Antwort vom Server wird mit einem Statuscode zurückgegeben. Bei Fehlern wird zusätzlich ein Detailtext zurückgegeben, der genauere Auskunft über die Ursache gibt. Folgende Codes sind implementiert:

CodeBeschreibung
200 OkAlles i.O.
400 Bad RequestDer URL enthält unerlaubte Zeichen, Strukturen, Parameter, oder die Parameter im Body können nicht interpretiert werden.
401 UnauthorizedNicht authentifiziert
403 ForbiddenNicht autorisiert
404 Not FoundDie angeforderte Ressource wurde nicht gefunden, z.B. ein Delete auf einen nicht existierenden Datensatz.
406 Not AcceptableDer Contenttype (Request oder Response) wird nicht unterstützt.
409 ConflictKonflikt in den Daten, DB-Fehler, z.B. Constraintverletzung
415 Unsupported Media Typeaccept- oder content-type-Header der nicht unterstützt wird.
500 Internal Server ErrorSystem- oder Programmfehler
501 Not ImplementedAnforderung einer nicht implementierten Funktionalität
  • No labels