Donnerstag, 12. November 2020, 07:23
REST vs. JSON vs. custom
Zwei eifrige Twitter-(aber noch-nicht Blog-)Leser hatten mich (privat) nach diesem Tweet nach ein paar Interna über unsere API gefragt - genauer gesagt, was wir intern als API-Format einsetzen. Gerne - Here we go.
Und da ich gestern ja schon meine Meinung über XML geschrieben hatte, tue ich das an dieser Stelle gerne auch für REST. So einfach eine REST-basierte API ja auf den ersten Blick ist, hat dieses "Format" in meinen Augen einige Schwächen.
Zum einen finde ich es gruselig, das Konzept von CRUD (Create, Read, Update, Delete) in http-Methoden (GET, POST, PUT, DELETE) zu packen. Auch wenn es für die meisten Fälle ausreicht, ist man dennoch irgendwie beschränkt. Und nicht alles lässt sich logisch matchen.
Das Ergebnis der API-Aktion in einen http-Fehlercode zu packen, finde ich ebenso unschön, um nicht wieder gruselig zu schreiben. Ich finde, man sollte klar zwischen Fehlercode auf Transport-Ebene (stimmt nicht ganz, aber nennen wir es mal so), und dem auf API-Ebene unterscheiden. Und demnach kann ein "200 OK" auf http-Ebene durchaus ein negatives API-Ergebnis enthalten.
Es gäbe jetzt durchaus bekannte Alternativen, eine davon ist JSON:API. Aber auch dieses Format halte ich für nicht wirklich praktikabel. Es bildet z.B. keinerlei Authorisation und Authentifikation ab. Und über das Layout kann man durchaus diskutieren, und evtl. auch schmunzeln.
Wir haben uns daher für uns intern für ein auf JSON basierendes Format entschieden, das Wert auf Praktikabilität und Sicherheit legt. Unter anderem war uns wichtig, interne API-Anfragen mit Keys zu signieren und diese gegen Replay-Attacken abzusichern.
Wie man nun die einzelnen JSON-Elemente nennt, ist dabei eher Geschmackssache. Wir haben uns hier intern etwas mit "auth", "action" und "payload" als Anfrage sowie "auth", "status" und "payload" als Antwort ausgedacht. Funktioniert sehr simpel, effektiv und ist dennoch sicher.
Vielleicht mag der ein oder andere, der auch etwas Eigenes implementieren möchte, sich ja daran orientieren.
Und da ich gestern ja schon meine Meinung über XML geschrieben hatte, tue ich das an dieser Stelle gerne auch für REST. So einfach eine REST-basierte API ja auf den ersten Blick ist, hat dieses "Format" in meinen Augen einige Schwächen.
Zum einen finde ich es gruselig, das Konzept von CRUD (Create, Read, Update, Delete) in http-Methoden (GET, POST, PUT, DELETE) zu packen. Auch wenn es für die meisten Fälle ausreicht, ist man dennoch irgendwie beschränkt. Und nicht alles lässt sich logisch matchen.
Das Ergebnis der API-Aktion in einen http-Fehlercode zu packen, finde ich ebenso unschön, um nicht wieder gruselig zu schreiben. Ich finde, man sollte klar zwischen Fehlercode auf Transport-Ebene (stimmt nicht ganz, aber nennen wir es mal so), und dem auf API-Ebene unterscheiden. Und demnach kann ein "200 OK" auf http-Ebene durchaus ein negatives API-Ergebnis enthalten.
Es gäbe jetzt durchaus bekannte Alternativen, eine davon ist JSON:API. Aber auch dieses Format halte ich für nicht wirklich praktikabel. Es bildet z.B. keinerlei Authorisation und Authentifikation ab. Und über das Layout kann man durchaus diskutieren, und evtl. auch schmunzeln.
Wir haben uns daher für uns intern für ein auf JSON basierendes Format entschieden, das Wert auf Praktikabilität und Sicherheit legt. Unter anderem war uns wichtig, interne API-Anfragen mit Keys zu signieren und diese gegen Replay-Attacken abzusichern.
Wie man nun die einzelnen JSON-Elemente nennt, ist dabei eher Geschmackssache. Wir haben uns hier intern etwas mit "auth", "action" und "payload" als Anfrage sowie "auth", "status" und "payload" als Antwort ausgedacht. Funktioniert sehr simpel, effektiv und ist dennoch sicher.
Vielleicht mag der ein oder andere, der auch etwas Eigenes implementieren möchte, sich ja daran orientieren.
Kommentare
Ansicht der Kommentare: Linear | Verschachtelt
Daniel
Für diese Art der Schnittstelle hast du natürlich einen OAuth2 provider für die nutzerautorisierung vorgeschaltet und prüfst dann übergebene tokens.
Bezüglich HTTP-Codes stimme ich dir eingeschränkt zu. Der HTTP COde ist natürlich nicht dein Applikationscode, sondern ist nur zur Einschätzung ob eine Anfrage geklappt hat. Wenn die Transaktion abgelehnt wird, dann dann gibst du einen 400er oder 500er Code zurück. Man kann weitere Informationen ja durchaus als Fehlercode innerhalb der Antwort zurückgeben.
Faustregel: Wenn eine Abfrage erfolgreich ist, dann sind eben 200er Codes, ansonsten nicht. Wenn du z.B. eine Rechteabfrage machst, dann kommt eben ein 200er Zurück, auch wenn du keine Rechte hast. Ist eben ein leeres Array mit Rechten; die Abfrage selbst hat ja geklappt.
Einige Anwendungen versuchen ein 1:1 Mapping zwischen HTTP Code und Applikationsstatus: Das machen wir explizit nicht.
Florian