Kapitel 2
Anfragen von Hand schreiben
Sichere und idempotente Methoden
In Kapitel 1 hast du zwei Arten von Anfragen an practice-api gesendet: GET, das nach einer Ressource fragt, und HEAD, das nach derselben Antwort ohne ihren Body fragt. Das erste Wort der Anfragezeile ist die
GET und HEAD. Drei weitere sind für diesen Kurs wichtig: POST, PUT und DELETE. practice-api akzeptiert nur GET und HEAD, also wirst du ihm die anderen nicht senden; der Server, den du in Kapitel 5 schreibst, akzeptiert alle fünf.
Jede Methode gibt zwei Versprechen, auf die sich ein Client verlassen kann. Beide betreffen, was mit den Daten auf dem Server passiert, nicht die Antwort, die zurückkommt.
Sicher
Eine Methode ist sicher (safe), wenn der Client um keine Änderung bittet. Den Datensatz eines Buchs zu lesen ändert nichts auf dem Server, also ist GET sicher, und HEAD ebenso. Ein Server darf trotzdem eine Zeile in sein Log schreiben oder den Besuch zählen; sicher bedeutet, dass der Client um keine Änderung gebeten hat und für keine verantwortlich gemacht werden kann.
Idempotent
Eine Methode ist
Nimm eine Leseliste, einen Server, der eine DELETE /books/7 entfernt Buch 7. Sende es noch einmal, und Buch 7 ist immer noch weg; sonst hat sich nichts geändert. Also ist DELETE idempotent, obwohl es nicht sicher ist: Die erste Anfrage hat die Liste sehr wohl geändert.
PUT /books/7 mit einem Body setzt Buch 7 auf genau diesen Body. Sende es zweimal, und Buch 7 enthält in beiden Fällen denselben Body, also ist auch PUT idempotent.
POST /books mit einem Body bittet den Server, ein Buch hinzuzufügen und seine Nummer zu wählen. Sende es zweimal, und die Liste enthält zwei neue Bücher. POST ist weder sicher noch idempotent.
Die fünf Methoden
| Methode | Beispiel bei einer Leseliste | Sicher | Idempotent |
|---|---|---|---|
GET | GET /books/7: sende Buch 7 | ja | ja |
HEAD | HEAD /books/7: sende den Kopf, den GET senden würde, ohne den Body | ja | ja |
POST | POST /books: füge dieses Buch hinzu und wähle seine Nummer | nein | nein |
PUT | PUT /books/7: mach Buch 7 genau zu diesem | nein | ja |
DELETE | DELETE /books/7: entferne Buch 7 | nein | ja |
Jede sichere Methode ist auch idempotent: Eine Anfrage, die nichts ändert, hinterlässt denselben Zustand, egal wie oft du sie sendest. Umgekehrt gilt das nicht, wie PUT und DELETE zeigen.
Warum das einen Client interessiert
Manchmal sendet ein Client eine Anfrage, und die Antwort kommt nie. Die Verbindung bricht ab, oder das Timeout des Clients läuft ab. Der Client kann nicht erkennen, ob der Server die Anfrage nie bekommen hat oder ob er sie bekommen, ausgeführt und die Antwort auf dem Rückweg verloren hat.
Bei einem GET spielt diese Frage keine Rolle: Sende es noch einmal, und schlimmstenfalls liest der Server dasselbe Buch zweimal. Bei einem PUT oder einem DELETE spielt sie ebenfalls keine Rolle, weil eine zweite Kopie denselben Zustand hinterlässt wie die erste. Bei einem POST spielt sie eine große Rolle: Wenn die erste Anfrage angekommen ist, fügt ein erneutes Senden das Buch ein zweites Mal hinzu. Ein Client darf also eine sichere oder idempotente Anfrage nach einer verlorenen Antwort wiederholen und darf ein POST nicht wiederholen, ohne auf anderem Weg zu wissen, ob das erste angekommen ist. Kapitel 5 kommt darauf zurück: Dort akzeptiert dein eigener Server POST und PUT, und deine Tests zeigen, dass ein wiederholtes POST ein zweites Buch hinzufügt, während ein wiederholtes PUT nichts weiter ändert.
Ein Client sendet zweimal DELETE /books/7. Die erste Antwort sagt, dass es funktioniert hat und es nichts zurückzusenden gibt (204 No Content); die zweite sagt, dass es kein solches Buch gibt (404 Not Found). Ist DELETE hier idempotent?
Eine Methode wählen
Die Tabelle funktioniert auch andersherum: Geh von dem aus, was du erledigt haben möchtest, und wähle die Methode, deren Versprechen dazu passen. Etwas lesen ist GET, oder HEAD, wenn der Kopf genügt. Etwas unter einer URL ersetzen, die du schon kennst, ist PUT. Es entfernen ist DELETE. Etwas Neues hinzufügen, dessen URL der Server bestimmt, ist POST.
Welche Methode passt zu "füge der Liste ein neues Buch hinzu; der Server wählt seine Nummer"?
Die Methode ist das erste Wort der Anfragezeile. Das zweite Wort ist das Ziel, das du bisher von Hand eingetippt hast. Die nächste Lektion nimmt eine ganze URL auseinander und zeigt, wohin jeder ihrer Teile gehört.