Shownotes & Links
- Training “iSAQB Advanced Level Training WEB: Skalierbare Web-Architekturen”
- Information Management: A Proposal
- RFC 3986 für URI
- How DNS works
- Telnet
- Netcat bzw.
nc
- example.org
- curl
- Security Podcast: TLS
- WebSockets
- Server-sent Events
- Roy Fieldings Thesis
- REST und HTTP
- Brotli
- ETag
- HPACK: the silent killer (feature) of HTTP/2
- faucet-pipeline
- HTTP Server Push
- Client Hints
Transkript
Robert:
Hi und herzlich Willkommen zum INNOQ Podcast. Wir freuen uns, dass ihr alle dabei seid und zuhört! Ich bin der Robert und ich habe heute den Lucas bei mir. Und wir drehen den Spieß mal wieder um, denn üblicherweise moderiert der Lucas ja viele Folgen hier im INNOQ Podcast, aber heute muss er sich wieder meinen Fragen aussetzen. Hallo Lucas!
Lucas:
Hallo Robert!
Robert:
Hi! Schön, dass ich dich mal wieder dran habe. Wir machen das nicht einfach so, um den Spieß mal rumzudrehen, sondern du weißt tatsächlich glaube ich ganz schön viel zu dem Thema, was wir heute haben. Nämlich ‚das Rückgrat des Webs‘.
Lucas:
Ja, ich… würde ich jetzt auch mal behaupten, ist ja immer so schwer, das über sich selbst zu sagen. Ich habe mich auf jeden Fall schon viel mit dem Web beschäftigt, mache Webarchitektur und Webentwicklung jetzt seit vielen, vielen Jahren. Gebe da auch Schulungen zu, also sowohl in der Praxis als auch in der Theorie bin ich da glaube ich ganz gut aufgestellt.
Robert:
Ich wollte dich zum Anfang auch nur mal mit Lob überhäufen, um dich in Verlegenheit und Schamesröte zu treiben. Das ist mir auch gelungen, wie ich sehe, aber die Hörerinnen und Hörer sehen das natürlich nicht, weil wir hier audio only sind. Aber man konnte es wahrscheinlich auch hören. Cool! Ja, du hast schon gesagt, so ein kleiner Disclaimer vorab an alle, wir wollen ja transparent sein: Du machst bei uns… Du bist natürlich Consultant bei INNOQ, aber du gibst auch ein Training und das nennt sich ‚Skalierbare Webarchitektur‘, ne? Hattest du ja gesagt.
Lucas:
Genau.
Robert:
Und da gibt es, wenn euch das interessiert, wir verlinken das in den Shownotes. Da lernt man quasi all das, was wir heute nur anreißen können, weil das wirklich ein mega umfangreiches Thema ist, in der Tiefe in mehreren Tagen, online und vielleicht bald auch wieder vor Ort, hoffen wir alle mal. Wir verlinken das, da könnt ihr euch ein paar Infos zu angucken bei socreatory.com. Das ist unser neues Schulungsportal zusammen mit embarc. Also das machen wir als INNOQ mit embarc zusammen. So. Das vorab und jetzt erstmal meine… hätte ich fast gesagt, wichtigste Frage, aber das interessiert mich tatsächlich brennend, weil ich deine Kaffeetasse gerade gesehen habe und wir machen das ja unter uns zur Regel: Was hast du denn heute für einen Kaffee in der Tasse?
Lucas:
Tatsächlich ist mein Kaffee tatsächlich gerade leer und ich muss mir nach dieser Folge eine neue Tasse machen! Weil, ich habe heute Morgen etwas früher losgelegt und deswegen habe ich gerade gar nichts mehr in der Tasse. Es tut mir leid, Robert!
Robert:
Oh mein Gott!
Lucas:
Und du so?
Robert:
Ich hatte heute… es ist ja gerade Kenya Saison, deswegen hatte ich Kenya in der Tasse. Ich mag die ja persönlich sehr.
Lucas:
Ja, schmeckt auch gut.
Robert:
Schmeckt mir sogar besser als Äthiopien.
Lucas:
Ui, das ist aber ein großes Lob!
Robert:
Gut, dann sind wir alle kaffeeiniert. Wir hoffen ihr auch! Und dann geht es los! Lucas, wir haben gesagt: Die Folge heißt ja ‚die Grundlagen‘ oder ‚das Rückgrat‘ oder ‚das Backbone des World Wide Webs‘. Was ist denn das eigentlich so? Also gibt es da ein Rückgrat wie beim Menschen oder gibt es da vielleicht so mehr? Was macht das Web denn eigentlich aus?
Lucas:
Genau, also ich würde sagen das ist ein ganz kurioses Rückgrat aus drei Säulen. Also nicht ganz wie bei Menschen. Und wenn man so auf die Anfänge des Webs zurückschaut, dann hat das alles begonnen mit diesem Paper oder diesem Proposal, was Tim Berners-Lee geschrieben hat ‚Information Management: A Proposal‘. Klingt ja wirklich sehr bescheiden für eine extrem große Revolution. Und eigentlich vom Anfang an gab es drei Sachen oder drei Standards oder drei Aspekte, die wesentlich sind fürs Web und die das auch bis heute ausmachen. Und das sind aus meiner Perspektive: HTML, HTTP und URLs. Das sind so diese drei Sachen, die gemeinsam geboren sind quasi und die bis heute so die Grundlage bilden. Also klar, es wurde viel ergänzt über die Zeit: CSS, JavaScript und viele, viele weitere Sachen. Aber auch bis heute sind diese drei Sachen einfach essentiell dafür.
Robert:
Okay. Das heißt vorher… wissen wir alle vielleicht noch, falls wir Informatik studiert haben, aber es hören ja noch viele andere Menschen zu. Aber man hat es vielleicht schon mal gehört: Es gab das Internet ein bisschen länger als das World Wide Web, ne?
Lucas:
Genau, das ist richtig! Also auch wenn wir jetzt nachher nochmal auf die Protokolle eingehen, dann ist quasi das Web… also das HTTP-Protokoll ist quasi ein Protokoll, was auf den Protokollen des Internet also TPC/IP und TCP/UDP aufbaut. Also dass dementsprechend, wenn man das als Venn-Diagramm betrachtet, ist quasi das Web ein Teil von dem großen Internet. Also Mails sind zum Beispiel Internet, aber kein Web.
Robert:
Okay. Wir sprechen heute zu dem Thema, weil wir uns vorher schon mal zu zweit überlegt haben, dass wir da unbedingt mal was zu senden wollen, weil das eben so wichtig ist. Weil viele von uns, die zuhören, viele bei uns in der Firma… aber wir wollen nicht lügen, der Markt ist heute bestimmt von Webentwicklung. Die Anzahl der nativen Anwendungen, die man auf irgendwelchen PCs, MACs, was auch immer für Geräten installieren muss und wo dann Byte-Code ausgeführt wird… also die gibt es noch. Die haben auch ihre Bewandtnis, aber immer mehr wird ins Web verlagert. Weil, glaube ich, die Vorteile liegen auf der Hand. Das ist universell, ich kann sowohl reine Informationen dort publizieren sowohl als auch interaktive Anwendungen und da macht sich auch ein ganz großes Spektrum auf. Also wir haben heute Sachen, da hätte man vor zehn Jahren nicht mal im Traum dran gedacht. So eine Art Photoshop im Web jetzt machen zu können, ne? Das ist heute möglich, aber es gibt weiterhin einfach das andere Ende des Spektrums von einfach informativen, dokumentartigen Seiten, wo nicht viel interaktive Aktivität ist. Das ist alles möglich und das zeigt so ein bisschen, wie mächtig eigentlich dieses Konstrukt Web ist. Und deswegen haben wir gedacht wir machen da mal eine Folge zu und erörtern das mal so ein bisschen. Weil das einfach auch unglaublich wichtig ist für Softwarearchitektur, Softwareentwicklung und Produktentwicklung, dass man weiß, in welchem… ja, Ökosystem man sich denn dann bewegt und es kann nicht schaden, da ein bisschen tieferes Verständnis für zu haben.
Lucas]:
Absolut!
Robert:
Genau und jetzt hattest du gesagt, es gibt eigentlich drei Backbones, ne? HTTP, URLs und HTML. Wie kommt denn jetzt HTTP eigentlich… also wie ist HTTP damals in das bestehende Internet, das es ja schon gab mit ein paar Features, würde ich mal behaupten, wie kommt denn das da drauf? Hat das Tim Berners-Lee dann auf TCP draufgeflanscht oder wie funktioniert das technisch?
Lucas:
Genau, also das würde ich sagen stimmt so. Also wenn wir uns so das… Es gibt ja dieses OSI-Schichtmodell und blah, blah, blah, das hat jetzt in der Praxis wenig Relevanz, würde ich jetzt mal behaupten. Aber es gibt schon so vier Schichten grob, die Relevanz haben. Also die unterste Schicht ist diese ganze physikalische Verbindung zwischen Geräten. Also da sind jetzt sowas wie Ethernet-Standards, aber auch sowas wie die Wifi-Standards oder sowas wie 3G, 4G, Mobilfunk-Standards. Wo einfach erstmal, wie kommen Signale von einem Punkt zum anderen? Das ist etwas, davon habe ich überhaupt gar keine Ahnung. Da müsst ihr irgendwen anders zu befragen, das weiß ich nur ganz oberflächlich, wie das funktioniert. Darauf aufbauend gibt es dann halt das Internet-Protokoll, das ist tatsächlich dann das Internet. Das ist halt ein Protokoll, um Verbindungen herzustellen, um Pakete von einem Ort zu einem anderen zu bringen. Und darauf aufbauend gibt es dann traditionell zwei Protokolle zu Auswahl. Das eine heißt TCP und das andere heißt UDP. Und das ist das, womit wir als Softwareentwickler und -entwicklerinnen eigentlich meistens am ehesten noch Verbindungspunkte haben. Alles da drunter ist so low level, dass ich das jetzt auch mal für diesen Podcast einfach ignorieren würde. Und bei TCP und UDP, da ist es dann tatsächlich so, da bauen wir halt eine Verbindung von einem Computer zu einem anderen auf und dieser ganze Apparat da drunter, der kümmert sich da drum, dass die ganzen Zwischenstellen, die wir dafür überbrücken müssen, um diese Pakete von einem Ort zu einem anderen zu bringen auch wirklich ankommen. Also das ist ein ganz schön kompliziertes Ding, aber das ignorieren wir jetzt einfach mal. Und bei TCP und UDP muss man einfach grob unterscheiden: Das TCP ist halt ein verlässliches Protokoll und UDP ist ein unverlässliches Protokoll. Was bedeutet das? Das bedeutet, dass bei TCP sichergestellt wird, dass wenn ich dir ein Paket schicke, dass es auch ankommt und dass wenn es nicht ankommt, ich das bemerke und das dir nochmal schicken kann. Und wenn es dann nach einer bestimmten Anzahl von Versuchen immer noch nicht funktioniert, dann sagen sie: ‚Sorry, das funktioniert einfach nicht.‘. Und das ist bei UDP nicht so, da schieße ich einfach Nachrichten rüber und wenn sie ankommen, kommen sie an und wenn sie nicht ankommen, dann kommen sie nicht an. Und das Web ist ein… Also HTTP ist jetzt ein Protokoll, was auf diesem Level aufbaut, ein Applikationsprotokoll und dieses Protokoll geht erstmal davon aus, dass sich die Schichten da drunter darum kümmern, dass es eine verlässliche Kommunikation ist. Also das keine Daten verloren gehen. Das heißt HTTP selbst guckt jetzt nicht: Ist mein Paket angekommen? Es geht einfach davon aus das hat funktioniert, weil da haben sich die Sachen da drunter drum gekümmert. Und genau das hat sich der Tim Berners-Lee dann halt überlegt, so ein Protokoll und diese erste Version davon, das war einfach ein plain text Protokoll, das er sich überlegt hat. Quasi so eine Konversation und da kommen wir auch in so ein Thema ‚Client/Server‘ irgendwie. Also wir haben einen Client, das bin ich. Ich möchte irgendeine Information von einem Server bekommen und da liegen die Informationen. Das heißt ich baue eine Verbindung zu dem Server auf, ich schicke irgendetwas zu diesem Server hin und er antwortet mir. Ja, das ist dieses grundlegende Client/Server-Prinzip.
Robert]:
Okay. Nun ist es aber so, wenn ich als Entwicklerin oder Entwickler irgendwie eine Seite ins Netz stelle, zum Beispiel für eine Impftermin-Buchung, kann ich denn da überhaupt entscheiden: Nehme ich jetzt TCP oder UDP? Ich könnte ja sagen: ‚Ey, diese Impftermin-Reservierung, da möchte ich bitte, dass die Pakete wirklich hier ankommen bei mir und das möchte ich sicherstellen. Also nehme ich TCP.‘. Und bei UDP, das würde ich wahrscheinlich eher benutzen, wenn ich… weiß ich nicht, als Server dem Client irgendwie eine Stunde Video schicke. Und da ist es nicht schlimm, wenn mal ein paar Pixel nicht ankommen. Da muss ich nicht für jedes Paket sicherstellen, dass das auch bei dir als Client ankommt. Aber ich glaube, ich kann das ja als Entwickler:in gar nicht bestimmen, was für ein Protokoll da unter der HTTP-Haube verwendet wird, oder?
Lucas:
Genau, das kannst du tatsächlich nicht beeinflussen. HTTP ist, wie gesagt, basiert eigentlich immer auf einem verlässlichen Protokoll. Also immer auf etwas wie TCP. Es gibt neuere Entwicklungen, da können wir auch später drauf eingehen, die ein anderes Protokoll unten drunter verwenden. Das Stichwort da ist ‚QUIC‘, aber auch das ist ein verlässliches Protokoll, bei dem keine Daten verloren gehen. Wenn du jetzt sowas wie Videostreaming machen möchtest, wo man… Also Live-Streaming von Video, wo man eher so ein unverlässliches Protokoll verwendet, da kann man sich ja vorstellen, wenn ich jetzt dir ein Video zuschicke und ein paar Frames werden fallen gelassen, dann wackelt zwar das Bild mal kurz, aber du bist immer noch live. Wenn das ein verlässliches Protokoll wäre, würdest du ja quasi immer weiter in der Zeit zurückdriften. Also immer, wenn Pakete verloren gehen, müsstest du ein bisschen warten und dann würde es immer weiter hinterherhängen. Und das ist etwas, was HTTP nicht mehr kann. Also es ist einfach nicht mehr Teil von HTTP, dafür brauchen wir andere Protokolle. Das sind auch Protokolle, die der Browser teilweise versteht, aber das ändert nichts daran, dass das nicht mehr HTTP ist. Das sind einfach andere Protokolle, die da verwendet werden.
Robert:
Okay. Das Protokoll, das wir hier verwenden, ist offenbar ein verlässlich unzuverlässiges, denn ich sehe dich sehr breiig und pixelig. Wir sehen uns hier, während wir das aufnehmen.
Lucas:
Genau!
Robert:
Und offenbar nimmt unsere Tonaufnahme so viel Bandbreite in Beschlag, dass der Server denkt, er müsste mir nur noch Lucas in zehn Pixeln schicken.
Lucas:
Also ich vermute, dass diese Software auf WebRTC aufbaut und das ist eben ein UDP-basiertes Protokoll. Genau!
Robert:
Okay. Das haben wir doch… Dann verstehe ich das jetzt etwas besser. Okay. Aber nochmal zurück zu den Säulen. Jetzt wissen wir so ein bisschen was unter HTTP drunter schlummert und seine Dienste tut. Entweder zuverlässig oder auch mal unzuverlässig. Aber was sind denn jetzt URLs? Also ich… Das ist so ein bisschen eine rhetorische Frage, weil ich glaube: alle, die hier zuhören, haben schon mal eine URL gesehen oder eingetippt oder sogar ‚Enter‘ gedrückt. Da gehe ich jetzt mal ganz, ganz fest von aus. Und wir haben vielleicht auch alle den Begriff schon mal gehört. Das ist ja eher der technische Begriff, meistens, was man so ‚Internetadresse‘ oder ‚Seitenadresse‘ oder einfach ‚Adresse‘ nennt. Wenn ich mir so eine URL angucke, dann steht ja da ganz am Anfang auch das Protokoll, was verwendet wir, drinnen, ne? http
oder jetzt halt https
immer öfter, Gott sei Dank. Wie funktioniert denn das technisch? Also wenn ich jetzt zum Beispiel https://www.innoq.com eintippe, was passiert da eigentlich? Also wie wird diese URL… Wer löst die auf? Und wer erkennt das Protokoll? Und wer weiß dann welches Dokument aufgerufen werden muss? Das würde ich gerne nochmal auseinanderdröseln.
Lucas:
Ja, also der Browser, der spricht ja, wie ich schon angedeutet habe, verschiedene Protokolle. Aber das wichtigste ist auf jeden Fall HTTP beziehungsweise HTTPs und wenn er sich jetzt so eine URL anguckt… Also eine URL ist einfach wieder ein Standard. Da müssen wir ganz kurz nochmal auf das RFC eingehen. Also RFC sind diese Standarddokumente, die herausgegeben werden, wo zum Beispiel das ‚was ist eine URL?‘ standardisiert wird oder ‚was ist HTTP?‘. Das ist da durchstandardisiert und es gibt halt einfach ein RFC und da drin steht: ‚was ist eine URL?‘. Und URL ist im Prinzip ein Format. Das ist also… man kann sich vorstellen, ein großer regulärer Ausdruck, alles wo er sagt: ‚Ja, das ist so!‘, das ist eine URL und alles, wo er sagt: ‚Nein!‘, ist keine URL. Und die URL, die hat halt verschiedene Bestandteile und für uns jetzt in diesem Podcast das wichtigste sind quasi zwei Teile. Das eine ist das, was man Authority nennt. Das ist quasi der Server, mit dem wir sprechen wollen und alles, was dahinter kommt. Das ist das, was wir anfragen wollen. Also wir wollen jetzt bei innoq.com einen bestimmten Blogpost lesen, dann ist die Authority www.innoq.com und dann ist der Pfad halt irgendwie articles…blah, blah, blah. Und das ist auf jeden Fall was, das der Browser schonmal in zwei Teile teilt. Das heißt der guckt sich erstmal die Authority an und dann später guckt er sich den Pfad an. Weil, er muss jetzt erstmal verstehen: Mit welchem Server muss ich sprechen? Und da sind wir wieder auf dieser TCP-Ebene. Das heißt er muss jetzt irgendwie herausfinden, welche IP-Adresse ist das denn? Weil www.innoq.com ist ja keine IP-Adresse. Also gibt es dafür ein System, das ist das Domain Name System. Das ist ein eigenes Protokoll. Das ist also auch ein Applikationsprotokoll, was auf TCP oder UDP aufsetzt. Was also neben HTTP steht, deswegen erkläre ich das nur ganz kurz. Also man sagt halt hier: www.innoq.com und der sagt mir: Das ist die IP-Adresse, mit der du sprechen musst. Details ignorieren wir jetzt einfach erstmal und dann habe ich…
Robert:
Das würde wahrscheinlich einen eigene Podcast-Folge rechtfertigen.
Lucas:
Genau! Das würde ich auch behaupten, ja. Weil da steckt auch viel hinter, aber da hat sich auch viel verändert.
Robert:
Okay. Aber DNS ist in Kurzform: Ich sage dir: ‚Geh mal beim Lucas den gelben Eimer holen!‘ und niemand weiß, wo Lucas wohnt. Deswegen muss man erstmal im Telefonbuch gucken, wo wohnst du eigentlich? Und dann kriegt man Straße und Hausnummer und DNS tut genau das für den Browser, ne?
Lucas:
Genau!
Robert:
innoq.com hat folgende IP-Adresse und guck doch da mal nach. Und schick da deine TCP-Pakete hin.
Lucas:
Genau!
Robert:
Das macht DNS in ultrakompakter Form wahrscheinlich.
Lucas:
Genau. Genau das ist es und dabei ist wichtig zu betonen, dass DNS eine Technologie ist, die nicht nur für das Web benutzt wird, sondern auch für ganz viele andere Sachen. Also beispielsweise für den Mailversand. Das wäre auch etwas, wo DNS eben zum Einsatz kommt, wo wir aber nicht über Web sprechen. Das heißt also es ist eine separate Technologie, aber die wird verwendet, um jetzt erstmal herauszufinden: Was ist denn die wirkliche IP-Adresse? Damit ich als Browser da meine Pakete hinschicken kann. Und wenn ich das jetzt getan habe, dann habe ich jetzt eine IP-Adresse. Dann baue ich dahin jetzt erstmal eine Verbindung auf, so eine TCP-Verbindung. In dem traditionellen Fall, wir kommen später zu dem nicht mehr traditionellen Fall. Und dann kann ich anfangen da Nachrichten hinzuschicken und das ist der Punkt, wo HTTP beginnt. Das ist der Teil, wo wir über HTTP sprechen. Weil das Protokoll, das wir jetzt mit diesem Server irgendwie ermittelt haben, sprechen, das ist HTTP.
Robert:
Okay. Das heißt… Also mir scheint das, als hätten wir jetzt mal kurz den Kopf unter die Wasseroberfläche gehalten. Da sind aber noch ein paar Meter Tiefe durchzutauchen, fürchte ich.
Lucas:
Genau!
Robert:
Also ich glaube man sieht schon… Also was alleine unter dieser Oberfläche schlummert. Was wir täglich eine Millionen Mal benutzen, wenn wir irgendwelche URLs eintippen und ‚Enter‘ drücken, das ist… da denkt man immer so nicht dran. Und wenn man… für viele von uns klingt das glaube ich trivial, ja gut, wir haben das alle mal im Studium gemacht oder wir entwickeln jetzt eh schon lange Webanwendungen. Aber manche behaupten ja, es ist auch eine interessante Frage für ein Vorstellungsgespräch: ‚Was passiert eigentlich, wenn man im Browser ‚Enter‘ drückt?‘. Denn die ganze Komplexität und das ganze Schmalz, was da drunter schlummert, ist nicht ohne, ne?
Lucas:
Genau!
Robert:
Okay, aber jetzt sind wir… jetzt haben wir gesagt, wie das funktioniert, wenn jemand innoq.com/blog/noch-tollerer-blogpost aufruft. Wir suchen mal irgendeinen schönen für die Shownotes raus, dann können alle das üben. Genau, der Name der Authority wird aufgelöst, man bekommt eine IP zurück und der Browser weiß: Da kann ich jetzt TCP-Pakete hinschicken. Was steht in diesen TCP-Paketen drin? Du hast gesagt jetzt kommt HTTP zum Tragen. Was schickt der Browser da genau?
Lucas:
Genau. Also wenn wir das HTTP bis 1.1 verwenden, dann ist das ein plain text Format. Das bedeutet, dass wenn ich als Mensch diese Nachricht lese, dann kann ich die tatsächlich lesen. Also ich brauche keine Software, die mir das irgendwie dekodiert oder so, sondern das ist tatsächlich einfach plain text. Und so ist das Protokoll am Anfang designed gewesen. Also es ist ein sehr einfaches, sehr lesbares Protokoll, über das wir da sprechen. Und wenn ich jetzt als Client mit dem Server Kontakt aufnehme, dann schicke ich einen sogenannten HTTP-Request hin und das ist eine Nachricht, die ein bestimmtes Format hat und die besteht im Prinzip aus einer HTTP-Methode, dem Pfad, den ich auflösen will… da sind wir nochmal ganz kurz bei den URLs. Das ist quasi der rechte Teil, das ist jetzt der Pfad von meinem Blogpost. Weil, ich weiß ja jetzt schon mit welchem Server ich spreche, aber jetzt muss der Server wissen über welchen Blogpost ich spreche. Und dann kommt ein Block, das sind die sogenannten HTTP-Header und ich würde so behaupten, das ist so der Kern des HTTP-Protokolls. Das ist das, was das HTTP-Protokoll ausmacht. Und dann kommt eine Leerzeile und dann kommt ein Body. Und der Body, das ist quasi eine Nachricht, die ich an den Server schicke. Wenn ich jetzt also Informationen an den Server übermitteln möchte, wie zum Beispiel ‚ich habe ein Formular ausgefüllt‘, dann steht die das in dem Body drin. Oft ist der Body aber auch einfach leer. Also wenn ich jetzt einfach nur das Beispiel nehme, worüber wir gerade gesprochen haben: Ich drücke ‚Enter‘ in meiner Browserzeile, nachdem ich da eine URL eingetippt habe. Dann ist das ein leerer Beutel, da steht einfach gar nichts drinnen. Und das ist also optional. Ja, genau.
Robert:
Und um auszudrücken was ich von dir will als Client… Also du bist jetzt der Server, ich bin der Client, muss ich ja noch sogenannte Verben benutzen in meinem HTTP-Request und sagen ich möchte eben ein ‚GET‘ machen, also ich möchte etwas von dir bekommen. Da hast du gesagt, da ist der Body typischerweise leer, weil ich alles, was ich eben haben will von dir, rein in den Headern beschreiben kann, ne?
Lucas:
Genau! Also fast schon nur in dem Pfad. Also wenn ich jetzt einen… Also so eine Message, wenn man die jetzt vorlesen würde, die kann man tatsächlich auch verstehen. Das wäre jetzt: GET /articles/roberts-article HTTP/1.1
. Das wäre dann quasi die erste Zeile, die wir tippen können. Also das können wir auch, wenn wir mit Telnet eine Verbindung aufbauen, würde das auch funktionieren, wenn da nicht diese lästige Verschlüsselung wäre. Können wir auch gerne nochmal drüber sprechen. Aber grundsätzlich…
Robert:
Moment! Da muss ich nochmal einhaken!
Lucas:
Okay.
Robert:
Telnet. Was ist Telnet? Ich habe das mal im Studium gehört. Was tut das? Das ist doch… Ist das ein Programm, was ich auf meinem Computer starten kann und das macht dann eine TCP-Verbindung auf? Und…
Lucas:
Genau!
Robert:
Also was passiert da? Wie kann ich das nachvollziehen?
Lucas:
Genau, also ich verwende heutzutage eher netcat, das ist aber sowas ähnliches wie Telnet. Das ist jetzt wirklich Detail. Grundsätzlich baut das einfach eine Art TCP-Verbindung zu einem Server auf. Und dann kann ich anfangen, da Nachrichten hinzuschicken und kriege auch die Nachrichten zurück. Das heißt also, wenn ich beispielsweise eine Telnet oder netcat Verbindung zu example.org aufbaue, dann kann ich da tatsächlich einfach reintippen in Telnet: GET HTTP/1.1 und dann kriege ich quasi example.org zurückgeschickt. Ich sage example.org, weil das halt eine einfache Webseite ist, die auf diese Art und Weise ohne Verschlüsselung und so weiter geholt werden kann. Weil Telnet und netcat können keine verschlüsselte Verbindung aufbauen.
Robert:
Interessant! Das heißt, ich kann theoretisch auf ultra niedrigem Level das nachvollziehen und mal selber händisch eintippen, was so ein Browser eigentlich immer für mich macht, ne?
Lucas:
Genau! Das wäre quasi noch niedriger als das Tool cURL, was vielleicht auch schon viele mal benutzt haben. cURL ist ja auch so ein Command-line-Tool, mit dem ich von der Command-line ein HTTP-Request aufmachen. Das ist aber eine Ebene höher, weil cURL versteht halt schon HTTP und Telnet und Konsorten verstehen halt kein HTTP, sondern die verstehen nur TCP und alles was ich jetzt an HTTP machen möchte, muss ich halt von Hand machen. Aber das ist absolut möglich, ich kann diese Verbindung aufbauen. In unserer Schulung machen wir das auch immer als eine kleine Demo, um das auch nochmal ein bisschen zu entzaubern. Kann man halt sehen, dass das wirklich funktioniert, dass man einfach so eine Verbindung selber aufbauen kann. Man kann mit so einem Tool… also Telnet kann das nicht, aber netcat kann das beispielsweise, kann man auch den Server darstellen. Das heißt da würde man tatsächlich einfach sich öffnen für eine Verbindung und dann kann sich jemand dahin connecten und wir können auch antworten. Also das ist zum Beispiel mit netcat möglich, da ist sowohl der Client als auch ein Server.
Robert:
Cool, das probiere ich auch mal aus. Besonders der Tipp mit example.org ist glaube ich gut, weil ja super viel, Gott sei Dank, heute auch verschlüsselt ist. Und du hattest gesagt, dass wenn ich das jetzt auf diesem niedrigen Level mit Telnet oder netcat probieren würde, dann bekäme ich eben keine… ja, keine HTTP geparste Antwort zurück. Also ich würde mit Telnet eine HTTPs-verschlüsselte Seite aufrufen und dann kommt da nur für mich unlesbarer Quatsch zurück, weil ich eben diese Entschlüsselung noch leisten müsste, ne?
Lucas:
Genau! Also wir können da nochmal ganz kurz drauf eingehen, einfach nochmal… Wenn wir nochmal an unsere Schichten von eben denken, dann: HTTP ist ein unverschlüsseltes Format, auch in den neuesten Versionen davon. Weil HTTP davon ausgeht, dass bestimmte Aspekte in der Ebene da drunter geregelt sind. Also beispielsweise diese Verlässlichkeit wird da drunter geregelt, aber auch Verschlüsselung wird da drunter geregelt. Das heißt also, wenn ich eine Verbindung aufbaue und ich tippe ‚https‘ ein, dann ist das auch dasselbe HTTP-Protokoll. Das hat sich nicht verändert, also ist genau das gleiche Protokoll. Der Unterschied ist nur, dass ich keine TCP-Verbindung aufbaue, sondern eine TCP-TLS-Verbindung. Das heißt also, das ist eine verschlüsselte TLS-Verbindung. Das heißt, wenn ich mit example.org verschlüsselt kommunizieren will, dann würden trotzdem dieselben Nachrichten hin und her geschickt werden, nur dass diese Nachrichten halt auf dem Transportweg verschlüsselt sind. Aber das ist wirklich dann ein Thema, da gibt es auch schon INNOQ Security Podcast Folgen zu, wie TLS funktioniert. Das geht jetzt weit über das hinaus, was wir heute besprechen wollen. Wir gehen einfach davon aus, das ist verschlüsselt.
Robert:
Die können wir ja verlinken.
Lucas:
Genau. Das können wir gerne machen.
Robert:
Okay. Aber an example.org könnt Ihr es unverschlüsselt einfach mal probieren, wie so ein… Also den Request tatsächlich wie ein Steinzeitmensch mit den Händen einzutippen.
Lucas:
Genau.
Robert:
Aber ich glaube da lernt man viel, ne? Ich habe das auch mal probiert. Man kann es auch ja immer in den Browsern, in den DevTools und wie sie alle heißen, unten in dieser Leiste nachvollziehen, indem man einfach die Seite nochmal neu lädt und dann im Network Tab die oberste Zeile anklickt und dann kriegt man glaube ich 2–3 Tabs, wenn nicht sogar mehr. Und zwei davon sind Request/Response und da kann ich mir auch nochmal die Header angucken und den HTTP-Request, den der Browser, Chrome/Firefox, was auch immer, jetzt eigentlich für mich geschickt hat und eben den Response, den der Server mir geantwortet hat. Und da sind wir jetzt wahrscheinlich schon im Schmalztopf des Pudels. Ich glaube dieses… Im Kern des Pudels ankommen. Nämlich der Request-Response-Zyklus, so habe ich mal gehört nennt sich das. Also heißt das, dass alle meine Aufrufe und meine gesamte Kommunikation im Web immer in so einer Klammer abläuft? Request, Response, Request, Response? Ist das so?
Lucas:
Ja, das ist so! Grundsätzlich ist HTTP ein Request/Response-Protokoll. Das heißt, der Server kann uns nicht einfach eine Antwort schicken, ohne dass wir danach gefragt haben. Das ist nicht möglich. Deswegen gibt es halt so Protokolle, wie beispielsweise WebSockets, von denen haben bestimmt auch schon viele gehört. Das ist ein Protokoll, wo quasi beide Seiten einfach jederzeit eine Nachricht schicken können. Also so Vollduplex-Protokolle, wie auch immer man das nennen möchte. Und das bedeutet halt auch, dass WebSockets basieren halt… sind halt wirklich etwas separates. Es ist ein eigener Standard, es ist eine eigene Welt. Wir können mit HTTP ein bisschen tricksen und dafür sorgen, dass der Server uns selber Antworten schicken kann, ohne dass wir weitere Fragen gestellt haben. Können wir gerne auch später nochmal drüber reden, aber grundsätzlich ist es immer: Ich schicke irgendeine Frage und der Server antwortet mir. Das ist… Und wenn ich etwas Neues will, dann stelle ich wieder eine Frage und dann antwortet mir der Server. Das ist das grundlegende System dahinter.
Robert:
Okay. Da merkt man auch so ein bisschen an dieser architektonischen Entscheidung, das Web war wahrscheinlich mal für dokumentartige Informationsabrufe konzipiert. Also ich möchte mich über… weiß ich nicht, Nachrichten informieren, rufe diese URL ab. Ich folge einem Link, rufe wieder ab und schicke mir den Response. Und so über die Links folge ich immer weiter und da passiert ja eigentlich immer das gleiche in dieser Request/Response-Klammer, ne?
Lucas:
Genau. Da ist es halt auch das, was ich eben meinte, dass diese drei Technologien, also HTML, HTTP und Adressen sind halt… gehören halt eng zusammen. Weil wenn ich halt auf so einen Link draufklicke… Der Link ist ja ein Teil von HTML, aber das, was dann passiert ist, dass ein HTTP-Request ausgelöst wird. Also wenn ich auf einen Link klicke, dann machen wir wieder einen Request und kriegen wieder eine Response zurück. Und der Browser ersetzt quasi den Inhalt von dem, was er gerade anzeigt durch den der gerade gekommen ist. Und genauso Formulare: Machen einen HTTP-Request und man bekommt eine Antwort zurück. Das ist das gleiche System.
Robert:
Okay. Aber wir haben es so ein bisschen… Du hast das schon angedeutet: Wenn ich mehr tun will in meiner Webanwendung, die ich vielleicht in meinem Produkt, als statische Informationsseiten auszuliefern, dann kann ich da an Grenzen stoßen mit diesem Request-Response-Cycle, oder? Tue ich da schnell oder kann man eigentlich… Also werden wir mal konkret: Was ist denn mit einem Chat? Ich will einen Chat bauen: www.roberts-toller-chat.de und Chat klingt für mich so wie das totale Anti-Feature für die Architektur in einem Request-Response-Cycle. Weil, ich hänge ja in dem Chat und klar, manchmal will ich eine Nachricht schreiben, dann würde ich wahrscheinlich einen HTTP POST an den Server schicken mit meiner Nachricht. Aber ich will ja nicht immer GET neue Chatnachrichten abrufen, um zu sehen, wer hat denn jetzt sonst was in dem Chat geschrieben. Oder wie kriegt man das auf diese Architektur gemappt? Oder sprengt diese Art von Anwendung schon das… ja, nicht das Internet, aber vielleicht die Webarchitektur?
Lucas:
Ja, also ich glaube, dass das viele, die das entwickeln, sehen das so, dass das die Grenze wäre, wo man nicht mehr auf HTTP zurückgreifen sollte. Das ist einer der Gründe warum WebSockets entwickelt wurde, weil das eben genau das zulässt. Wir können halt eine WebSocket-Verbindung zu einem Server aufbauen und dann kann der uns jedes Mal, wenn irgendjemand anderes eine neue Nachricht im Chat geschrieben hat, kann der uns die einfach direkt zuschicken. Ohne dass wir jetzt dauernd nachfragen müssen, das wäre ja das, was man jetzt als Polling bezeichnet. Also wo man dann immer wieder fragt: Und gibt es etwas Neues? Gibt es etwas Neues? Das wäre Polling. Es gibt auch eine Alternative dazu, das wäre: Ich baue eine Verbindung zum Server auf und sage: ‚Bitte gib mir Nachrichten!‘ und der Server schickt mir die Nachrichten, die er gerade hat, schon mal alle zu. Und lässt dann aber die Verbindung offen und wenn eine weitere Nachricht kommt, schickt er über dieselbe Verbindung die nächste Nachricht. Das nennt man dann auch Server-sent Events, das ist wieder ein Standard, der auf HTTP aufsetzt, um genau so etwas zu tun. Ich habe auch mal einen Beispielchat gebaut, der genauso funktioniert. Der also eben nicht WebSockets benutzt, sondern der einfach, wie du gesagt hast: Wenn du eine neue Nachricht schreibst, macht der einen POST auf dem Server und wenn… Aber im Hintergrund ist halt einfach so ein Server-sent Event-Stream offen und immer, wenn eine neue Nachricht kommt, dann kommt der durch den Stream zurück. Das ist auf GitHub, kann ich auch gerne in die Shownotes verlinken. Da kann man das nochmal angucken…
Robert:
Das ist ja vielleicht mal interessant! Dass man sieht, wie man so eine Architektur dann hinbekommen könnte.
Lucas:
Genau! Ja, aber man muss das ja auch nicht immer alles auf Gedeih und Verderb da drauf mappen. Es gibt gute Gründe, warum viele von den Chatanbietern, wie jetzt Slack und so weiter eher auf WebSockets setzten. Aber grundsätzlich ist das wirklich ein sehr flexibles Format oder ein flexibles Protokoll mit dem wir extrem viele Use Cases abbilden können. Also oft wollen wir ja nicht einfach irgendwelche Nachrichten bekommen ohne danach gefragt zu haben, sage jetzt mal ganz pauschal.
Robert:
Ja, das stimmt. Okay. Dann sind wir schon in so eine architektonische Sonderlocke vorgedrungen, wo wir so die eigentliche Klammer Request-Response-Cycle verlassen müssten, um unsere Anwendungen eben universell im Web bereitzustellen. Aber lass uns doch nochmal so einen Schritt zurückgehen, du hast ja gesagt, dass in… also in HTTP die Header eine besondere Rolle spielen. Also wir haben jetzt das Verb kennengelernt, den Pfad und dann hast du gesagt kommen Header und letzten Endes der Body. Der Body ist ja meistens leer, wenn ich nur etwas anfrage mit GET, aber er ist meistens befüllt, wenn ich etwas zurückbekomme im Response. Aber ich kann den Body auch selber füllen, wenn ich beispielsweise ein Formular abschicke.
Lucas:
Ja.
Robert:
Was machen denn die Header genau? Also was passiert da?
Lucas:
Genau, also die Header sind wirklich etwas total einfaches, aber dadurch sehr flexibles. Und das ist eigentlich nur so ein Key/Value-Pair. Genauso wie so ein Dictionary in Python oder ein Hash in Ruby oder ein Object in JavaScript, das ist einfach eine Menge von Key/Value-Pairs und die beschreiben irgendetwas über meinen Request. Und wir kommen gleich auch dazu, das gleiche gibt es auch in der Response. Da gibt es halt die Response Header, das sind auch genau die gleiche Datenstufe. Das heißt HTTP sagt jetzt grundsätzlich erstmal: Es gibt so etwas wie Header und die kann ich halt mitschicken. Und dann kann der Server die interpretieren und HTTP standardisiert direkt auch eine ganze Menge von Headern mit. Die sind dann also… Die können dann alle, die HTTP verstehen können, diese Header, aber man kann auch sich weitere Header ausdenken und ergänzen. Und manche neue Header sind auch dadurch entstanden, dass Leute sich quasi einen Header überlegt haben und der wurde dann später standardisiert. Sowas kann auch passieren. Das heißt also grundsätzlich ist das wirklich was ganz einfaches, einfach nur Key/Value-Pairs.
Robert:
Okay. Das heißt ich könnte auch selber einen erfinden. Ich könnte auch sagen ‚Preferred coffee: Kenya‘ in meinem…
Lucas:
Genau. Absolut, das könntest du tun. Und du könntest den jetzt auch einfach an example.org schicken und example.org würde sagen: ‚Komischer Header! Aber kenne ich nicht, ignoriere ich!‘. Weil der… Also HTTP grundsätzlich davon ausgeht, dass die andere Seite vielleicht Teile des Standards nicht kennt oder du dir halt selber wirklich etwas ausgedacht hast. Das heißt das geht nicht kaputt, wenn du was rüberschickst, was die andere Seite nicht kennt.
Robert:
Okay. Was sind denn Header, die vielleicht sogar standardisiert sind, die man immer wieder sieht und die ich vielleicht auch beachten muss? Wenn ich jetzt zum Beispiel in Telnet meinen Request, mein GET Request an example.org schicke, muss ich bestimmte Header setzen? Also eintippen oder kann ich die alle weglassen?
Lucas:
Genau, also es gibt einen Header, den müssen wir tatsächlich immer setzen. Zumindest wenn wir mit einem… mit so einem Server im Internet sprechen und nicht mit unseren localhost und das ist der Host header. Der Host header, das ist so ein bisschen merkwürdig irgendwie, wenn man nochmal sich dran erinnert, wir haben ja die URL eingetippt und jetzt hat der Server… Also ein Client hat diese URL genommen und in zwei Teile geteilt. Und zwar in diese Authority oder den Host und diesen Pfad und schickt da in der ersten Zeile von meiner HTTP-Nachricht nur den Pfad an den Server. Das heißt also bei meinem Server kommt der Host nicht an. Und das ist ja erstmal unter der Idee: Ja, ist ja richtig. Weil wir haben ja jetzt schon den richtigen Host gefunden. Das heißt wir müssen ja jetzt nicht nochmal sagen: ‚Hey, du bist übrigens mein Host!‘. Das hat so lange funktioniert wie auf jeden Server nur exakt eine Domain läuft. Wenn auf einen Server aber zwei Domains laufen, zum Beispiel auf dem Server von example.org laufen auch example.com, was exakt die selbe Seite ist, dann weiß jetzt der Server ja nicht: Hat du example.com oder example.org eingegeben? Und deswegen gibt es den Host header und da schicken wir eigentlich nur nochmal diesen ersten Teil, den wir eingegeben haben, einfach nochmal mit. Und damit können wir halt dieses… diese virtual hosts haben vielleicht ja ein paar Leute schon mal von gehört, von Apache oder so, können wir dann quasi mehrere Hosts auf dem selber Server betreiben.
Robert:
Okay. Und insofern ist das relevant, weil es gibt ja zum Beispiel google.de und google.com. Liefert ja eigentlich auch, ich hätte fast gesagt ‚das gleiche aus‘, aber die Seiten sind ja zumindest lokalisiert. Bei google.de sehe ich das UI auf Deutsch und bei google.com wahrscheinlich auf Englisch, wenn da nicht noch irgendwelche anderen Tricks greifen, ne?
Lucas:
Genau!
Robert:
Warum ist das wichtig? Wenn ich zum Beispiel auf einer Seite robert-und-lucas-testen.de und den Host nochmal mit .com und .club und .info dran betreibe, dann könnte ich doch eigentlich überall, ja, die Seite test… also /test ausliefern über alle diese Hosts und das wäre okay? Also warum muss ich da einen host header setzen und warum ist das relevant? Und was hat das den Server zu interessieren?
Lucas:
Genau. Also das ist eine gute Frage, weil du… Also eigentlich können wir auch einfach als Server den Host ignorieren. Also in dem Fall, den du jetzt gerade beschrieben hast, würden wir einfach den host header nicht anschauen, sondern immer einfach nur auf den Pfad gucken und immer mit dem antworten, was uns der Pfad und Methode sagt. Aber wenn wir jetzt auf irgend… Wir haben einen Server aufgesetzt, irgend so einen Hetzner Box und auf der betreiben wir sowohl Roberts Homepage als auch Lucas Homepage, einfach weil wir Geld sparen wollen als alte Sparfüchse. Und jetzt wollen wir einfach dafür sorgen, dass wenn die Leute robert.de eingeben, dass sie Roberts Homepage bekommen und dass wenn sie lucas.de eingeben, dass sie Lucas Homepage bekommen, dann ist das einfach ein sehr einfacher Weg dafür zu sorgen, dass der Client dem Server mitteilt: ‚Übrigens, ich möchte jetzt die Blogposts von Robert sehen!‘. Also das ist eigentlich schon die Idee dahinter, einfach damit man solche Sachen teilen kann. Es hat auch noch Gründe wie Proxies und so weiter, das geht jetzt ein bisschen über die Sachen hinaus, die wir heute besprechen, aber grundsätzlich kann ich damit so etwas tun und das ist schon sehr, sehr praktisch. Also so für shared hosting oder auch für… Also wir könnten auch sagen es gibt innoq.com und innoq.de und je nachdem ob ich .com oder .de eingeben habe, zeige ich die Blogposts auf Deutsch oder auf Englisch an. Das würde ja auch gehen. Könnte auch derselbe Server im Hintergrund das betreiben. Das heißt, ich als Client schicke auf jeden Fall dem Host mit, weil ich nicht weiß, ob der Server das braucht oder nicht. Und der Server kann sich dann entscheiden, ob er mit der Information etwas anfängt oder nicht. Das ist auch wieder so ein grundlegendes Prinzip von HTTP, dass… der Server muss halt nicht eben Header beachten. Der kann Header auch einfach ignorieren.
Robert:
Okay. Hat dieser host header auch schon was mit redirections zu tun? Also ist das… führt uns das zu diesem Thema? Oder ist das irgendwie dafür relevant?
Lucas:
Ich würde sagen nein, das ist ein unabhängiger Header. Also der Header, den wir setzen können, das ist aber ein response header. Um einen Redirect durchzuführen, das ist der Location header. Da sagen wir tatsächlich… geben wir einen Header zurück und sagen: ‚Bitte gehe jetzt auf folgende URL!‘. Und das wäre… ist das einfache Prinzip, was hinter redirections steht, dafür müssen wir aber kurz nochmal auf die Response eingehen, die nämlich einen Statuscode hat. Und der ist dafür nämlich auch wichtig. Genauso wie der Request über den wir ja schon gesprochen haben, da schicken wir eine Methode mit, um grundsätzlich zu sagen was wir vom Server wollen. Ob wir irgendwas an Information holen wollen oder ob wir irgendeine Information hinschicken wollen, haben wir bei der Response… schicken wir einen Statuscode zurück und das ist eine Zahl. Eine dreistellige Zahl, die einfach so ein generelles Feedback gibt: Wie ist der Request gelaufen? War es super? War nicht so gut? Und da wären jetzt Statuscodes, die mit einer zwei anfangen, das sind die Statuscodes, die sagen: ‚Ja, es ist alles gut gewesen!‘. Da gibt es dann auch verschiedene Ausprägungen von. Kann man sich gerne auch mal angucken in so Statuscodes-Listen, welcher da der richtige ist für den eigenen Use Case. Aber grundsätzlich ist das etwas, was geklappt hat. Statuscodes, die mit einer fünf anfangen, da hat der Server irgendetwas… ist irgendetwas auf dem Server kaputt gegangen und wir haben einen Fehler gemacht.
Robert:
Mist gebaut!
Lucas:
Genau, wir haben Mist gebaut und geben das auch zu. Dann sagen wir zum Beispiel einen Statuscode 500 und dann haben wir dem Client gesagt: ‚Ich habe irgendwie Mist gebaut und wir müssen das irgendwie nochmal versuchen!‘ oder ‚Versuch es später nochmal!‘ oder sonst irgendwas. Bei einem Statuscode, der mit einer vier anfängt, da gibt der Server dem Client die Schuld und sagt: ‚Du hast mir irgendetwas geschickt, womit ich nichts anfangen kann!‘. Und dann gibt es halt die Statuscodes mit einer drei anfangen und das ist das, wo wir im Thema ‚Redirects‘ landen. Also Redirects ist halt eine Möglichkeit vom Server zu sagen: ‚Okay, du hast mir eine Anfrage geschickt für diesen Pfad‘ beispielsweise, ‚aber du musst, um diese Information zu bekommen, eigentlich woanders hin. Also beispielsweise haben wir jetzt irgendwie uns entschieden, dass unsere URLs für die Artikel nicht mehr mit /articles anfangen, sondern mit /written oder so. Dann können wir ein Redirect durchführen und einfach die Leute woanders hinschicken. Und das machen wir, indem wir den Statuscode auf einen der Statuscodes, die mit einer drei anfangen, setzen. Details machen jetzt im Audioformat nicht so viel Sinn, können wir gerne auch ein bisschen was zu verlinken, welche Statuscodes da welche genaue Bedeutung haben. Und dann setzen wir zusätzlich einen sogenannten location header und da steht dann drin, wo ich die Person hinschicken will. Das heißt also beispielsweise /written. Und dann kriegt der Browser diese Antwort zurück, sieht: ‚Ah okay, ich soll da hin!‘ und dann schickt er wieder einen neuen HTTP-Request an den Server und kriegt dann die richtige Antwort. Das ist quasi die Idee hinter so einem Redirect und da sieht man auch wie mächtig dieses einfache Format ist. Also das basiert einfach nur da drauf, dass wir sowas haben, wie den Statuscode und sowas haben wie HTTP-Header und damit können wir schon so etwas relativ komplexes mit abbilden, mit Redirects.
Robert:
Ich habe ja am Anfang meiner Karriere lange versucht damit durchzukommen meine Fehlerseiten mit dem Code 200 auszuliefern. Bin ich dann aber doch nicht so lange mit durchgekommen, wie ich das eigentlich erwartet hätte. Das Problem liegt, glaube ich, nicht ganz auf der Hand, denn ich habe früher immer gedacht: ‚Okay, wenn da jetzt ein Fehler bei mir auf dem Server passiert, dann sage ich halt ‚hier ist ein Fehler passiert, tut mir Leid, wir arbeiten dran‘ und der User oder die Userin, die meine Seite aufruft, wo es eben geknallt hat, die sieht das dann. Die kann da ja lesen.‘. Das Problem bei der Sache, wenn ich sowas mit einem 200er zurückliefere, liegt erstmal nicht auf der Hand, wie gesagt, ich gehe davon aus die Userin liest und versucht es vielleicht hoffentlich später nochmal. Aber wir wissen ja, dass das Web eigentlich ein universelles Medium ist und das heißt: Es ist nicht zwangsläufig nur für Menschen gedacht, sondern darin sollen sich vielleicht auch Maschinen bewegen. Und eine Maschine weiß natürlich nicht, wenn da eine Seite mit 200 zurückkommt, ‚hier ist gerade was in die Luft geflogen‘, dann ist das für die erstmal okay. Weil 200 deutet an, dass alles geklappt hat. Und das zeigt so ein bisschen warum dieser Fehlercodes auch eigentlich im Web enorm wichtig sind, dass wir sie in unserer Architektur eben berücksichtigen und in unseren Anwendungen vor allem implementieren korrekt. Weil das Web eben nicht nur von Menschen benutzt wird. Ein schönes Beispiel ist glaube ich eine API, die wird nicht… meistens nicht von Menschen abgerufen und wenn die Maschine immer 200 zurückbekommt, dann müsste sie ja immer irgendwelche Fehlermeldungen auslesen, die sich ja auch mal ändern von ‚Hier ist was explodiert!‘ zu ‚Tut uns leid, bitte gehen sie weiter!‘ und dann müsste ich dauernd diese Strings neu überprüfen. Und da ist es glaube ich schon ganz schön einen Fehlercode zu haben als Maschine, oder?
Lucas] :
Absolut! Also das ist einer der Gründe dafür. Andere Gründe sind auch, dass der Browser, den wir ja benutzen, um auf eine Webseite zuzugreifen, ist ja auch eine Maschine. Das heißt also der kann… der liest ja nicht ‚Sorry, es ist etwas schief gegangen!‘ und macht dann irgendwelches Machine Learning und schließt daraus Schlüsse, sondern der will einfach so eine Zahl haben und dann weiß er halt: Ist dieser Inhalt, den ich da anzeige, ist das eine Fehlerseite oder ist das eine korrekte Seite? Und kann daraus dann auch Schlüsse ziehen für verschiedene Sachen, wie jetzt irgendwie Caching und so weiter. Wichtiges Thema für Statuscode sind auch irgendwelche Proxies, das geht auch über das hinaus, worüber wir heute sprechen. Können wir auch gerne mal eine Folge zu machen! Also so irgendwelche Maschinen, die zwischen mir und dem Server stehen und die irgendwelche Sachen mit dem machen, was ich dahin schicke, die könne auch aus diesem Statuscode Schlüsse ziehen was sie mit dieser Antwort machen. Ob sie sie behalten, ob sie sie verwerfen, solche Sachen. Und dafür sind Statuscodes immens wichtig und deswegen sollten wir die auf jeden Fall nicht ignorieren. Und sie haben halt auch noch diese spezielle Eigenschaft, dass sie halt Redirects mit auslösen, was ja… Die sind halt weder ein 200er, noch ein 400er, 500er Code und die brauchen wir einfach um Redirects zu machen. Ohne funktionieren die einfach nicht. Das ist auch nochmal so ein Sonderfall, sage ich mal.
Robert:
Okay und wir gewinnen eigentlich langfristig selbst als Entwicklerinnen und Entwickler, wenn wir darauf achten die Statuscodes zu beherzigen. Ein schönes Beispiel ist: Es gibt von Suchmaschinenanbietern, wie zum Beispiel Google, aber es gibt ja auch noch andere Suchmaschinenanbieter, meistens so Webmaster-Tools oder Search Consoles, oder wie die sich alle nennen. Da kann ich, wenn ich eine Homepage oder eine Unternehmenswebsite oder was auch immer betreibe, meine Domain hinterlegen und sagen: ‚Die gehört mir!‘, meistens über einen DNS-Eintrag oder ein Zeichen, was ich in meinem HTML, einen Zeichensatz, den ich in meinem HTML wie so einen Schlüssel hinterlege. Wo die wissen: Der gehört tatsächlich dem Robert. Und dann gibt mir Google ein paar Infos aus ihrem Geschäftspreis. DuckDuckGo kann das vielleicht auch, Bing mit Sicherheit auch. Nämlich zum Beispiel: Wie viele Leute haben denn meine Seite aufgerufen über die Google Suche mit folgenden Keywords? Die Infos würde ich sonst nie bekommen. Die melden mir aber auch sogenannte Alarme, also zum Beispiel von ihrem… auf robert.com waren im letzten Monat von 500 gefundenen Seiten 30 kaputt mit einem 500er. Das ist schon eine interessante Info, denn wenn ich zum Beispiel mein Monitoring oder Alerting nicht im Griff habe, dann ist sowas oftmals Gold wert, finde ich. Weil der Google Bot, der kommt ja einmal die Woche vorbei, vielleicht sogar öfter und wenn der da irgendwelche 500er findet von Seiten, die ja bei Google Index zu finden sind, dann melden die mir sowas. Und das ist natürlich ein Gewinn, weil diese Maschine, der Google Bot, verlässt sich natürlich auch auf Statuscodes. Wenn diese Seiten 200er hätten, würde ich diese Warnungen nie bekommen. Ich finde das ist ein superschönes Tool, weil ich gebe zu: Ich habe nicht immer ein Log Parsing und ein Alerting für alle kleinen Seiten, die ich so baue, am Start. Meistens vergisst man das ja auch oft oder hat es am Start, aber wertet es nicht richtig aus und da kann sowas echt helfen. Also zumindest für öffentliche Seiten, finde ich.
Lucas:
Genau oder…
Robert:
Ist glaube ich ein ganz schöner Gewinn!
Lucas:
Ja. Oder wir können es halt auch für solche Sachen wie Alering von uns selbst einsetzen. Also wenn wir beobachten welche Statuscodes unsere Sachen haben und auf einmal gibt es nur noch 500er zurück, dann gibt es vielleicht mal eine SMS. Also das würde ja auch auf derselben Mechanik aufsetzen im Prinzip.
Robert:
Ja. Okay, jetzt sind wir schon ein bisschen abgedriftet, wir sind eigentlich… haben wir uns Request Header und Response Header angeguckt. Und als Beispiel haben wir jetzt schonmal den wichtigen Host Header kennengelernt, der für die Requests gilt. Was gibt es denn noch für wichtige Header, die ich auf jeden Fall setzen muss, wenn ich jetzt in cURL so ein Request mal selber tippe?
Lucas:
Genau, also wir haben auch schon den Redirect Response Header kennengelernt, genau. Aber… Also als Request Header müsste ich tatsächlich, wenn ich einfach nur mit einem Server sprechen will, brauche ich nur den Host Header. Alle anderen Sachen sind völlig optional.
Robert:
Okay.
Lucas:
Aber die… Also es sind trotzdem natürlich ein paar Sachen dabei, die man üblicherweise mitschickt. Und das wäre beispielsweise der Accept Header und damit kommen wir in einem Bereich, der ganz wichtiger Teil des HTTP-Standards ist und der hat eine Philosophie. Und das ist die sogenannte Content Negotiation. Also der Accept Header sagt: ‚Ich habe dir jetzt einen Request geschickt und ich möchte, dass du mir eine Antwort im folgenden Format schickst‘. Also ein Beispiel dafür wäre: ‚Ich möchte, dass du mir die Antwort im HTML-Format schickst, denn ich bin ein Browser und ich möchte gerne eine HTML-Seite anzeigen!‘. Oder: ‚Ich möchte… Ich habe hier jetzt so einen image tag in meinen HTML drin gehabt und da wurde ein zweiter HTTP-Request gemacht, um ein Bild zu holen, dann würde mein Browser mitschicken: ‚Ich erwarte hier übrigens, dass da ein Bild zurückkommt. Weil ich möchte das jetzt als Bild hier reinrendern. Wenn du mir jetzt HTML zurückschickst, dann kann ich an der Stelle überhaupt nichts damit anfangen, weil ich erwarte, dass ich das als Bild hier einbetten kann!‘. Das heißt also der Accept Header gibt dem Server die Information: Was erwartet der Client für ein Format für die Antwort? Und mit diesem System können wir zum Beispiel sagen: ‚Ich möchte jetzt diese URL hier haben und ich möchte die als JSON Antwort zurückbekommen!‘ oder ‚Ich möchte die selbe URL als JSON zurückbekommen… ähm, als HTML zurückbekommen!‘. Das heißt also wir können in HTTP ausdrücken: ‚Bitte schickt mir genau das, aber ich möchte das in dem und dem Format haben!‘. Wir können uns genauso vorstellen, wenn wir über so moderne Bildformate reden, wie so WebP oder dieses neue AVIF oder wie es heißt, dass mein Browser einfach, wenn er ein Bild anzeigen möchte, mitschickt, welche Bildformate er versteht. Weil dann kann der Server entscheiden: Welches ist das beste Bildformat für diesen Client? Und schickt das in dem perfekten Format zurück. Das wären so Beispiele, die wir mit diesem Accept Header anfangen können. Der ist wirklich ein ganz tolles Tool, über was Leute nicht nachdenken, der uns ganz viele Möglichkeiten eröffnet. Und, wie viele Header, ist der Accept Header, der halt ein Teil von so einem Pärchen. Das heißt also es gibt einen Request Header und einen dazugehörigen Response Header. Und der dazugehörige Response Header vom Server wäre dann der sogenannte Content Type. Der Content Type gibt an: Welches Format habe ich denn jetzt verwendet in meiner Antwort? Das heißt: Der Accept Header, das ist so eine Liste von favorisierten Formaten. Also ich sage jetzt mal ich möchte ein Bild haben und ich sage: ‚Ich kann WebP, aber ich würde auch ein PNG nehmen oder auch ein JPEG.‘, dann kann der Server jetzt aus dieser Liste auswählen, was er am liebsten hat und entscheidet sich jetzt für das PNG. Dann muss der Client ja wissen, dass das jetzt ein PNG ist. Weil das konnte er ja nicht wissen, er hat ja eine Auswahlliste geschickt. Und dann würde er den Content Type auf PNG setzen und sagen; ‚Die Antwort, die ich dir schicke, ist in PNG.‘ und da sind wir dann bei diesem Response Body vom Server. In dem Response Body steht dann entweder so eine HTML-Nachricht drin, aber der könnte auch irgendwelche binären Daten von einem PNG-Bild drin schicken. Und damit der Browser weiß, wie er das zu interpretieren hat, steht oben in dem Header drin, was für einen Typ hat denn jetzt der Content? Das ist die Idee, die dahinter steckt. Und auf diese Art und Weise ist das immer so eine Nagotiation, also ein Verhandlung zwischen Client und Server. Der Client sagt; ‚Ich könnte folgendes!‘, der Server wählt eins davon aus und sagt welches er gewählt hat und schickt es an den Client zurück.
Robert:
Ah, okay! Aber kann ich denn diese Content Negotiation nicht auch über die URL machen? Ich könnte ja sagen; ‚Ich möchte auf lucas.de ein Kaffee.jpeg abrufen, weil ich ein Bild von deiner aktuell gefüllten Kaffeetasse sehen will.‘. Und dann sage ich doch in der URL, also als Teil der URL: lucas.de/kaffee.jpeg, was ich haben will. Nämlich eben JPEG. Damit ist die Lage doch klar für dich am Server, oder?
Lucas:
Absolut, also das ist auch eine Möglichkeit, das so zu tun und das tun auch viele so. Aber aus der Sicht von einem HTTP-Puristen gibt es keine Dateiendung in einem Pfad. Ein Pfad ist einfach ein Pfad und fertig. Also der hat keine Dateiendung wie .png oder .json. Und das ist jetzt die Puristen-Antwort, die pragmatische Antwort darauf ist: Ja, ich könnte auch quasi alles immer über die Endung einfach anfragen, aber das würde mir halt nicht die Möglichkeit geben, dass der Browser selber sagt, welche Formate er beherrscht und der Server dann auch aus dieser Liste etwas auswählen kann. Weil eine Dateiendung ist ja exakt ein Wert, aber so ein Accept Header ist halt eine Liste. Das heißt in der Art und Weise, wie du es gerade beschrieben hast, könnte ich nicht umsetzen, dass der Server auswählen kann, ob er jetzt WebP oder ein PNG schickt. Weil er dann nicht sieht, was ich kann. Ich kann das auch auf eine andere Art und Weise umsetzen, indem ich auf den Client quasi schon auswähle welche Bildformate ich kann, aber dann benutze ich nicht die nativen Fähigkeiten meines Browsers aus. Der kann das schon, der weiß schon was er für Formate spricht und dann kann ich das auch ausnutzen. Bei JSON ist das jetzt wieder etwas anderes. Also meistens weiß ich, ob ich jetzt gerade ein JSON-Client bin oder ein HTML-Client und kann das auch über eine Dateiendung machen so theoretisch, aber gerade bei solchen Bildformaten ist das ein ganz wertvolles Feature um solche Optimierungen durchzuführen.
Robert:
Ja, das ist natürlich schlau! Das heißt dadurch, dass ich als… Ja, ich rufe ja dieses kaffee.jpeg nicht als Mensch bei dir ab, das würde wahrscheinlich dein HTML referenzieren auf deiner Homepage, nämlich lucas.de, die wir nicht in den Shownotes verlinken, weil es sie wahrscheinlich nicht gibt…
Lucas:
Genau!
Robert:
Aber wenn du dort ein live-Bild von deiner Kaffeetasse zeigen würdest, würdest du im HTML wahrscheinlich hoffentlich nachdenken und nicht den Kurzschluss wählen einfach kaffee.jpeg dort zu referenzieren, sondern vielleicht einfach nur /kaffee. Damit eben dein Server im Stande ist zu gucken: Wer kommt denn da an? Und was kann derjenige oder Browser, der da eben kommt? Weil die Browser glaube ich immer mitschicken was sie verstehen in einem extra Header, ne?
Lucas:
Genau! Das ist genau dieser Accept Header, über den wir gesprochen haben. Also dafür ist der da und tatsächlich kann ich trotzdem auch kaffee.jpeg hinschicken und nachher ein WebP-Bild zurückschicken. Da der Server ja den Content Type zurückschickt, wird der Browser… der guckt eh nicht drauf, ob es da jetzt eine Dateiendung gibt und schließt daraus, wie er das Bild zu öffnen hat, sondern der schaut nur auf den Content Type und sagt aus dem Content Type: ‚Ah, okay. Du hast mir jetzt ein WebP zurückgeschickt, dann parse ich das als WebP und zeige das als WebP-Bild an.‘. Das heißt ich kann auch weiterhin kaffee.jpeg hinschrieben, das ist gar kein Problem, aber Server braucht das nicht um zu wissen, dass er jetzt das als JPEG oder WebP-Bild zurückschickt.
Robert:
Aber das wirkt irgendwie so ein bisschen schmutzig. Da fragt einer ein kaffee.jpeg an und kriegt dann mit Glück ein WebP zurückgeschickt, mit Pech eine Excel-Datei auf seinen Windows-Rechner.
Lucas:
Ja, das stimmt. Also gerade, wenn man jetzt… Keine Ahnung, du hast mir jetzt das Bild von deinem Kaffee geschickt und ich habe das im Browser auf und drücke STRG+S, um das zu speichern, dann würde mein Browser das ja jetzt als kaffee.jpeg abspeichern, obwohl es eigentlich ein WebP-Bild ist. Das fühlt sich so ein bisschen schmutzig an, aber ist halt die Frage, ob man darauf Rücksicht nimmt. Man kann auch einfach ‚Kaffee‘ hinschreiben und den Rest über… Der Content Type regelt das, das würde gehen.
Robert:
Okay und der Browser schickt immer in seinem Accept Header welche Bildformate und Videoformate und Audioformate er so kennt? Oder ist das nur der Fall, weil diese URL in einem image tag im HTML stand, dass er mir seine Bildformate im Accept Header schickt, die er versteht. Oder schickt der immer alle Formate für alle Medientypen, die er erkennt, bei jeder Art von URL, die er aufruft?
Lucas:
Genau, also das erste, was du gesagt hast, ist richtig. Also er macht das aus dem Kontext heraus. Das heißt wenn das ein image tag ist, dann schickt er die Bildformate mit, wenn es ein video tag ist, dann schickt er die Videoformate mit. Er schickt aber grundsätzlich immer, wenn er einen Request schickt, so eine Grundauswahl mit, dass er halt irgendwie HTML kann, dass er JSON kann und dass er grundsätzlich auch Bilder kann. Also zumindest die aktuellen Browser schicken jetzt nicht bei jedem Request auf eine beliebige URL die Liste aller Bildformate und aller Videoformate und aller Audioformate mit, die sie können, weil das wäre ja auch ein ganz schön großer Header. Aber das müssen wir auch mal im Hinterkopf behalten, zumindest bis HTTP 1.1 wäre es halt so, dass ich ja auch jedes Mal diesen Riesenheader mitschicke. Das heißt also, ich muss schon ein bisschen Bewusstsein dafür haben, dass ich sehr, sehr viele Daten übertragen würde, wenn ich immer diese gesamten Listen rüberschicke. Weil einfach der… ja jeder Request hat ja alle meine Header wieder mit dabei und dann würde ich die jedes Mal wieder an den Server schicken.
Robert:
Das heißt jeder Request ist per se auch atomar, ne? Er enthält eigentlich als… also self-contained, um es besser zu beschreiben, enthält alle Infos und ist isoliert, ergibt Sinn und man verlässt sich nicht auf Header, die in vorherigen Requests mal dringesteckt haben.
Lucas:
Genau! Und das ist eine ganz, ganz interessante Eigenschaft! Also diese Sachen, die HTTP ausmachen, wie zum Beispiel, dass halt jede Nachricht für sich selber steht oder dass es diese Meta-Information über eine Nachricht gibt oder dass es halt diese standardisierten Methoden, wie GET, POST und DELETE und so weiter gibt, das fand der Herr Roy Fielding so interessant, dass er daraus, nachdem er da mitspezifiziert hat, eine Doktorarbeit geschrieben hat. Und da behandelt er das Thema ‚REST‘ und REST ist quasi die theoretische Betrachtung davon, was so cool ist an diesen Eigenschaften von HTTP und HTML im Kern. Was das so cool macht und das hat er in seiner Thesis beschrieben. Und das ist das, was man als REST bezeichnet. Das geht aber jetzt auf jeden Fall über das hinaus, was wir heute besprechen. Da können wir gerne auch mal das Buch von unseren Kollegen und Kolleginnen zu verlinken, das ist ein ganz interessantes Thema. Das ist so ein bisschen die theoretische Betrachtung von diesem praktischen HTTP-Protokoll. Und da geht es auch genau um solche Eigenschaften und was es uns ermöglicht, so auch im Bereich der Skalierbarkeit und so weiter, dass eben diese Nachrichten für sich selber stehen.
Robert:
Ah, okay! Ich hätte jetzt fast abfällig gesagt: ‚REST studiert man, HTTP macht man.‘, aber ich glaube REST ist wirklich… das klingt jetzt so ein bisschen langweilig, ‚eine wissenschaftliche Betrachtungsweise von HTTP‘, aber es einfach glaube ich ein sehr gutes Framework oder Set von Empfehlungen und Lehren und was alles da auch immer noch drinsteckt, wie man HTTP eigentlich richtig gut nutzt und ebenso wie es eigentlich vorgesehen war.
Lucas:
Genau! Genau, also eigentlich vor allem so, wie es halt die Leute, die sich es überlegt haben, es sich gedacht haben. Das ist eigentlich das besonders interessante daran und deswegen… Ich persönlich bin ein großer Fan von diesem Paper, auch wenn das jetzt nicht 1A toller mitreißender Schreibstil ist, der da drin ist, aber trotzdem finde ich das eine sehr, sehr lesenswerte Thesis.
Robert:
Okay. Aber es gibt ja auch unterhaltsamere Verpackungen des eigentlichen Inhalts, der da drin steckt.
Lucas:
Genau!
Robert:
Vielleicht fallen uns noch ein paar ein und wir verlinken die hier drunter.
Lucas:
Genau!
Robert:
Aber lass uns mal weiter bewegen, jetzt haben wir verschiedene Header sowohl auf Client… also sowohl auf Request als auch auf Response-Seite angeguckt, die gehören unter anderem auch zusammen. Zum Beispiel ‚Accept‘ im Request und ‚Content Type‘ in Response. Da geht es um die Content Negotiation, Redirection, haben wir gehört. Was gibt es denn noch so wichtige Header? Mir liegt so ein bisschen dieser süße Keks auf der Zunge, sollten wir da noch drauf eingehen? Weil das ist glaube ich auch ein Header, ne?
Lucas]:
Genau! Also dieser berühmte Cookie, der mittlerweile so bekannt ist, dass er ja auch Leuten, die überhaupt nichts mit… nicht mal wissen was genau HTTP ist, bekannt ist, weil es diese Cookie Warnings gibt, die man da immer wieder angezeigt bekommt und alle sagen: ‚Ach, Cookies, das ist ja total fies und gemein. Das will ich gar nicht haben!‘. Cookies sind ein ganz, ganz wichtiger Teil von dem, wie HTTP funktioniert. Ich würde vorschlagen, dass wir nur jetzt ganz grundlegend sagen: Was ist ein Cookie? Und dann uns nochmal in einer weiteren Folge dieses Thema angucken, weil es wirklich großes Thema ist, was viele Implikationen hat und wo es auch interessante neue Entwicklungen gibt. Da können wir nochmal dann ganz im Detail drauf eingehen. Aber grundsätzlich ist Cookie einfach wieder ein Pärchen von HTTP-Headern, und zwar dem Set Cookie Header und dem Cookie Header. Set Cookie Header ist ein Header, den der Server mitschickt und der sagt: ‚Bitte merk dir doch bitte den folgenden String.‘ und der Client, der kriegt den, speichert den lokal ab und immer, wenn er wieder an den gleichen Server einen Request schickt, dann schickt er genau diesen String wieder mit. Und das können wir zum Beispiel benutzen, um uns einen User zu merken. Der hat sich eingeloggt und wir wollen uns merken ‚das ist der gleiche Nutzer‘, dann können wir das in diesen String reinschreiben und dann schicken wir das an den Server. Das ist jetzt sehr dramatisch vereinfacht, weil das wirklich nur das ist, was quasi grundlegend im HTTP-Format funktioniert. Aber grundsätzlich ist das das, was der Cookie Header ist und was man damit alles machen kann, was für gute und was für schlechte Dinge, da können wir gerne nochmal eine separate Folge zu machen!
Robert:
Ah, okay. Das heißt dadurch: Auch hier zeigt sich wieder schön diese self-contained Prinzip von Request und Response. Wenn ich einen Cookie per Set Cookie bekommen habe vom Server in der Response und ich will ihn beim nächsten Request wieder dem Server geben, muss ich den wieder mitschicken. Wenn ich ihn nicht mitschicke, dann ist er fort, oder?
Lucas:
Genau, weil wir müssen ja… In diesem Prinzip worüber wir eben gesprochen haben ist es ja so, dass jede Nachricht quasi für sich selber steht. Das heißt ich kann ja nicht einfach sagen; ‚Du kennst mich ja schon!‘, weil das ist eben nicht so. Das heißt wenn der nächste Request kommt, dann schicke ich wieder den Cookie mit, damit ich mich wieder ausweisen kann quasi, dass ich immer noch der gleiche bin wie eben.
Robert:
Also das Web hängt auch so ein bisschen auf Gedeih und Verderb an diesen Keksen, ne?
Lucas:
Ja, kann man schon so sagen. Es gibt neue Ideen wie man das anders lösen könnte, aber ja… da, wie gesagt…
Robert:
Aber Cookie-Folge finde ich super! Das machen wir!
Lucas:
Genau.
Robert:
Wir geloben hiermit, dass wir eine Cookie-Folge machen werden wollen. Wir hoffen aber natürlich, dass euch da auch interessiert. Also wenn euch das interessieren würde, dann lasst es uns doch wissen. Ihr könnt uns doch auch gerne zwischendurch mal eine Mail an [email protected] schicken. Wir hören nämlich immer gerne Feedback von Hörerinnen und Hörern, was wir besser machen können, wo wir vielleicht mal Folgen zu machen sollten, was es vielleicht noch nicht gibt. Also schreibt uns doch einfach mal, ein lockerer Einzeiler reicht. Ansonsten auch gerne auf Twitter oder an unsere E-Mail-Adressen oder… FAX haben wir nicht mehr, aber irgendwie findet ihr uns!
Lucas:
Also wir haben auch schon mehrere Folgen gemacht, die auf Vorschlägen von euch basierten. Also wir sind da sehr offen für!
Robert:
Tut das, bitte! Okay. Lucas, Cookies sparen wir ein bisschen aus, aber wir wissen jetzt wie die Header lauten und was sie so grob tun. Und wir können uns wahrscheinlich auch denken, dass das eine Möglichkeit ist in diesen eigentlich statuslosen… in dieser ewigen Abfolge von Request/Response-Zyklen, die immer wieder aufeinander folgen und eigentlich nichts vom Vorgänger oder Nachfolger wissen, dass Cookies eigene kleine, aber doch sehr mächtige Möglichkeit sind Status in eigentlich ein statusloses Protokoll einzuhieven.
Lucas:
Genau! Genauso ist es.
Robert:
Okay. Mit großer Macht folgt große Verantwortung. Dementsprechend müssen wir da eine andere Folge zu machen. Aber lass uns mal gucken was es noch so an wichtigen Headern gibt. Redirection hatten wir jetzt, Content Negotiation, Cookies, was gibt es noch?
Lucas:
Genau, also ein wichtiger und viel einfacherer Header ist die Compression. Also wir wollen vielleicht die Sachen, die wir vom Server bekommen vorher komprimieren mit sowas wie gzip. Dann gibt es hier wieder dasselbe Prinzip wie bei Content Negotiation, gibt es quasi eine Content Compression Negotiation. Das heißt der Client schickt an den Server: Folgende von den Kompressionsformaten kann ich. Also ich verstehe zum Beispiel jetzt GZIP und DEFLATE, dann schicke ich das mit. Dann kann der Server sagen: ‚Ah, okay. Aus dem wähle ich den aus, der mir am besten gefällt oder den ich selber am besten kann!‘ und schicke dann einen Header zurück der sagt: ‚Ich habe übrigens den Content, den du jetzt bekommst, mit dieser Kompression komprimiert.‘ und das ist auch wieder ein Header und schicke den an den Client zurück. Und auch damit haben wir wieder eine ganz tolle Möglichkeit… GZIP gibt es jetzt halt schon eine ganze Weile, aber es gibt auch ein moderneres Kompressionsformat, das heißt ‚Brotli‘. Das ist ein sehr komischer Name, aber ein sehr gutes Kompressionsformat. Und dann, wenn mein Browser das kann, dann stellt der automatisch, ohne das ich jetzt irgendwas tun muss, schickt der immer mit: ‚Ich kann übrigens auch Brotli!‘ und wenn der Server das auch kann, dann kann er statt GZIP zu verwenden, kann er auch Brotli verwenden. Das heißt also auch hier ist wieder dieses Negotiation-System dahinter, das einfach davon ausgeht, dass man nicht so viel über Server und Client vorher weiß, sondern dass die das einfach in der Kommunikation miteinander ausmachen. Das steckt da auch hinter.
Robert:
Ja und Compression ist glaube ich auch so das meist vergessene Thema, wenn ich irgendwie eine Webanwendung an den Start bringe mit einem Webserver und was alle dazugehört, ne? Das vergisst man irgendwie, also ich kenne es so immer, weil am Anfang: ‚Ach komm, wir müssen jetzt erstmal live gehen und dann ist was da.‘ und oftmals muss man aber gar nicht so viele Hebel in Bewegung setzen damit man eben Compression hat. Das ist eigentlich… bringt super viel das zu aktivieren, oder?
Lucas:
Absolut! Also ich sehe das auch immer wieder in der Praxis, dass Leute das nicht tun. Auch gerade eine JSON Antwort vom Server profitiert ganz dolle davon, wenn man sie komprimiert. Also würde ich das empfehlen und es ist wirklich super wenig Arbeit, wenn wir irgendein Framework oder irgendein reverse proxy, wie jetzt ein Apache oder ein nginx benutzen, da ist das meistens ein Schalter, den wir anschalten müssen und dann haben wir Kompression. Also da müssen wir auch nicht selber was für leisten, das ist eine Arbeit, die relativ wenig ist. Ich glaube der Grund warum das häufig vergessen wird ist tatsächlich, dass das irgendwie sich anfühlt, wie so ein Operations-Thema und dass dann halt vielleicht das irgendwie in der Kommunikation zwischen Operations und Development vielleicht verloren geht, dass das gemacht werden sollte. Und das ist halt auf jeden auch wieder so ein Punkt, einfach nochmal zu gucken, dass man nicht immer nur mit den Entwicklern und Entwicklerinnen spricht, sondern auch mal mit den Ops-Leuten. Die sind ganz wichtig auch dafür, dass das eine performante coole Anwendung ist und Kompression wäre ein Beispiel dafür.
Robert:
Ja, dass es vor allem Performance quick wird. Weil ich es bei den meisten einfach nur einschalten muss und Dinge wie HTML, JSON, also auch so plain text-Gedöns, HTML hat ja auch schön viele spitze Klammern, ich glaube die wiederholen sich oft. Das eignet sich auch ganz gut für einen Kompressionsalgorithmus.
Lucas:
Genau!
Robert:
Macht es! Bitte macht es! Denn am Ende fällt es auf das Produkt und das Team zurück. Egal wer es dann Schuld war es nicht zu aktivieren, denn am Ende bestraft Google mit den Web Vitals: ‚eure Seite ist langsam‘, ‚eure Seite komprimiert nicht‘, ‚mobile devices könnten Akku sparen, wenn ihr hier komprimiert übertragen würdet, weil dann einfach weniger Daten durchgehen‘. Dann wird schlimmstenfalls in ein paar Jahren die eigene Website downgeranked von Google und anderen Suchmaschinen, weil sie eben nicht so performant ist, wie sie das eigentlich sein könnte und Compression ist einfach so ein no brainer glaube ich, oder?
Lucas:
Ja, genau.
Robert:
Okay. So…
Lucas:
Ja und als letztes, du hast halt gefragt ‚was kann HTTP noch?‘, würde ich als quasi fünfte von den wichtigen Features, würde ich da auch das Caching betrachten. Caching ist auch… Ich glaube das ist auch so ein Thema, mit dem sich viele viel zu wenig beschäftigen, weil damit kann man auch eine Webseite viel, viel, viel performanter machen als ohne. Ist aber nicht ganz so einfach wie Kompression, weil das halt doch relativ viele Fallstricke und Problemchen mit sich bringt, wo man was falsch machen kann und so weiter. Ein Kollege von uns sagt immer: ‚Caching ist die Antwort, sowohl bei der Problem- also auch bei der Lösungssuche.‘. Das ist einfach etwas was schwierig ist. Auch da kann ich mir gut vorstellen, dass wir dazu mal eine Folge machen über das ganze Thema ‚Caching‘, weil es da auch quasi so verschiedene Methoden gibt, die da zur Verfügung stehen. Aber das ist auch etwas was ganz, ganz wichtig ist, um eine performante coole Webanwendung zu bauen. Das richtig zu machen. Grundlegend ist Caching erstmal die Idee, dass wir dafür sorgen wollen, dass der Client eine Antwort, die er schonmal vom Server bekommen hat, wiederverwenden kann. Also der… Wir wollen einfach nicht dauernd dasselbe erzählen. Das heißt wenn ich jetzt das fünfte Mal den Blogpost von Robert lese, dann braucht der Browser den ja nicht fünf Mal runterzuladen. Wenn das immer noch der gleiche Blogpost ist, dann kann ich den ja einfach behalten lokal, dann brauche ich den ja nicht nochmal runterzuladen. Und das ist so die grundlegende Idee dahinter. Und das zeigt aber auch schon das Problem, nämlich wie stelle ich denn fest, ob der Robert nicht vielleicht doch noch ein paar Rechtschreibfehler korrigiert hat in seinem Blogpost, so dass ich den doch nochmal neu runterladen muss, damit ich auch die gespellcheckte Version von seinem Blogpost bekomme. Und das ist genau das, was Caching kompliziert macht. Also dass man versehentlich vielleicht alte Antworten wiederverwendet, obwohl die halt alt sind. Das ist so die Frage, die hinter Caching steht, die das Caching schwierig machen. Und deswegen würde ich auch behaupten, ist das fast nochmal ein eigenes Thema.
Robert:
Ja, für mich als Person, die immer nur endlos gültige Manifeste publiziert im Internet, völlig frei von Rechtschreibfehlern, ist Caching natürlich nicht so wichtig. Aber für dich zum Beispiel, wenn du öfters mal einen Typo einbaust oder sowas, da ist das schon von Relevanz.
Lucas:
Genau. Also du als Mensch, der keine Fehler macht, du kannst einfach cachen, was das Zeug hält und kannst damit die beste Performance überhaupt rausholen!
Robert:
Ja, aber auch für mich wird es kompliziert auf einmal und ich komme ins Schwitzen, wenn ich um meine Manifeste auf einmal einen Rahmen, wie eine Navigation, einen Footer, Kommentare, drumwickele. Eigentlich will ich keine Kommentare für meine Manifeste, aber muss man heute so machen.
Lucas:
Genau.
Robert:
Dann wird es schwer auf einmal, weil dann kann ich dieses… hätte jetzt fast gesagt: Ein altes Testament kann man gut cachen, da ändert sich nichts mehr drin! Aber so ein Rahmenwerk, das haben wir oftmals auf Websites, macht es dann extrem kompliziert auf einmal.
Lucas:
Genau, absolut! Also zum einen halt irgendwie… nach dem Manifest kommt das zweite wichtige Manifest und jetzt willst du von dem ersten Manifest aber das zweite verlinken. Allein das wäre ja schon eine Änderung. Aber wir können halt auch nicht nur HTML-Seiten cachen, wir können halt auch JavaScript, CSS, Bilder und so weiter cachen. Und da müssen wir halt auch überlegen, ob die sich verändern, unter welchen Umständen verändern die sich und wie sorgen wir dafür, dass einfach die gleichen Sachen so selten wie möglich das zweite Mal runtergeladen werden. Das ist quasi unsere Aufgabe.
Robert:
Und wie wir das alle vielleicht wissen, starten wir ja gerne mal mit MVPs, was ja fast schon zum Schimpfwort verkommen ist. Lösungen, die erstmal Wert bringen und da lassen wir oft sehr gerne auch mal Dinge wie Caching hinter uns. Compression leider auch, aber Compression ist eben Quick Win haben wir gelernt, Caching meistens nicht.
Lucas:
Ja!
Robert:
Gibt es denn irgendwas um das Thema Caching für diese Folge auch abzuschließen, was ich trotzdem so Quick Win machen könnte? Könnte ich nicht sagen: ‚Komm, alle Seiten kriegen jetzt mal einen Caching-Header mit zehn Minuten. Weil mein Gott, wenn in zehn Minuten dieser Blogpost aktualisiert wird und jemand ruft den Inhalt in zehn Minuten zum zweiten Mal auf, kriegt er nochmal den alten. Ist ja nicht so schlimm! Aber auf Millionen von Requests kann ich schon was gewinnen damit.‘. Ist das eine gute Vorgehensweise?
Lucas:
Ja, also mit sowas wäre ich immer sehr vorsichtig. Also auch zehn Minuten können halt schon bei bestimmten Sachen fatal sein, sollten wir uns gut überlegen. Also das was wir tatsächlich wieder als einen Quick Win mitnehmen können, ist der sogenannte ETag. Das ist ein Tag, den wir auch wieder als Header an den Client schicken, wo irgendwie zum Beispiel eine Quersumme über meine geschickte Datei drinsteht und wenn ich dieselbe Datei dann nochmal anfrage, also dieselbe URL nochmal anfrage von meinem Client aus, dann schickt mein Client mit: ‚Ich habe übrigens eine Datei hier liegen, da hast du mir den ETag so und so gegeben, ist die noch aktuell?‘. Und dann antwortet der Server mit einem einfachen: ‚Ja, ist noch aktuell!‘ und schickt die Datei nicht nochmal mit. Das heißt also hier sparen wir uns den Transfer von dieser großen Datei. Wir sparen uns nicht die Anfrage der Datei, aber wir sparen uns den Transfer der Datei und das ist ein Quick Win, den wir einfach auch in sowas wie einem Apache oder ein ngnix konfigurieren können, dass der einfach automatisch eine Quersumme über alle Antworten jeweils berechnet und die als ETag mitschickt. Das wäre eine Möglichkeit, das tatsächlich zu tun.
Robert:
Okay. Aber Caching ist, wie vielleicht einige von uns auch gelernt haben, entweder mühsam oder aus dem Lehrbuch eins der harten Probleme der Informatik.
Lucas:
Definitiv!
Robert:
Vor allem cache invalidation, also die Ungültigerklärung von bereits gecachten Dingen.
Lucas:
Genau, absolut!
Robert:
Okay, wir nähern uns Spielfilmlänge. Ich hoffe es war bis hierhin genauso unterhaltsam wie ein guter Spielfilm! Aber Lucas lass uns, damit wir das nicht ewig hier weitertreiben… Ich weiß gar nicht wie lange hören unsere Hörerinnen und Hörer eigentlich gerne Podcasts?
Lucas:
Wir werden es heute herausfinden!
Robert:
Ich weiß nicht, wie ich anderthalb Stunden bei mir unterbringen sollte. Aber lasst uns auch das mal wissen, was ist eine gute Länge? Also wir haben ja typischerweise immer so Dreißigminüter, einen kurzen Einstieg in ein Thema. Aber sowas hier, da müssen wir einfach ein bisschen länger werden, ist das ab und zu mal gut? Oder ist das zu lang? Lasst es uns wissen, schickt uns eine Mail! Lucas, lass uns zum Abschluss noch einen Ausblick wagen. Jetzt haben wir so ein bisschen die drei grundlegenden Säulen des Webs kennengelernt: HTTP, URLs und HTML. Auf HTML sind wir so ein bisschen eigegangen heute, aber es ist eben die beschreibende Sprache für Webdokumente. Also wie sieht das aus? Was liegt wo? Wo sitzt das Bild? Wo steht welcher Text? Und so weiter. Für die, die das noch nicht kennen. Die drei Säulen haben wir heute kennengelernt, wir haben auch Protokolle kennengelernt, die unterhalb von HTTP liegen und die es auch schon ein bisschen länger gibt als HTTP. Wir haben besprochen, dass alles eigentlich in so self-contained Request/Response-Klammern läuft im Web? Was gibt es denn… Also HTTP gibt es jetzt wie lange? Weißt du es aus dem Kopf?
Lucas:
Also so 1991 ist das erste Mal HTTP rausgekommen.
Robert:
Okay, das heißt, du hast vorhin kurz die Version 1.1 erwähnt, ne? Wenn ich einen Request schreibe in meinem Telnet, falls einige gerade mitmachen, muss ich ja immer die Versionsnummer auch hintendran schreiben, ne?
Lucas:
Genau!
Robert:
In welcher ich mit dem Server telefonieren will. Sind wir… Also wenn ich jetzt den aktuellsten Chrome, Safari, Firefox, was auch immer benutze, nehmen die noch 1.1 oder gibt es was neueres?
Lucas:
Genau, also diese Version, die 1991 rausgekommen ist, das ist die Version 0.9. Die hat es eine Zeit lang gegeben, dann gab es 96 die Version 1.0 und 99 ist dann diese Version 1.1 rausgekommen. Und ich würde sagen heute ist… 1.1 ist so das, was man als ‚normal‘ bezeichnen würde. Das ist das, was quasi jeder Browser kann, weil 99 ist ja jetzt auch schon eine ganze Weile her. Das heißt also wie können auch mindestens mal von Version 1.1 ausgehen, aber seit 99 gab es trotzdem noch Verbesserungen und seit 2015 gibt es HTTP 2.0. Das ist quasi eine verbesserte Version von HTTP und die können wir heute in der Praxis auch ganz klar schon einsetzen, weil alle gängigen Browser beherrschen HTTP 2.0 und auch schon seit einiger Zeit. Das heißt also auch das ist eigentlich was, was wir gut verwenden können. Dabei kann ja kurz noch sagen, dass es natürlich so ist, dass wir sowohl 1.1 als auch 2.0 anbieten können. Das heißt also, wenn uns doch nochmal so ein historischer Browser vorbeikommt, der kein 2.0 spricht, dann kriegt er halt eine 1.1 Antwort und das ist auch ohne Probleme möglich. Das heißt also, auch hier kann man auch einfach auf die Bedürfnisse vom Client eingehen. Wie genau das funktionier, das würde ich jetzt heute mal überspringen, weil das sehr technisch ist. Aber grundsätzlich sind das so die zwei verbreitetsten Versionen von HTTP, 1.1 und 2.0. Ich würde kurz erklären was 1.1 und 2.0 ausmacht. Also 1.1 hat damals als revolutionäre Veränderung eingeführt, dass man nicht pro Request eine neu TCP-Verbindung aufmacht, sondern dass man TCP-Verbindungen mehrfach verwenden kann. So dass man nicht jedes Mal eine neue TCP-Verbindung aufmachen muss. Das ist halt heute eine Selbstverständlichkeit quasi, aber das war damals eine sehr, sehr große Veränderung. Aber 2.0 hat dann tatsächlich jetzt nochmal einiges verändert. Also interessant dabei ist, dass alles was ich heute so erzählt habe über Content Negotiation, Compression und so weiter, das gilt für jede HTTP-Version seit 1.1 im Kern. Also auch 2.0, da gelten all diese Sachen, die ich eben erzählt habe, genauso für und auch das 3.0, das wir gleich kurz nochmal gucken können, da gilt das auch für. Das heißt also das ist nicht umsonst gelernt, das können wir uns alles merken und wir können auch vor unserer Anwendung ein reverse proxy setzen, der dafür sorgt, dass unser Server sowohl 1.1 als auch 2.0 sprechen kann. Und im Hintergrund unsere Server können sich dann eins davon aussuchen und das wird dann quasi übersetzt. Also das ist gar kein Problem, das macht man als best practice. Was jetzt Version 2.0 eingeführt hat sind… Im Kern würde ich sagen gibt es zwei Highlights, die das gebracht hat. Das eine ist, aus HTTP ist halt ein Binär-Format geworden. Das heißt wir können das dann nicht mehr ohne weiteres in Telnet einfach eintippen was wir da schicken, weil bestimmte Sachen jetzt einfach nicht mehr plain text sind, um sie effizienter zu gestallten. Und das andere… Und dazu gehört ein Kompressionsverfahren, das sich HPACK nennt. Das sorgt dafür, dass die Header nicht… Also dass wenn wir ein Header schicken, dass wir bestimmte Methoden benutzen können, damit der Header nicht in der vollen Länge ein zweites Mal gesendet werden muss. Und das ist für mich eine von den zwei wichtigsten Änderungen bei HTTP/2. Also wenn ich einen Request an den Server schicke und ich schicke jedes Mal meinen Cookie mit, dann ist das sehr viel Daten, weil der Cookie ja jedes Mal in seiner vollen Größe geschickt wird. Bei HTTP/2 mit HPACK ist das jetzt so, dass sich Client und Server so ein Wörterbuch merken während der laufenden Kommunikation und da immer reinschreiben welche Sachen schonmal geschickt wurden. Und dieses Wörterbuch, das können wir dann verwenden, um wenn wir beispielsweise nochmal den selben Cookie schicken, zu sagen: ‚Ich möchte denselben Cookie schicken wie eben, erinnerst du dich noch daran?‘. Dann muss ich den Cookie nicht nochmal mitschicken. Das ist also eine Kompression der Header und die ist tatsächlich ein nicht zu verachtender Performancegewinn, weil viele von den Headern, die wir schicken, sind halt bei jedem Request immer wieder die gleichen. Und da können wir auch gerne nochmal einen Blogpost, den ich sehr gut fand, zu verlinken von Cloudflare. Da haben die drin erklärt was das für Performancegewinne gebracht hat diesen HPACK-Algorithmus miteinzuführen über dieses Dictionary, was ich erklärt habe. Aber zusätzlich auch das Huffmann Encoding, aber das geht jetzt zu weit da nochmal reinzutauchen. Da empfehle ich einfach den Blogpost zu, da ist das sehr gut drin erklärt. Und der andere Aspekt sind ‚Streams‘ und das hat tatsächlich eine Auswirkung auch auf unsere Architekturentscheidungen. Wenn wir uns mal vorstellen, dass ich einen HTTP-Request an den Server schicke und dann möchte… kommen jetzt von mir nochmal weitere Requests, nämlich für die ganzen Bilder, die ich anzeigen will, das CSS, das JavaScript und so weiter. Und für jedes davon mache ich quasi eine neue Verbindung auf und muss immer erst warten, bis die gesamte Antwort gekommen ist bis ich die nächste Anfrage schicken kann. Und das ändert sich mit HTTP/2 Streams, das ist quasi ein Weg, dass bei jeden einzelnen Paket, was ich an den Server schicke, steht eine Nummer dran oder ein Identifier dran, damit man weiß zu welchen meiner Anfragen… beziehungsweise Antworten gehört dieses Packet. Das bedeutet ich schicke einen… kann die quasi miteinander verweben. Das heißt ich schicke hin: ‚Ich möchte gerne dieses Bild, dieses CSS-File und dieses JavaScript-File.‘ und der Server kann dann auf derselben Leitung mir erst ein Stück von den CSS schicken, dann ein Stück von dem Bild und dann ein Stück von dem JavaScript und dann wieder ein bisschen von dem Bild und ich kann das dann auf meiner Seite wieder zusammenbauen. Und für jedes Paket, was vollständig fertig ist, kann ich dann sagen: ‚Cool! Packe ich aus, kann ich anzeigen.‘. Und das hat halt die Folge, dass ich viel weniger mir Sorgen darum machen muss, viele kleine Requests an den Server zu machen und kleine Antworten zurückzubekommen als früher. Da war es viel wichtiger zu gucken, dass man möglichst wenige Requests macht, weil dann wird halt immer diese Blockade riskiert. Und darum würde ich sagen, das sind die zwei wichtigsten Sachen. Einmal, dass wir uns weniger Sorgen um große Header machen müssen, die sich wiederholen und zum anderen, dass wir uns weniger Sorgen machen müssen um kleine Dateien, die wir einzeln verschicken. Das ist so die Revolution von HTTP/2 würde ich sagen.
Robert:
Okay. Das heißt nochmal zusammengefasst: Wenn ich deine alte Homepage lucas.de aufrufe mit den zehn besten Fotos von deinen letzten Sauerteigbroten, ich gebe jetzt einfach ungefragt all deine geheimen Hobbies hier Preis, dann würde ich HTML zurückbekommen und in dem HTML steht bestimmt ein bisschen Text drin und es sind zehn image tags darin. Und der Browser löst dann, wenn mein Browser das HTML zurückbekommt, nochmal zehn HTTP-Requests aus für jedes dieser Bilder, das bei dir verlinkt ist.
Lucas:
Genau.
Robert]:
Und HTTP/2, also auf lucas20.de, die selbe Seite mit HTTP/2, würde ich nur noch einen Request haben, der aber…
Lucas:
Nein.
Robert:
…offengehalten wird und gemultiplext ist. Also das habe ich noch nicht ganz verstanden.
Lucas:
Okay, also ich würde trotzdem elf HTTP-Request schicken hintereinander, aber der Server kann mir quasi auf derselben Leitung diese zehn beantworten und mir auf der selben Leitung miteinander verwoben die zehn Antworten zurückschicken. Sodass wenn das eine Bild irgendwie noch aus meinem tape drive gelesen werden muss und länger braucht, das halt den Rest der Bilder nicht blockiert, wenn das zufällig das erste war, was ich angefragt habe. Das heißt also wir haben Multiplexing auf der selben TCP-Leitung, kann man so sagen.
Robert:
Das heißt für mich als Mensch, der das versucht in den DevTools zu debuggen, dort sehe ich einfach auch wieder die zehn Folge-Requests, wie auch bei HTTP 1.1. Das ist für mich quasi transparent.
Lucas:
Ja. Und das ist das Schöne. Also wir müssen uns eigentlich überhaupt keine Gedanken darüber machen, denn das kann alles auf einer Ebene unter unserem Radar passieren. Aber wir müssen es wissen, weil es einfach Auswirkungen darauf hat, wie wir mit Daten und mit unseren Paketen umgehen können. Aber wir müssen dafür eigentlich überhaupt gar nichts beachten, wir müssen nur dafür sorgen, dass unser Server HTTP/2-fähig ist und dann alles andere passiert von selbst.
Robert:
Okay. Das heißt, gehen wir mal von deiner privaten Homepage weg und bewegen uns mal vielleicht zu einer komplexeren Unternehmensanwendung im Internet hin, die vielleicht sogar viele andere Seitenbestandteile von vielen anderen Systemen anbindet. Also vielleicht eine Versicherungsliste für einen Kunden in der Mitte anzeigt, eine Hauptnavigation oben, die von einem ganz anderen Host kommt, dann noch irgendwie ein übergeordnetes Kundenmenü, das von einem dritten Host kommt und dann noch zig Bilder oben drauf und 50 JavaScript-Dateien. Wenn ich sowas habe und jetzt entscheide in unserer Architektur unseren Webserver HTTP/2-fähig zu machen, dann ist das eigentlich gar nichts schlimmes, dass ich so viele kleinteilige Requests auslöse bisher, sondern es wird alles besser.
Lucas:
Genau!
Robert:
Ich muss an der Kleinteiligkeit eigentlich drehen, im Gegensatz dazu wird die Kleinteiligkeit sogar zum Vorteil, oder?
Lucas:
Genau, absolut! Also solche alten Hacks, wie irgendwelche image maps, die wo man halt irgendwie 50 Bilder in ein Bild reinpackt und dann immer zurechtschiebt und so, dass ist alle völlig überflüssig und vielleicht sogar kontraproduktiv. Weil man dann eben nicht diese Einzelteile dieses Bilder mehr einzeln cachen… die konnte man ja nicht einzeln cachen. Und das geht damit. Das heißt also, wir können einfach viel sorgloser kleine Pakete schicken und sollten das auch tun, wenn wir eine gute Caching-Strategie haben.
Robert:
Okay und jetzt sag mir bitte noch, dass ich mich nicht mehr drum kümmern muss meine ganzen JavaScript-Module und web components und was ich eben alles so habe, in einen großen Ball zu bundlen. Das nervt nämlich, auch wenn es coole Asset Pipelines wie faucet gibt und andere, die ich persönlich nicht so mag, wie webpack. Aber das nervt einfach, ich will mich damit nicht aufhalten! Wird das besser? Kann ich dann zum Beispiel meine zehn web components einfach in zehn script tags ausliefern?
Lucas:
Ja, also manche sagen, dass man das jetzt ganz ignorieren kann, ich würde nicht ganz so weit gehen. Also wir müssen nicht mehr ganz so sehr uns um dieses Bundling Sorgen machen. Also wenn wir wirklich eine überschaubare Anzahl von JavaScripts haben, sagen wir mal zehn, elf, dann würde ich sagen lohnt sich das Bundling vermutlich nicht mehr. Wenn wir jetzt ein riesiges JavaScript-Projekt haben aus hunderten von Files, weiß ich nicht ob ich das empfehlen würde. Weil das Problem, was weiterhin besteht, ist: Ich schicke einen… Ich möchte eine JavaScript-Datei haben, lade die runter und in der JavaScript-Datei sind fünf weitere verlinkt. Dann kann ich ja jetzt erst zu dem Zeitpunkt, wo ich diese Datei heruntergeladen und geparst habe, diese Anfrage schicken, dass ich fünf weitere haben möchte. Und wenn jetzt in den fünf Dateien nochmal jeweils fünf Dateien drinstehen, dann kann ich jetzt wieder erst diesen Request schicken. Das heißt also, solange ich quasi eine Liste… immer erst die Datei runterladen muss, um mir dann die Liste zu holen von weiteren Dateien, die ich runterladen möchte, ist das Problem nicht ganz weg. Aber auch dafür gibt es eine Lösung. Die ist aber… Also da gibt es quasi zwei verschiedene Lösungsansätze für. Der eine ist HTTP-Server Push, den würde ich jetzt einfach mal ignorieren, weil der jetzt aus Browsern teilweise wieder ausgebaut wird. Deswegen kann man den glaube ich ignorieren. Aber viel interessanter ist der Weg der Browser Hints. Browser Hints sind eine Möglichkeit, dass der Server sagt in wieder einen HTTP-Header: ‚Wenn du diese Datei hier gerader herunterlädst, dann gehe ich davon aus, dass du in naher Zukunft folgende dreißig Dateien auch noch möchtest!‘. Dann kann der Browser lokal gucken: Habe ich diese dreißig Dateien schon? Wenn nein, dann schicke ich jetzt einfach schon mal Requests los für diese dreißig Dateien und lade die alle gleichzeitig runter. Und mit diesem Trick kann ich tatsächlich quasi sagen: Ich habe diesen Baum von JavaScript-Dateien und sage dir am Anfang direkt schonmal welche du brauchen wirst und dann kann ich auf einen Schlag all diese Request auflösen und kriege die zurück. Und damit kann ich diesen Nachteil ausgleichen. Und das würde mir tatsächlich ermöglichen auf Bundling zu verzichten, muss man aber einfach mal ausprobieren, wie das in der Praxis bei einem funktioniert. Aber grundsätzlich ist das, also dieser Browser Hint ist eine Möglichkeit, dass tatsächlich zu umgehen.
Robert:
Okay, dann hänge ich mich jetzt an dieser Stelle aus dem Fenster und sage: Das Bundling der Zukunft ist einfach eine index.html mit sehr vielen script tags und wahrscheinlich diesen link tags, die ich brauche um dem Browser hints schonmal zu senden.
Lucas:
Ja, also würde nicht unbedingt sagen, dass es viele script tags sind, weil wir wollen am liebsten ja unsere Abhängigkeiten zwischen Dateien immer nur in unserem JavaScript drin haben. Das heißt, dass wahrscheinlich eine HTML-Seite und ein script tag, wo diese Start-JavaScript-Datei drin ist und dann halt jeder Menge entweder link tags, wie du das gerade gesagt hast, die wir im HTML schreiben oder link header, die wir in den HTTP-Header reinschreiben. Das ist die gleiche Mechanik, sind einfach nur zwei verschiedene Arten das auszudrücken. Und dann würde ich sagen, könnte man das so tun. Ja, absolut!
Robert:
Okay. Dann näher wir uns… Nein, wir sind über die Spielfilmlänge jetzt wirklich drüber, wir nähern uns nicht mehr. Sag mir doch noch kurz, HTTP/2 scheint mir jetzt, nach dem was du erklärt hast, so state of the art zu sein. Das sollten wir alle glaube einfach machen, oder?
Lucas:
Genau, absolut! Also ich würde sagen: Grundsätzlich: benutzt HTTP/2, benutzt gute moderne Kompressionsformate. Das sind Quick Wins, die könnt ihr einfach in eurer serverseitigen Software, egal ob das jetzt irgendwie nginx, Apache oder euer Framework oder was auch immer ist, einfach anschalten und dann kriegt ihr das kostenlos. Das lohnt sich, das macht einen Riesenunterschied und kostet euch quasi nichts.
Robert:
Okay. Erntet die niedrighängenden Früchte, die wir in dieser Sendung erwähnt haben! HTTP/2 verwenden ist eine davon, Compression solltet ihr HTTP/2 nicht verwenden. Vielleicht eine ältere Version ist ein anderes Thema, sind wir alle durchgegangen. Kurzer Ausblick noch: Gibt es noch was neueres als HTTP/2?
Lucas:
Genau, also ihr solltet auch Compression verwenden, wenn ihr HTTP/2 verwendet. Weil HTTP/2 nur die Header komprimiert und die Compression ja auch noch den Body komprimiert. Also da die Compression bitte beibehalten und nicht ausschalten. Aber ja, es gibt auch noch was neueres als HTTP/2 und das ist HTTP/3, überraschend für alle Leute, die Zahlen beherrschen. Das ist quasi das allerneuste in diesem Bereich. Dieser Standard ist noch nicht verabschiedet, zumindest zu dem Zeitpunkt, wo wir es jetzt hier aufnehmen, aber könnte jetzt jederzeit herauskommen als neuer Standard. Und das ist tatsächlich etwas, was sehr ähnlich ist halt zu HTTP/2, aber mit einem Unterschied. Nämlich dass es statt auf einer TCP mit TLS-Verbindung aufzusetzen, setzt es auf einer sogenannten QUIC-Verbindung auf. Das ist ein neues Protokoll, Transportprotokoll und das ist eigentlich, würde ich sagen, der Hauptunterschied zwischen HTTP/2 und HTTP/3, dass wir halt dieses QUIC-Protokoll einsetzen können. Und das verspricht halt auch nochmal einiges an Performancegewinn. Ich würde persönlich behaupten: Die Unterschiede zwischen HTTP 1.1 und HTTP/2 sind viel größer für uns als normale Webentwickler und Entwicklerinnen als der Unterschied zwischen 2 und 3. Das ist eher sowas was man braucht, wenn man irgendwie auf Google-Scale ist, dass man da drauf Rücksicht nehmen muss. Aber irgendwann wird auch das so verbreitet sein in Client- und Serversoftware, dass wir auch das einsetzen können und da die weiteren Gewinne rausholen können. Aber dafür ist es meiner Einschätzung nach noch etwas zu früh, weil da an vielen Stellen einfach noch der Support noch nicht gut genug ist und da sollten wir einfach nochmal ein bisschen warten bis wir auf diesen HTTP/3 Zug aufspringen. Aber das ist tatsächlich wirklich zusammengefasst alles, was man über HTTP/3 wissen muss. Es benutzt halt ein anderes Transportprotokoll. Das ist aber auch ein verlässliches Protokoll, also auch wieder eins, was keine Daten verliert und konzeptuell steht es quasi neben TCP und UDP, als drittes Transportprotokoll. Auch wenn es in der Implementierung etwas anderes funktioniert aus technischen, historischen Gründen, ist das quasi das, was uns HTTP/3 bringt. Aber da würde ich sagen, wartet nochmal ein bisschen ab bis ihr da euch mit näher beschäftigt. Guckt euch lieber mal HTTP/2 an, das ist das was euch heute schon große Vorteile bringt.
Robert:
Okay. Aber gesetzt den Fall, ich hätte vor meinem Host irgendwie ein reverse proxy stehen, Cloudflare ist ein Anbieter, es gibt ja noch andere und die können HTTP/3 schon mit so einem on-off-Schalter, also den einfach an und funktioniert das dann? Oder muss ich mir Sorgen machen, dass dann Clients meine Seite nicht mehr erreichen können, weil sie HTTP/3 noch nicht sprechen?
Lucas:
Genau, also genau wie HTTP/2 ist das halt eine Veränderung, die inhaltlich nichts verändert. Das heißt wir müssen in unseren Applikationscode überhaupt nichts verändern. Das heißt man kann in so einem reverse proxy diese Übersetzung vornehmen. Das heißt es kostet uns erstmal nichts das zu tun und grundsätzlich bietet… also schaltet man ja nicht HTTP/2 und HTTP 1.1 einfach ab und alle, die kein 3.0 können haben Pech gehabt. Das würde keiner machen glaube ich. Deswegen ist auch das kein Problem. Also grundsätzlich könnt ihr das einschalten, aber versprecht auch davon einfach nicht zu viel große Gewinne, dass das da euch jetzt alles ändert. Aber wenn ihr Software habt, die einen Schalter dafür anbietet, probiert es mal aus, wie so das Feedback ist und würde ich jetzt kein Problem mit sehen.
Robert:
Okay. Super, dann haben wir noch einen kleinen Ausblick in die Zukunft gemacht. Wobei HTTP/2 ist ja eher Gegenwart, nutzt es, HTTP/3 evaluiert es. Wenn man das in so Technology-Radar Sprechweisen einordnen würde. Lucas, danke! Wir machen hier mal Schluss. Wir haben ja Folge-Folgen versprochen in dieser Sendung.
Lucas:
Genau!
Robert:
Lasst uns doch einfach mal wissen, wie euch diese doch etwas längere Folge gefallen hat und wo wir vielleicht mal in einer anderen Folge gezielter drauf eingehen könnten. Das hilft uns sehr! Ansonsten habe ich keinerlei Fragen mehr, ich habe definitiv was dazugelernt heute. Danke, dass du da warst!
Lucas:
Sehr gerne!
Robert:
Und wir verabschieden uns bis zur nächsten Folge, oder?
Lucas:
Genau, das machen wir. Dann sage ich mal auf Wiedersehen!
Robert:
Tschüss!