Datenbank mit REST API

Zu a) von @KonradN und weil ich das in #42 nicht gezeigt habe: wir hätten in dem Fall das DTO als Body des Put-Requests. Heißt, der Aufrufer übermittelt ein JSON in der Form
JSON:
{
    "id": 4711,
    "name": "Daniel Düsentrieb"
}
Das wird dann automatisch in ein UserDTO konvertiert, das die Methode als Parameter erwartet. Bei ein, zwei Felder macht das aber nicht unbedingt Sinn.

Und die NPE ist eine typische "EntwicklerIstZuBlödException" - das sollte dir bewusst sein!
LOL. Man könnte die Abkürzung natürlich auch umdeuten: NPE = NotProfessionalException.
 
Ok ich habe es geändert. Nur hat die Methode nicht wirklich Sinn.
Weil wenn ich bei den Argumenten noch den ort angebe, dann tut der ort ja auch überschrieben werden.
Aber ich denke mal, das DTO ist meist nur für die Ausgabe gedacht, das der Anwender nicht alles sieht.

orElse() habe ich mit mit orElseThrow() verwechselt.
 
Zuletzt bearbeitet:
Weil wenn ich bei den Argumenten noch den ort angebe, dann tut der ort ja auch überschrieben werden.
Generell kann man sich das natürlich so überlegen, wie man das braucht.

Wenn es nur um ein Update geht, dann kann man ein DTO bauen, dass nur Referenzen enthält (Also bei Value Typen die entsprechende Wrapper Klasse). Dann kann man etwas nur dann aktualisieren, wenn es gesetzt wurde. Damit entfällt aber dann das Löschen von Werten - Aber statt null ist es ja denkbar, dass man den leeren String setzt oder so.

Also dann wäre da sowas wie:
if (dto.getName() != null) entity.setName(dto.getName());

Und auch ganz wichtig: Wenn Du ein REST Service haben willst, dann setzt Du da keine einzelnen Parameter sondern es wird ein DTO als Objekt übergeben - wie @mihe7 gesagt hat,
 
Bezüglich dem JSON marshaling - da ist dieses Vorgehen relativ sauber, denn null Werte werden in der Regel einfach weggelassen. Wenn Du also nur id und name gesetzt hast, dann finden sich im JSON die anderen Werte nicht und man hat etwas wie
Code:
{
    id: 1234,
    name: "Some Name"
}
 
Also mache ich es mit JSON, lasse die Parameter weg und übergebe nur das DTO Objekt.
Das ganze soll später von einen anderen Java-Programm abgerufen werden können.
 
Also mache ich es mit JSON, lasse die Parameter weg und übergebe nur das DTO Objekt.
Das ganze soll später von einen anderen Java-Programm abgerufen werden können.
Jein - Du selbst machst nichts mit JSON. Das passiert automatisch. Du hast einen Controller. In dem hast Du ein Mapping. Da baut also Spring Boot dann entsprechend alles für Dich auf. Dabei ist es Dir egal, wie die Daten ankommen. Spring Boot erlaubt JSON aber prinzipiell auch XML.

Das muss Dich als Entwickler nicht interessieren. Du erwartest einen Parameter und der ist vom Typ her dein DTO Objekt.
 
Genau das meinte ich. Mit JSON meinte ich damit beim Test über Postman, da kann man JSON wählen.

Macht sich das dann gut beim Anwenderprogramm mit Java, das ich über JSON arbeite?
 
Genau das meinte ich. Mit JSON meinte ich damit beim Test über Postman, da kann man JSON wählen.

Macht sich das dann gut beim Anwenderprogramm mit Java, das ich über JSON arbeite?
Ja, bei Postman arbeitest Du dann mit JSON.

Aber im Java Client wirst Du hoffentlich nicht direkt mit JSON arbeiten sondern auch mit den DTO Klassen. Die Libraries, die Spring Boot nutzt, kann auch ein Java Client nutzen. Dazu gibt es ja so Libraries wie RESTeasy und Co.
 
Aber im Java Client wirst Du hoffentlich nicht direkt mit JSON arbeiten sondern auch mit den DTO Klassen. Die Libraries, die Spring Boot nutzt, kann auch ein Java Client nutzen. Dazu gibt es ja so Libraries wie RESTeasy und Co.
Das wusste ich nicht, ich dachte man "direkt" drauf zugreifen und sich das Object zurückgeben lassen etc.

Also muss ich später beim Client auch spring Boot aufsetzen, mit ein DTO-Objekt der mit der entfernten Rest-API kommuniziert?
 
wir hätten in dem Fall das DTO als Body des Put-Requests. Heißt, der Aufrufer übermittelt ein JSON in der Form
JSON:
{
    "id": 4711,
    "name": "Daniel Düsentrieb"
}
Das wird dann automatisch in ein UserDTO konvertiert, das die Methode als Parameter erwartet.
Macht das mit auch bei PutMapping Sinn oder sollte man da die Variablen, die geändert werden sollten, als Parameter angeben?
Ich habe Name, Ort und Geburtsdatum und möchte aber nur den Ort ändern, da habe ich den Ort als Parameter übergeben.
Hoffe das ist so richtig.
 
Also generell funktioniert es, oder? Also ist es kein klares falsch.

Aber ich selbst achte immer etwas auf die Methoden und was diese bedeuten. Und bei einer REST API kenne ich es in erster Linie so, dass Entities übergeben werden - an eine Ressource.

Du kannst also eine Entity mit id und Ort an die Ressource User geben um da dann etwas zu ändern. Dann ist nur die Frage: Welche Methode nimmt man da?

Da kann man z.B. schauen, was bei Mozilla dazu gesagt wird: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
Und da ist es eher kein PUT, da Du ja nichts ersetzt (oder neu erstellst). Da ist dann eher ein POST Request das Mittel der Wahl (Wenn ich entscheiden müsste).
 
Das heißt also, ich übergebe (wie beim erstellen eines Objektes) eine UserDTO Entity, mit nur dem ort, die ID wird ja übergeben.
In der Methode erstelle ich ein User-Objekt, mit den ganzen Daten des Objektes mit der ID (Name, ort, geburtsdatum...).
Dann ersetze ich nur die Variablen die in der der UserDTO Entity mitgeteilt wurden (im dem Fall nur der ort), das andere bleibt.
 
Macht das mit auch bei PutMapping Sinn oder sollte man da die Variablen, die geändert werden sollten, als Parameter angeben?
Ich habe Name, Ort und Geburtsdatum und möchte aber nur den Ort ändern, da habe ich den Ort als Parameter übergeben.
Hoffe das ist so richtig.
Die Methode PUT dient zum Ändern eines Objektes. Es ist sinnvoll immer das ganze Objekt zu übergeben. So kann man in dem selben Endpunkt auch mehrere Dinge ändern und braucht keine separaten Endpunkte, z.B.: zum ändern des Namen und zum ändern des Ortes. Als Rückgabe des Endpunktes sollte wieder das gesamte neue Objekt übergeben werden. Im Client wird dann das bestehende Objekt durch die Rückgabe ersetzt.
Man muss dabei bedenken, Webanwendungen haben nicht nur einen Nutzer. Ein andere Nutzer könnte zwischenzeitlich den Vornamen geändert haben (sofern das nicht anderweitig ausgeschlossen wurde). Nachdem das gesamte Objekt zurückgegeben wurde kann auch der neue Vorname im Client angezeigt werden.
Die Datenmenge ist dabei zweitrangig und bei deinem DTO sowieso unbedeutend. Wenn man optimieren möchte könnte man die Objekte gezippt übertragen. Nur bei sehr großen Datenmengen würde ich anfangen die Objekte zu zerlegen.
 
Die Methode PUT dient zum Ändern eines Objektes.
Ach ja - der Moment, wenn einem klar wird, dass man etwas falsches geschrieben hat ... Meine Ausführungen in #64 waren bezüglich POST und PUT natürlich falsch - und ich habe mich da auf eine blöde Grundlage gestellt, die wenig optimal ist.

Daher nutze ich diesen Post als Chance, dies etwas zu korrigieren:

Also erstes die Frage: Wo kann man dies den gut beschrieben finden. Und da ist dann vermutlich die RFC mit am günstigsten:
https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-p2-semantics-16#section-4.3.3

4.3.3 behandelt POST,
4.3.4 dann PUT. Und dann wird schnell deutlich, dass ich in #64 irgendwie neben mir war 🙂

In 4.3.4 findet sich dann auch ein Abschnitt, der den Unterschied deutlich beschreibt:
The fundamental difference between the POST and PUT methods is
highlighted by the different intent for the enclosed representation.
The target resource in a POST request is intended to handle the
enclosed representation according to the resource's own semantics,
whereasç Hence, the intent of PUT
is idempotent and visible to intermediaries, even though the exact
effect is only known by the origin server.

Und das "the enclosed representation in a PUT request is defined as replacing the state of the target resource." beschfreibt ja auch genau das, was Du willst. Du hast eine target Resource (den User) und willst da einen state (den Ort) ändern.

Sorry, wenn ich da bei dem Beitrag eben Verwirrung gestiftet haben sollte.
 

Neue Themen


Zurück
Oben