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 8 Next »

Codierung der Daten

Alle zu übermittelnden Daten müssen im ASCII-Format und HTTP-konform übertragen werden.
Folgende Daten-Konvertierung ins ASCII-Format wird erwartet:

DatentypFormat
ZeichenkettenErsetzen der reservierten Zeichen gemäss Übergabeformat / HTTP-Standard
Binärbase64-Codierung
DatumswerteISO 8601
BooleanTrue/False
ZahlenDezimaltrennzeichen Punkt, keine weiteren Formatzeichen

URL-Encoded

Content-type:    application/x-www-form-urlencoded
Accept: -


Dieses Format wird zum Senden (zum REST-Server) von Nutzdaten unterstützt. Es gelten die Regeln nach RFC 3986 über die URI-Syntax (http://tools.ietf.org/html/rfc3986

Die Nutzdaten werden in Form von Name-Wert-Paaren übergeben, die jeweils Url-encoded werden müssen. 

Beispiel für die Übergabe der Parameter ABCEinteilung, Name und Geburtsdatum:

Daten:

ABCEinteilung=1&Name=äöüèéàÖÄÜÉÀÈ+@#°§¬|¢´~¦¨][{}-"*ç%&(/=<>,?&Geburtsdatum=2000-10-02T00:00:00.000Z 

Payload:

ABCEinteilung=1&Name=%C3%A4%C3%B6%C3%BC%C3%A8%C3%A9%C3%A0%C3%96%C3%84%C3%9C%C3%89%C3%80%C3%88%2B%40%23%C2%B0%C2%A7%C2%AC%7C%C2%A2%C2%B4%7E%C2%A6%C2%A8%5D%5B%7B%7D%2D%22%2A%C3%A7%25%26%28%2F%3D%3C%3E%2C%3F&Geburtsdatum=2000%2D10%2D02T00%3A00%3A00.000Z

JSON

Content-type:   application/json
Accept:             application/json

Format "compact"

Dieses Format erlaubt bei grosser Anzahl Datensätzen eine reduzierte Nutzdatenmenge und die Übergabe von Zusatzinformationen in den Metadaten.

Accept:             application/json;compact

Senden Client -> REST

Die Nutzdaten werden als JSON-Objekt in Form von Name-Wert-Paaren übergeben. In der einfachen Form sieht das so aus:

Daten:

{
    "ABCEinteilung":"2",
    "Name":"abc"
}

Sollen gleichzeitig Detaildatensätze respektive Substrukturen übergeben werden, so muss das in folgender Form geschehen:

{
    "<Attribut-Name>":"<Attribut-Wert>",
    "<Attribut-Name>":"<Attribut-Wert>",
   .....
   "<Entität-Name>": [

       {
          "<Attribut-Name>":"<Attribut-Wert>",
          "<Attribut-Name>":"<Attribut-Wert>" ,
          ......
       }
    ] 

Dies Sub-Entitäten können beliebig tief verschachtelt werden. Sie müssen aber immer zwingend benannt werden und in Array-Form übergeben werden,

Die Struktur muss zwingend dem Datenmodel entsprechen, d.h die logische Verbindung zwischen den Elementen muss definiert sein, und zwar immer vom übergeordneten Element zum untergeordneten:

Einem Auftrag können Positionen angehängt werden, aber positionen nicht einem Auftrag. Von dieser Regel ausgenommen sind referenzierte Daten, die nur einmal vorkommen. z.B. eine Adresse kann einem Auftrag mitgegeben werden (obwohl der Auftrag Datentechnisch durch die referenzielle Integrität von der Adresse abhängt).

 

Konkret im Beispiel eines Updates auf einen Kurs mit 2 Unterlisten zu Grundausbildungen und Anstellungsarten sieht es so aus:

{
    "BildungsschwerpunktID": 13,
    "GrundausbildungListe": [
        {
           "StichwortID": 7
        },
        {
           "StichwortID": 7
        }
    ],
    "AnstellungsartListe": [
        {
           "StichwortID": 1
        },
        {
           "StichwortID": 2
        },       
        {
           "StichwortID": 3
        }
    ] 
}

Sobald Substrukturen übergeben werden, wird diese als komplett gültige Liste betrachtet, d.h. bei Update-Operationen werden zuerst alle vorhandenen Einträge gelöscht, dann werden alle übergebenen eingefügt.

Als Konsequenz werden mit einer leeren Daten-Liste alle vorhandenen Einträge gelöscht:

    …
    "GrundausbildungListe": [],
    …

Ist dies nicht gewollt und die vorhandene Liste soll nicht verändert werden, darf die Substruktur nicht übergeben werden.

Empfangen REST -> Client

Bei der Ausgabe von Daten wird unterschieden, ob ein einziges Root-Element vorhanden ist, oder ob auf oberster Ebene mehrere Datensätze ausgegeben werden können. Folgende regeln gelten:

AusgabeRequest
Root, einzelnes ObjektEindeutig über die ID identifizierte Entität, z.B. ../rest2/region/12
(GET, PUT, POST und DELETE) 

Methoden mit einem Parameter-Set (keine Mehrfachaufrufe)


Merfache Datensätze, ArrayAlle Views

Alle Abfragen auf Entitäten
(GET mit Filter oder ohne ID im Pfad) 

Methoden mit mehreren Parameter-Sets

Die Datenstrukturen sind dabei identisch zu denjenigen die gesendet werden. 

Beipiele:

GET auf ../rest/mwst:

[
   {
      "ID": 1,
      "Aktiv": true,
      "Bezeichnung": null,
      "ExterneID": null,
   }
]

GET auf ../rest/mwst/1:

{
   "ID": 1,
   "Aktiv": true,
   "Bezeichnung": null,
   "ExterneID": null,
}

Format "fullmeta"

Dieses Format erlaubt bei grosser Anzahl Datensätzen eine reduzierte Nutzdatenmenge und die Übergabe von Zusatzinformationen in den Metadaten.

Accept:             application/json;fullmeta

Senden Client -> REST

Die Nutzdaten werden als JSON-Objekt in Form von Name-Wert-Paaren übergeben. In der einfachen Form sieht das so aus:

Daten:

{
    "ABCEinteilung":"2",
    "Name":"abc"
}

Sollen gleichzeitig Detaildatensätze respektive Substrukturen übergeben werden, so muss das in folgender Form geschehen:

{
    "<Attribut-Name>":"<Attribut-Wert>"
    "childList": [
    {
        "meta": {
            "name": "<Entität-Name>",
            "parameters": [
            {
               "name": "<Parameter-Name>",
            },{
            ...
            ...
            },{
               "childList": [
                {....}]
           }
        }
        "data": [<Array mit den Daten gemäss Parameter>]
    },
    {
        "meta":...
        ... 
    }]
}

Das Element childList entspricht in der Struktur exakt dem resource-Element für Methoden-Aufrufe. Diese Elemente können beliebig tief verschachtelt werden. Definiert werden sie in der Liste der Parameter.

Die Struktur muss zwingend dem Datenmodel entsprechen, d.h die logische Verbindung zwischen den Elementen muss definiert sein, und zwar immer vom übergeordneten Element zum untergeordneten:

 

Konkret im Beispiel eines Updates auf einen Kurs mit 2 Unterlisten zu Grundausbildungen und Anstellungsarten sieht es so aus:

{
    "BildungsschwerpunktID":"13",
    "childlist": [
    {
        "meta": {
            "name": "GrundausbildungListe",
            "parameters": [{
            "name": "StichwortID"
            }]
        },
        "data": [[7], [8]]
    },
    {
        "meta": {
            "name": "AnstellungsartListe",
            "parameters": [{
            "name": "StichwortID"
            }]
        },
        "data": [[1], [2], [3]]
    }
    ]
}

Sobald Substrukturen übergeben werden, wird diese als komplett gültige Liste betrachtet, d.h. bei Update-Operationen werden zuerst alle vorhandenen Einträge gelöscht, dann werden alle übergebenen eingefügt.

Als Konsequenz werden mit einer leeren Daten-Liste alle vorhandenen Einträge gelöscht:

        …
        "name": "AnstellungsartListe",
        "parameters": [{
        "name": "StichwortID"
    }]
    },
    "data": []

Ist dies nicht gewollt und die vorhandene Liste soll nicht verändert werden, darf die Substruktur nicht übergeben werden.

Empfangen REST -> Client

Jede zurückgegeben Datenstruktur besteht aus den Elementen „meta" und „data". Damit wird strikte zwischen den Nutzdaten und den Meta-Informationen unterschieden, die Verarbeitung der Antworten wird vereinheitlicht.

In den Nutzdaten stehen nur die angeforderten Daten. Dieses Element kann auch leer sein, wenn keine Nutzdaten zurückgegeben werden, z.B. bei der Abfrage von Metadaten oder bei Fehlermeldungen.

Der meta-Bereich wird für beschreibende Informationen zu der ausgeführten Operation und/oder den Daten verwendet. Darin stehen z.B. die Feldnamen bei Abfragen, sowie weiterführende Links zu abhängigen Daten.Werden nur die Meta-Daten abgefragt (/model), ist der data-Bereich leer.

Die generelle Rückgabe-Struktur sieht wie folgt aus:

{
    "resource": [{
        "type": "<Resourcentyp "object">",
        "meta": {
            "name": "<Entität-Name im Kontext der Abfrage>",
            "description": "<Beschreibung>",
            "parameters": [ Nur bei Views und Methoden
            {
                "name": "<Parameter-Name>",
                "description": "<Beschreibung>",
                "required": <Ist Pflichtfeld [true|false], optional>,
                "type": "<Feldtyp number|string|object|boolean|datetime|base64>"
                "cardinality": <Kardinalität 1|2147483647>
            },{
                ...
                ...
            }],
            "properties": [
            {
                "name": "<Element-Name>",
                "description": "<Beschreibung>",
                "primary": <Ist Primärschlüssel [true|false], optional>,
                "required": <Ist Pflichtfeld [true|false], optional>,
                "type": "<Feldtyp number|string|object|boolean|date-time|base64>"
                "links": [
                {
                    "resource": "<Entität-Name ohne Kontext>",
                    "cardinality": <Kardinalität 1|2147483647>,
                    <Wiederholung des Meta-Elements> Bei Model-Abfragen wird vom Meta-Element nur der Name zurückgegeben, da der Baum je nach Datenmodell ansonsten ins Unendliche wächst.
                }]
            },{
                ...
                ...
            }]
        }
        "data": [<Array mit den Daten gemäss properties>] Bei Elementen mit Detail-Datensätzen wird der Element-Wert als Array mit 2 Werten ausgegeben, dem Feldwert und einem Array mit den Detaildatensatz-Arrays. Die data-Struktur         entspricht exakt derjenigen des properties-Elements. 
    }]
}


Fehlermeldungen werden in einem analogen Format zurückgegeben: 

{
    "resource": [{
        "type": "<Resourcentyp „message">",
        "code": "<ErrorCode mit Errortext>",
        "message": "<Detailtext>"
    }]
}

Die resource-Elemente können sich wiederholen, wenn unterschiedliche Daten-Strukturen in einem Aufruf übergeben werden.


Beispiel einer komplexen Abfrage einiger Adress-Daten, Attributen des Aufwandkontos und der hinterlegten MWST-Details, sowie der vorhandenen Belege der Adresse 1181:

Abfrageresultat
{
	"resource": [{
		"type": "object",
		"meta": {
			"name": "Adresse",
			"description": "",
			"properties": [{
				"name": "AnredeID",
				"description": "Anrede",
				"type": "number"
			},
			{
				"name": "Name",
				"description": "Name",
				"type": "string"
			},
			{
				"name": "Name2",
				"description": "Zweitname",
				"type": "string"
			},
			{
				"name": "ID",
				"description": "",
				"primary": true,
				"required": true,
				"type": "number",
				"links": [{
					"name": "Beleg",
					"resource": "Beleg",
					"cardinality": 2147483647,
					"description": "",
					"type": "object",
					"properties": [{
						"name": "ArtikelTotal",
						"description": "Artikeltotal",
						"type": "number"
					},
					{
						"name": "AuftragsNr",
						"description": "Auftrags-Nr.",
						"type": "number"
					},
					{
						"name": "BelegNr",
						"description": "Nummer",
						"type": "number"
					},
					{
						"name": "ID",
						"description": "",
						"primary": true,
						"required": true,
						"type": "number"
					},
					{
						"name": "AdresseID",
						"description": "Adresse",
						"type": "number"
					}]
				}]
			},
			{
				"name": "KontoIDAufwand",
				"description": "Vorschlag Aufwandskonto",
				"type": "number",
				"links": [{
					"name": "KontoAufwand",
					"resource": "Konto",
					"cardinality": 1,
					"description": "Vorschlag Aufwandskonto",
					"type": "object",
					"properties": [{
						"name": "Bezeichnung",
						"description": "Bezeichnung",
						"type": "string"
					},
					{
						"name": "Kontoart",
						"description": "Kontoart",
						"type": "number"
					},
					{
						"name": "ID",
						"description": "",
						"primary": true,
						"required": true,
						"type": "number"
					},
					{
						"name": "MWSTID",
						"description": "Vorschlag MWST",
						"type": "number",
						"links": [{
							"name": "MWSTToOne",
							"resource": "MWST",
							"cardinality": 1,
							"description": "Vorschlag MWST",
							"type": "object",
							"properties": [{
								"name": "Aktiv",
								"description": "MWST aktiv",
								"type": "boolean"
							},
							{
								"name": "Bezeichnung",
								"description": "Bezeichnung",
								"type": "string"
							},
							{
								"name": "Kuerzel",
								"description": "Kürzel",
								"type": "string"
							},
							{
								"name": "ID",
								"description": "",
								"primary": true,
								"required": true,
								"type": "number"
							}]
						}]
					}]
				}]
			}]
		},
		"data": [[null,
		"Meine AG",
		null,
		[1181,
		[14835.15,
		1024,
		11476,
		4904,
		1181],
		[14835.15,
		1024,
		1024,
		4907,
		1181],
		[42.25,
		null,
		2643,
		4914,
		1181],
		[311.1,
		null,
		2644,
		4915,
		1181],
		[110.3,
		null,
		2645,
		4916,
		1181]],
		[1000008,
		["Einkauf Bier",
		3,
		1000008,
		[2,
		[true,
		"8% MWST",
		"8%",
		2]]]]]]
	}]
}


Customizing, Modellerweiterungen

Die Anwendungen der I-AG sind stark modellbasiert und können somit auch in der REST-Schnittelle individuell angepasst werden.

Typischer Einsatz ist das Abschirmen der internen Struktur um eine vereinfachte Sicht nach aussen zu geben, die für den jeweiligen Fall optimal ist.

Als Beispiel werden das Denormalisieren von Referenzwerten wie Gebindebezeichnug, oder das Berechnen benötigter Daten wie der aktuelle Lagerbestand etc. in einer Bestellposition genannt.

Es ist auch möglich, denormalisierte Daten schreibbar zugänglich zu machen.

 

 

  • No labels