Die Funktionsweise der API kann auf einfach Art nachvollzogen werden, wenn man einen aktuellen Firefox-Browser mit installierter Firebug Erweiterung zur Verfügung hat:
Verwendet man jetzt die einzelnen Funktionen der Anwendung und beobachtet dabei die Ajax-Kommunikation mit dem Server wird schnell offensichtlich, wie die einzelnen Operationen funktionieren.
Im Firebug können jetzt sowohl die HTTP-Header (Anfrage und Antwort), sowie die Übertragenen Requests im Detail angeschaut werden. Die Funktionsweise der API-Funktionen, zumindest für die HTTP-GET Methoden kann ebenfalls direkt im Browser ausprobiert werden, indem man - bei angemeldetem Benutzer - den entsprechenden Aufruf direkt als URL eingibt. Beispiel:
Im Unterschied zu den AJAX-Requests vom Frontend werden alle Requests, die von einem Maschinen-Client kommen über eine Api-Wrapper geschickt. Der Sinn liegt darin, dass es möglich und notwendig ist ggf. verschiedene Versionen der API gleichzeitig zu unterstützen. Damit muss der Anfragende Client die gewünschte Api-Version im Aufruf codieren. Dies geschieht durch Anpassung der Resourcen-URL. Hier das Bespiel von oben für die API-Version 1.1.
Das Wrapper-Objekt liefert die Orginal-Response aus dem Interface call im Feld response. Das Wrapper-Objekt hat zusätzlich folgende Fehler:
Feld | Beschreibung | |
---|---|---|
servicePrefix | Das servicePrefix wid immer geliefert. Es hilft der Client-Anwendung den Service-Aufruf für den eigentlichen Service zu konstruieren | |
methodCall | ggf. der Name des Services der aufgerufen wurde (im Moment nicht belegt) | |
statusCode | API-Call Status Antwort. Eine response wird nur belegt, wenn der statusCode == 0 ist. Dann ist in der Regel auch die statusMessage gesetzt. | |
statusMessage | falls statusCode <> 0 eine Erläuterung des Fehlers | |
apiSessionName | der Name der für das Session-Cookie zu verwenden ist und im Anfrage-Header gesendet werden muss (sieh auch Cookie im Firebug) | |
apiSessionToken | der Wert für das Session-Cookie, also der eigentliche Session-Token | |
minorNumber | die Angefragte Api-Versions-Nummer (Minor-Part) | |
majorNumber | die Angefragte Api-Versions-Nummer (Major-Part) |
Die Minor- und Major-Nummer können als 0,0 zurück gegeben werden, falls der statusCode == 0 ist und gelten damit für ALLE Api-Versionen.
{ "servicePrefix" : "/ica/rest/api/1/1/service/", "methodCall" : null, "response" : { "success" : true, "data" : [ { "descriptor" : "LAUFEND", "name" : "", "representedClass" : "de.iconcept.nami.entity.beitrag.BeitragZahlTermin", "id" : "LAUFEND" } ], "responseType" : "OK", "totalEntries" : 1 }, "statusCode" : 0, "statusMessage" : "", "apiSessionName" : "JSESSIONID", "apiSessionToken" : "DwMhUAAd9ZMrAG90HtheoBwe.undefined", "minorNumber" : 1, "majorNumber" : 1 } |
Alle API-Anfragen liefern Antworten, die in einem HTTP-Response Transportiert werden. Beim Prüfen der Antwort ist auf jeden Fall zuerst den HTTP-Status-Code zu überprüfen. Gültige Server-Antworten tragen die HTTP-Status-Code:
2xx und 3xx. Für die Auswertung von Operationen sind lediglich Antworten mit den Status-Codes 2xx zu berücksichtigen.
Alle Antworten sind in de Regel in eine ApiResponse Objekt auf REST-Anfragen sind in einer ExtResponse - Objekten
Die Architektur der ICA-Api Schnittstelle basiert auf dem REST- Paradigma (siehe dazu auch http://de.wikipedia.org/wiki/Representational_State_Transfer).
Folgende Prinzipien wurden übernommen und finden sich in der Implementierung wieder:
Allen Objekten des Backends sind Resourcen-URLs zugeordnet. Sofern die Basis-URL der Anwendung bekannt ist, sowie die Resourcen URL des gewünschten Objektes, dann sind prinziell die Basis-CRUD-Operation (Create, Read, Update und Delete) möglich.
Der Zugriff auf die Benötigte Operation erfolgt über die korrekte HTTP-Methode auf der Resourcen-URL und mittels anhängen der ID, mit der die Instanz der Resouce identifiziert wird.
Operation | HTTP-Methode | Beschreibung | Pfad-Erweiterung | Bedingung | Antwort |
---|---|---|---|---|---|
CREATE | POST | Legt ein neues Objekt an | |||
UPDATE | PUT | Aktualisiert die übergebenen Instanz zur gegebenen ID | /ID | ID=Identifier Instanz Resource | |
READ | GET | Liefert die Instanz zur übergebenen ID der angefragten Resouce | /ID | ID=Identifier Instanz Resource | |
READ | GET | Liefert eine Kurz-Liste aller Instanzen der angefragen Resource | |||
DELETE | DELETE | Löscht das existierendes Objekt mit der gegebenen ID | /ID | ID=Identifier Instanz Resource |
Weitere Lese-Operation können über die Pfad-Erweiterung der GET-Methode möglich sein:
Pfad-Erweiterung | Beschreibung | Request-Parameter | Antwort |
---|---|---|---|
/flist | Liste alle Objekte einer Resource mit allen "listbaren" Feldern | ExtResponse; data= List von Response-Objekten | |
/default | Liefert ein Vorbelegtes Objekt für die CREATE Operation | Pagination Daten | ExtResponse; data = Instanz Resource Objekt |
/META | Liefert die Meta-Informationen zum Objekt | ExtRespone | |
/download | Liefert eine xls-Dokument mit den "listbaren" Felder aller Instanzen des angefragten Objekts | ||
Alle Antworten, die vom Server zurück gegeben werden und vom Type application/json sind werden IMMER in einem RestResponse-Objekt zurück geliefert. Folgende Felder sind immer vorhanden:
RestResponseType
Feld | Type | Inhalt | |
---|---|---|---|
success | boolean | true, false | |
responseType | RestResponseType:String | OK, INFO, WARN, ERROR, EXCEPTION | |
message | String | Die Nachricht, falls success <> true |
Beispiel-Request: http://ICA_HOST/ICA_DEPLOY/rest/api/1/1/service/orgadmin/beitragsart/META/
Die Meta-Daten beschreiben ein komplettes Resourcen-Objekt. Für alle CRUD-Objekte, die über die Schnittstelle zur Verfügung gestellt werden steht die META Operation zur Verfügung.
Feld | Typ | Inhalt | Beschreibung |
---|---|---|---|
fields | array | Liste der Felder als Array von Objekten von FieldDefinition(s) | Beschreibt, von welchem Typ die Felder eines Objektes sind, wie die Sortierung ist, ob sie sichtbar sind usw. Sieh dazu die Erläuterung zu FieldDefinition |
relations | array | Liste der Relationen | |
actions | array | Liste von String der erlaubten CRUD-Operationen | |
flist | boolean | true / false | flist- Operation ist möglich ja / nein |
pageSize | int | Seitengröße | Anzahl der Einträge, die pro Seite im List-Aufruf geliefert werden |
label | string | Title (Name) der Resource | |
groupable | boolean | Gruppierbar | Falls true, sollten die Felder des Objektes auf mehrere Tabs aufgeteilt werden |
mainDataTabLabel | String | Name des Objekttyps | |
tabGroups | Array von TabGroup | TabGroup (id, label, position) | |
groupingType | |||
* | * | nur für das Benutzer-Interface | |
Bei der Verwendung von META-Objekten müssen NEUE Felder ignoriert werden (auch ohne API-Versions-Wechsel) Hier aufgeführte Felder bleiben innerhalb einer Version sematisch und syntaktisch erhalten.
Feld | Typ | Inhalt | Beschreibung |
---|---|---|---|
name | String | Feldname. Falls ein Objekt angelegt oder aktualisiert wird MUSS das geänderte Objekt dieses Feld beinhalten, sofern es berücksichtigt werden soll. | |
type | String:ExtField | Enum (ID, textfield, displayfield, comboBox, checkbox, hidden, date, numberfield, HTML_EDITOR | Definiert das Eingabe-Interface, wie Daten angezeigt, bzw editiert werden (sollen) |
visible | boolean | Anzeigen: Ja / Nein | |
enabled | boolean | Feld aktiv ja / nein | |
serviceUrl | String | Falls type comboBox ist, dann existiert immer noch ein 2. Feld mit der gleichen Namens mit der Endung id. Das "id-" Feld beinhaltet dabei die Referenz auf eine anderes Objekt, das eigentliche Feld, den "Namen" der Relation. Beispiele sind: Das Geschlecht beim Mitglied, das Land bei der Versandanschrift, etc | |
inputType | String | TEXT oder PASSWORD | Mit Password markierte Felder sollten bei der Eingabe "xxxxx" sein. |
order | int | Sortierreihenfolge | |
label | String | Der Anzeige-Name für das Feld | |
labelId | String | Eindeutige ID für das Feld | |
searchable | boolean | Ist das Feld suchbar | Wird eine über die Suche reduzierte Liste oder /flist angefragt und wurde ein nicht suchbares Feld angegeben wird ein Fehler auftreten. |
sortable | boolean | ist nach diesem Feld sortierbar | Wird eine über die Suche reduzierte Liste oder /flist angefragt und wurde ein nicht sortierbares Feld zum Sortieren angegeben wird ein Fehler auftreten. |
listable | boolean | Zeigt an, ob das Feld in der /flist auftauchen wird | |
pageSize | int | default pageSize für den Service-Call, falls type = comboBox |
{ "servicePrefix" : "/ica/rest/api/1/1/service/", "methodCall" : null, "response" : { "success" : true, "data" : { "fields" : [ { "name" : "id", "type" : "ID", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "", "searchable" : false, "sortable" : false, "listable" : false, "labelId" : "id", "label" : "ID", "order" : 1, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "", "labelCssClass" : "", "mandatory" : false, "actions" : [ "CREATE", "READ", "UPDATE" ] }, { "name" : "name", "type" : "textfield", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "", "searchable" : false, "sortable" : false, "listable" : true, "labelId" : "name", "label" : "Name", "order" : 10, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "", "labelCssClass" : "", "mandatory" : false, "regex" : "", "regexText" : "", "actions" : [ "CREATE", "READ", "UPDATE" ] }, { "name" : "beitragsTyp", "type" : "comboBox", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "nami/enum/beitragstyp", "searchable" : true, "sortable" : false, "listable" : true, "labelId" : "beitragsTyp", "label" : "Beitragstyp", "order" : 20, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "", "labelCssClass" : "", "mandatory" : false, "dependentOn" : [], "pageSize" : 1000, "multiSelect" : false, "actions" : [ "CREATE", "READ", "UPDATE" ] }, { "name" : "periodizitaet", "type" : "comboBox", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "nami/enum/periodizitaet", "searchable" : false, "sortable" : false, "listable" : true, "labelId" : "periodizitaet", "label" : "Periodizität", "order" : 30, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "", "labelCssClass" : "", "mandatory" : false, "dependentOn" : [], "pageSize" : 1000, "multiSelect" : false, "actions" : [ "CREATE", "READ", "UPDATE" ] }, { "name" : "zahlungsEmpfaenger", "type" : "comboBox", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "namiBeitrag/zahlungsempfaenger", "searchable" : false, "sortable" : false, "listable" : false, "labelId" : "zahlungsEmpfaenger", "label" : "Zahlungsempfänger", "order" : 40, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "", "labelCssClass" : "", "mandatory" : false, "dependentOn" : [], "pageSize" : 1000, "multiSelect" : false, "actions" : [ "CREATE", "READ", "UPDATE" ] }, { "name" : "beitragsEmpfaenger", "type" : "comboBox", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "namiBeitrag/beitragsempfaenger", "searchable" : false, "sortable" : false, "listable" : false, "labelId" : "beitragsEmpfaenger", "label" : "Beitragsempfänger", "order" : 50, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "", "labelCssClass" : "", "mandatory" : false, "dependentOn" : [], "pageSize" : 1000, "multiSelect" : false, "actions" : [ "CREATE", "READ", "UPDATE" ] }, { "name" : "beitragZahlTermin", "type" : "comboBox", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "nami/enum/beitragzahltermin", "searchable" : false, "sortable" : false, "listable" : true, "labelId" : "beitragZahlTermin", "label" : "Zahlungsweise", "order" : 60, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "", "labelCssClass" : "", "mandatory" : false, "dependentOn" : [], "pageSize" : 1000, "multiSelect" : false, "actions" : [ "CREATE", "READ", "UPDATE" ] }, { "name" : "mwstSatz", "type" : "comboBox", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "baseadmin/mwstsatz/", "searchable" : false, "sortable" : false, "listable" : false, "labelId" : "mwstSatz", "label" : "Mehrwertsteuer", "order" : 60, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "", "labelCssClass" : "", "mandatory" : false, "dependentOn" : [], "pageSize" : 1000, "multiSelect" : false, "actions" : [ "CREATE", "READ", "UPDATE" ] }, { "name" : "buchungsTextPattern", "type" : "textfield", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "", "searchable" : false, "sortable" : false, "listable" : true, "labelId" : "buchungsTextPattern", "label" : "Buchungstext", "order" : 70, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "", "labelCssClass" : "", "mandatory" : false, "regex" : "", "regexText" : "", "actions" : [ "CREATE", "READ", "UPDATE" ] }, { "name" : "prozBeitragsPflicht", "type" : "textfield", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "", "searchable" : false, "sortable" : false, "listable" : true, "labelId" : "prozBeitragsPflicht", "label" : "Mindestzugehörigkeit Abr.-Periode", "order" : 80, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "Option, Mitglieder nur dann abzurechnen, wenn Sie mindestens x% der Abrechnungsperiode beitragspflichtiges Mitglied waren. Bezogen auf die Periodizität der Abrechnungsperiode. Angabe als ganze Zahl (wird als % angewendet).", "labelCssClass" : "", "mandatory" : false, "regex" : "^(\\d{0,3})$", "regexText" : "Falsches Format. Beispiel richtiges Format: 12", "actions" : [ "CREATE", "READ", "UPDATE" ] }, { "name" : "abweichendesErloeskonto", "type" : "textfield", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "", "searchable" : false, "sortable" : false, "listable" : true, "labelId" : "abweichendesErloeskonto", "label" : "Abweichendes Erlöskonto", "order" : 99, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "", "labelCssClass" : "", "mandatory" : false, "regex" : "", "regexText" : "", "actions" : [ "CREATE", "READ", "UPDATE" ] }, { "name" : "btgsPflgMonateInFirstPeriod", "type" : "numberfield", "inputType" : "TEXT", "visible" : true, "enabled" : "true", "serviceUrl" : "", "searchable" : false, "sortable" : false, "listable" : true, "labelId" : "btgsPflgMonateInFirstPeriod", "label" : "btgsPflgMonateInFirstPeriod", "order" : 99, "tabGroupAssociation" : [], "hidden" : false, "columnCssClass" : "", "tooltipText" : "", "labelCssClass" : "", "mandatory" : false, "allowDecimals" : false, "minValue" : 1.0, "maxValue" : 12.0, "actions" : [ "CREATE", "READ", "UPDATE" ] } ], "relations" : [], "actions" : [ "UPDATE", "READ", "CREATE", "DELETE", "DOWNLOAD" ], "packageName" : "de.iconcept.nami.entity.beitrag.BeitragsArt", "simpleClassName" : "BeitragsArt", "flist" : true, "pageSize" : 20, "label" : "Beitragsart", "description" : false, "extraActions" : [], "groupable" : false, "tabGroups" : null, "groupingType" : "TABS", "loadDefaultEntity" : false, "mainDataTabLabel" : "Beitragsart", "withActionsOnMultipleRows" : false, "associatedFilterableEntities" : [ { "name" : "beitragsart", "label" : "Beitragssatz", "baseClass" : "BeitragsArt", "relClass" : "BeitragsSatz", "serviceUrl" : "orgadmin/beitragssatz/filtered/", "type" : "ONE_TO_MANY", "readOnly" : null, "filteringPropertyName" : "beitragsArt" } ], "extraActionsInExtraToolbar" : false }, "responseType" : "OK", "message" : null, "title" : null }, "statusCode" : 0, "statusMessage" : "", "apiSessionName" : "JSESSIONID", "apiSessionToken" : "DwMhUAAd9ZMrAG90HtheoBwe.undefined", "minorNumber" : 1, "majorNumber" : 1 } |