Objekt-Presenter¶
Der Objekt-Presenter \Alvine\Application\Web\Presenter\Data\Object
ist von \Alvine\Application\Web\Presenter\Data
abgeleitet und
stellt Methoden für die bearbeitung von DELETE
, GET
, HEAD
, PUT
und PATCH
Anfragen bereit. Für die POST
Methode ist ein eigener
Add-Presenter verantwortlich.
Die Steuerung, welcher View zur Anwendung kommt, erfolgt über den vom Client mitgesendeten Accept
-Header. Hier ist entweder
application/json
oder text/html
möglich. Für die HTML-Ausgabe ist der Standardview des Presenters - wenn keiner über
die Konfiguration angegeben wird - die von der Methode Object::getDefaultViewClass()
zurückgegebene Klasse.
Der View kann auch über die Konfiguration in der Route definiert werden.
Hinweis
Sie müssen sicherstellen das Ihr View das Interface \Alvine\Application\Web\View\InstanceFromContainer
implementiert.
Die Datenpresenter arbeiten normalerweise mit einem Suchindex (Solr, EleasticSearch) und einem Objektstorage (MongoDB, Riak, ...) zusammen. Der Presenter kann aber auch für die Verwendung mit SQL-Server konfiguriert werden. Hierzu muss neben der Konfiguration des Storage-Managers auch das Query-Modell angepasst werden. Im Query wird unter anderem der Aufbau des Suchsyntaxes definiert.
Hierzu kann in der Routenkonfiguration ein Tag mit der entsprechenden Klasse gesetzt werden.
<configuration>
<query> <!-- Klassenname des Query -->
<class>MyQuery</class>
</query>
</configuration>
Für die Verwendung von relationalen Datenbanken kann die Klasse Alvine\Persistence\Provider\MySQL\Query
verwendet werden.
Alternativ kann der Presenter auch abgeleitet und die Methode Data::createQueryInstance()
überschrieben werden.
Objekt holen¶
Über die GET
Anfrage können ein oder mehrere Objekte abgefragt werden. Die Einschränkung erfolgt über die definierten Parameter.
Hier können die gewünschten Feldnamen über name=value
eingeschränkt werden. Je nach View wird die Ausgabe als HTML-Datei oder
Json zurückgegeben.
Über folgende Parameter lassen sich weitere Einstellungen vornehmen:
Parmater | Beschreibung |
---|---|
count | Ergebnisse pro Anfrage |
name | Name des zu ändernden Feldes |
offset | Offset der zurückgegeben werden soll |
orderby | Feldnamen nach denen Sortiert werden soll |
page | Seiten die zurückgegeben werden soll |
Im folgenden Beispiel werden maximal 10 Objekte, beginnend auf Seite 2 und nach
dem Feld name
sortiert zurückgegeben.
curl --request GET \
--url 'http://example.com/api/myobject?count=10&page=2&orderby=name' \
--header 'accept: application/json'
Konfiguration der Route¶
<route id="ROUTE-ID-GET">
<method>GET</method>
<presenter>MyPresenter</presenter>
<pattern><![CDATA[^\/api\/object$]]></pattern>
<template><![CDATA[/api/object]]></template>
<configuration>
<model> <!-- Klassenname des Models -->
<class>MyModel</class>
</model>
<query> <!-- Klassenname des Query -->
<class>MyQuery</class>
</query>
<!-- erlaubte Mimetypes für die Antwort: Möglichkeiten: json, html -->
<mimetypes>
<allowed>text/html</allowed>
<allowed>application/json</allowed>
</mimetypes>
<view> <!-- Klassenname des Views für HTML und JSON -->
<class type="texyt/html">\Alvine\Application\Web\View\Data\Object</class>
<class type="application/json">\Alvine\Application\Web\View\Json\Dataset</class>
</view>
</configuration>
</route>
Objekte ändern¶
Über die PUT
Anfrage können ein oder mehrere Objekte geändert werden. Als Ergebnis wird entweder der Status 204 No Content
oder wenn JSON unterstützt wird ein Array mit dem Ergebnis zurück gegeben. Über den Parameter whatif
kann die Anfrage
simuliert werden.
Parmater | Beschreibung |
---|---|
whatif | Anfrage nur flüchtig, ohne echte Aktion durchführen |
Wird in der Route eine Redirect-URL definiert, so wird diese bei der Änderung eines Datensatzes per Location
Header
an den Client übergeben. Bei der Rückgabe von JSON oder mehreren Änderungen ist die Location in der Antwort enthalten.
In dem folgenden Beispiel werden die zwei Datensätze mit der ID 2 und 5 geändert.
curl --request PUT \
--url 'http://example.com/api/object' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"dataset": [
{
"id": 2,
"name": "Neuer Name",
},
{
"id": 5,
"flag":2,
}
]
}'
Im Erfolgsfall ist das Ergebnis folgendes JSON
{
"dataset": [
{
"dataset": {
"id": 2,
"name": "Neuer Name",
"flag": 5,
},
"sys": {
"updated": "2017-10-21T16:15:35",
"message": "200 OK",
"code": 200,
"location": ""
}
},
{
"dataset": {
"id": 5,
"name": "Alter Name",
"flag": 2,
},
"sys": {
"updated": "2017-10-21T16:15:35",
"message": "200 OK",
"code": 200,
"location": ""
}
}
]
}
In diesem Beispiel wurde ein Datensatz geändert und beim zweiten Datensatz ist ein Fehler aufgetreten (die angegebene ID gibt es nicht; 404).
{
"dataset": [
{
"dataset": {
"id": 5,
"name": "Alter Name",
"flag": 2,
},
"sys": {
"updated": "2017-10-21T16:30:31",
"message": "200 OK",
"code": 200,
"location": ""
}
},
{
"sys": {
"error": {
"code": 404,
"message": "404 Not Found"
}
}
}
],
"sys": {
"error": {
"code": 400,
"message": "400 Bad Request"
}
}
}
Werden keine oder falsche Daten übertragen, so wird folgende Fehlermeldung zurückgegeben:
{
"sys": {
"error": {
"code": 400,
"message": "400 Bad Request"
}
}
}
Konfiguration der Route¶
In diesem Beispiel wird das zu ändernde Objekte über die ID bestimmt und geändert.
<route id="ROUTE-ID-UPDATE">
<method>PUT</method>
<presenter>MyPresenter</presenter>
<pattern><![CDATA[^\/api\/object\/(?<id>[0-9]+)$]]></pattern>
<template><![CDATA[/api/object/${id}]]></template>
<configuration>
<model> <!-- Klassenname des Models -->
<class>MyModel</class>
</model>
</configuration>
</route>
Mehrere Objekte können über folgende Konfiguration verarbeitet werden.
Wichtig ist hier, dass der Parameter dataset
definiert ist.
<route id="ROUTE-ID-UPDATE">
<method>PUT</method>
<presenter>MyPresenter</presenter>
<pattern><![CDATA[^\/api\/object$]]></pattern>
<template><![CDATA[/api/object]]></template>
<parameters>
<parameter name="dataset" type="ArrayType" />
</parameters>
<configuration>
<model> <!-- Klassenname des Models -->
<class>MyModel</class>
</model>
</configuration>
</route>
Ein Redirect kann über den Linksbereich in der Route definiert werden.
<route id="ROUTE-ID-UPDATE">
...
<links>
<!-- die ID der anzuwendende Route und die Relation "redirect" -->
<link route="ROUTE-ID-UPDATE" relation="redirect" />
</links>
</route>
Objekte löschen¶
Über die DELETE
Anfrage können ein oder mehrere Objekte gelöscht werden. Als Ergebnis wird entweder der Status 204 No Content
oder wenn JSON unterstützt wird ein Array mit dem Ergebnis zurück gegeben. Die Einschränkung, welches Objekt gelöscht werden
soll erfolgt über die in den Parametern übergebene ID.
Parmater | Beschreibung |
---|---|
whatif | Anfrage nur flüchtig, ohne echte Aktion durchführen |
Die folgende Anfrage löscht den Datensatz mit der ID 1.
curl --request DELETE \
--url 'http://example.com/api/myobject/1' \
--header 'accept: application/json'
Wird an die URL der Parameter whatif
angehängt, so wird der Datensatz nur geprüft, aber nicht gelöscht.
curl --request DELETE \
--url 'http://example.com/api/myobject/1?whatif=true' \
--header 'accept: application/json'
Mehrere Objekte können über ein JSON mit den entsprechenden IDs gelöscht werden. Hierzu muss
in der Route (siehe unten) der Parameter dataset
definiert werden.
curl --request DELETE \
--url 'http://example.com/api/myobject' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"dataset": [
{
"id": 1
},
{
"id": 2
}
]
}'
Das Ergebnis ist dann im Erfolgsfall folgendes:
{
"dataset": [
{
"sys": {
"message": "200 OK",
"code": 200
}
},
{
"sys": {
"message": "200 OK",
"code": 200
}
}
]
}
Werden die Objekte nicht gefunden, so wird ein 404 Fehler zurückgegeben.
Konfiguration der Route¶
In diesem Beispiel wird die ID des zu löschenden Objektes in die URL integriert und von dort ausgelesen. Somit ist die ID der URL Bestandteil der URL.
<route id="ROUTE-ID-DELETE">
<method>DELETE</method>
<presenter>MyPresenter</presenter>
<pattern><![CDATA[^\/api\/object\/(?<id>[0-9]+)$]]></pattern>
<template><![CDATA[/api/object/${id}]]></template>
<configuration>
<model> <!-- Klassenname des Models -->
<class>MyModel</class>
</model>
</configuration>
</route>
Sollen mehrere Objekte mit einem Request gelöscht werden, so kann dies über ein JSON erfolgen. Die entsprechende Route muß folgendermaßen aussehen.
<route id="ROUTE-ID-DELETE">
<method>DELETE</method>
<presenter>MyPresenter</presenter>
<pattern><![CDATA[^\/api\/object$]]></pattern>
<template><![CDATA[/api/object]]></template>
<parameters>
<parameter name="dataset" type="ArrayType" />
</parameters>
<configuration>
<model> <!-- Klassenname des Models -->
<class>MyModel</class>
</model>
</configuration>
</route>
Kopfdaten anfragen¶
Head-Anfragen werden durch die GET
-Methode bearbeitet. Das Verhalten ist dort beschrieben.
Eigenschaft eines Objektes ändern¶
Mittels PATCH
-Anfragen lassen sich einzelne Eigenschaften eines Objektes überschreiben. Die Daten können entweder als
application/json
oder x-www-form-urlencoded
übertragen werden.
Parmater | Beschreibung |
---|---|
name | Name des zu ändernden Feldes |
uuid | Primärschlüssel des Datensatzes der geändert werden soll |
pk | Alternativer Name für den Primärschlüssel |
value | Neuer Wert des zu ändernden Feldes |
whatif | Anfrage nur flüchtig, ohne echte Aktion durchführen |
curl --request PATCH \
--url 'http://{{domain}}/api/commerce/item/catalog/category' \
--header 'accept: application/json' \
--header 'content-type: application/x-www-form-urlencoded'
-d "pk=5&name=flag&value=1425"
Im Erfolgsfall wird folgendes zurückgegeben
{
"dataset": {
"id": 5,
"name": "Alter Name",
"flag": 1425,
},
"sys": {
"updated": "2017-10-22T12:43:37",
"message": "200 OK",
"code": 200
}
}
Im Fehlerfall - fehlerhafte Validierung - wird folgendes zurückgegeben.
{
"sys": {
"validation": {
"report": {
"name": {
"message": "wrong value",
"state": "error",
"valid": false
}
}
},
"error": {
"code": 400,
"message": "400 Bad Request"
}
}
}
Konfiguration der Route¶
<route id="ROUTE-ID-PATCH">
<method>PATCH</method>
<pattern><![CDATA[^\/api\/object$]]></pattern>
<template><![CDATA[/api/object]]></template>
<configuration>
<model> <!-- Klassenname des Models -->
<class>MyModel</class>
</model>
</configuration>
</route>