rss feed articles activities all_comments

indeedgeek.de

Florian Eitel

Gedanken über URL's

Ich habe die letzten Tage etwas über vernünftige URL’s nachgedacht und mir sind dabei einige interessante Gedanken gekommen, die ich euch selbstverständlich nicht vorenthalten möchte. Wer sich wundert wie man über URL’s nachdenken kann, dem sei gesagt: Eine URL ist wohl eines der wichtigsten Merkmale einer Webseite. Sie ist das erste was man sieht und sie entscheidet ob man sich die Seite merken kann und evtl später noch einmal besucht. Zusätzlich kann eine gute Struktur auch entscheidend zu einer besseren Verfügbarkeit und Transparenz in größeren Netzen beitragen.

TLD – Top Level Domain

OK, prinzipiell ja eine ganz nette Idee aber die Ausführung ist ja mal mehr als misslungen. Das Problem ist, nur eine einheitliche Umsetzung würde hier Sinn machen. Wenn es funktionieren würde, fände ich die Regelung wie in Großbritannien nicht schlecht. Die unterscheiden einmal nach Land (UK) und dann nach Art der Webseite (co – commercial, gov – government, etc.) somit ergeben sich Kombinationen wie zum Beispiel .co.uk. Das Negativbeispiel ist wohl us: Dort gibt es vermutlich nur eine einzige Domain (del.icio.us) und selbst die nutzen offiziell nur noch com.

Die Unterteilung nach Art der Webseite (org, com, edu, gov, …) finde ich gut allerdings sollten sich auch alle daran halten. Zudem sollte es mehr Allgemeine Kürzel geben um detailierter abzugrenzen. Sonderregeln wie .pro welches nur für für eine Hand voll Berufsgruppen in noch weniger Ländern gilt könnte man sich ruhig sparen.

Unterscheidung nach Ländern finde ich umsonst. Die meisten Webseiten sind sowieso international und multilingual, so dass die TLD so gut wie keine Aussage mehr hat. Am Wildwuchs bei .com sieht man dies wohl am deutlichsten. Bestenfalls macht man mit der Landeskennung noch eine Unterscheidung welche Sprache angezeigt werden soll aber auch dies kann man in den Header des Requests auslagern.

Subdomains – www oder nicht www?

Ok, jetzt muss ich etwas in der Geschichte graben. Soweit ich das ganze verstehe war das mit den Subdomains folgendermaßen gedacht: Eine Domain repräsentiert zum Beispiel eine Firma, nun hat die Firma aber nicht Mail, DNS, Webserver auf der selben IP sondern vielleicht auf mehrere verteilt. Möchte man nun zu dem Webserver gibt man www.domain ein, für den ersten DNS ns0.domain und für Mail zum Beispiel mail.domain. Daher kommt auch das lästige www welches mal davor steht und manchmal nicht.

Eigentlich bräuchte man diese Unterteilung heute nicht mehr. Ich kann in meinem DNS Server für Dienste den srv Record angeben und somit kann der Client für den Dienst den er haben möchte die entsprechende IP beim DNS erfragen. Das schöne an den SRV-RR sind die Prioritäten die man schon vom MX-RR kennt. Diese lassen sich nun auch auf alle anderen Dienste anwenden.

Der Trend geht eher dahin die Subdomains für Abgrenzung der anzusprechenden Services zu “missbrauchen”. Also zum Beispiel für das Webmail webmail.domain oder für seinen Blog: blog.domain. Finde ich eine super Idee. Man muss im Hinterkopf aber auch die Rechner, für die ich auch einen Domainnamen vergebe. Zum Beispiel passt server03.domain nicht in den selben Namespace wie ein webmail.domain. Entweder ich spreche einen Rechner, eine Applikation oder ein Dienst (www) an. Das mag vielleicht etwas Kleinkariert erscheinen und vielleicht bin ich da etwas überempfindlich aber ich habe damit schlechte Erfahrungen gemacht. Vor allem wenn man DNS Einträge ändern und denkt “naja die werden schon alle svn.domain” nutzen und plötzlich kommt der erste angerannt der den selben Server unter einem anderen Domain Namen aufgerufen hat.

Zudem gibt es da wieder Probleme mit SSL-Zertifikaten da diese an einen Domainnamen gebunden sind. Somit bekommt man entweder den SSL-Fehler wenn man www weglässt oder eben wenn man es mit hin schreibt (lässt sich über "SNI"http://en.wikipedia.org/wiki/Server_Name_Indication beheben, ändert aber am Problem nichts). Auch ist eine Unterscheidung mit blog, webmail, ... sehr HTTP bezogen. Eigentlich kann man dagegen nichts sagen aber irgendwie habe ich einen schlechten Beigeschmack bei der HTTP Fixierung. (siehe weiter unten im Text)

Aktuell gefällt mir eine Unterscheidung nach Applikation am besten. Abgrenzung nach Service würde ich durch DNS erledigen lassen und so auch komplett auf ein www verzichten. Für Rechnernamen würde ich evtl einen extra DNS Namespace aufmachen also zum Beispiel *.servers.domain. Mein DNS Eintrag für blog.domain würde dann auf web01.servers.domain gelinkt eben so wie der SRV Record für HTTP.

(Ich weiß, natürlich das SRV Records nur von einer handvoll Clients und Diensten verwendet werden. Aber das ist wieder eine andere Geschichte.)

Ressourcen

So nun haben wir das ganze drum herum abgehandelt, jetzt kommen wir zu dem interessanten Teil. Es hatte sich ja eine Zeit etabliert einfach den Dateinamen wie home.html anzugeben. Mit aufkommen von PHP hat sich dies dann zum Teil soweit verlagert, dass nur noch eine index.php aufgerufen wurde die dann entsprechend mit Parametern gefüttert wurde. Ich finde beides sehr unschön. Man sollte nur auf Dateien referenzieren wenn man sie auch wirklich runterladen will. Wenn ich auf ein formular.pdf gehe dann erwarte ich, dass ich ein PDF-Dokument herunter laden kann. Wenn ich auf formular.php gehe möchte ich auch ein PHP-Dokument zum download bekommen. Alles andere, was die Applikation betrifft möchte ich bitte nicht an der URL erkennen. Der WebDav Standard spricht hierbei schön von Ressourcen und Collections. Ich finde diese Ansicht viel besser als die Datei/Ordner Sicht, da sie nicht erzwingt, das es sich auch wirklich um physische Dateien handelt. Ich finde URL’s sollten auch genau so aufgebaut sein, dass sie genau das zurückgeben was man erwartet. Ein Beispiel wäre /users welches alle User zurück gibt oder /users/horst welches mir den User Horst zurück gibt. Was dann wirklich im Hintergrund passiert ist mir als Nutzer völlig egal. Gott sei dank hat sich diese URL-Schemata in letzter Zeit weitgehend etabliert.

Verschachtelungstiefe

Ich finde man sollte hierbei aber darauf achten die Hierarchie von Müll, was vor der eigentlichen Applikation kommt, möglichst klein zu halten. Wenn ich also ein Webmail habe und die URL /webseiten/frontend/webmail/mails/today lautet dann betrifft die “Applikation” Webmail ja nur mails/today. Der restliche Müll wird vermutlich nur zur Organisation auf dem Server dienen. Das interessiert mich aber als Anwender wieder nicht. Hier wäre es zu überlegen ob man eine eigenen Subdomain Webmail macht und dann webmail.domain/mails/today verwendet. Aber da sind wie wieder bei der Frage um Subdomains.

Parameter

Ich glaube es gibt nichts schlimmeres als als eine URL die über drei Zeilen geht mit irgendwelchen kryptischen Session-ID’s. Diese URL ist komplett nutzlos. Sie ist nicht lesbar, sie ist nicht speicherbar sie ist nicht verschickbar. Erster Schritt zu einer besseren URL führt unweigerlich zu einer kompletten Löschung aller zustandsbehafteten Elemente wie die Session-ID’s. Eine URL sollte immer wenn man sie aufruft gültig sein und nicht nach 15 Minuten plötzlich ein kryptischen Fehler werfen. Zudem würde ich die Anzahl der Parameter möglichst gering halten. Das Meiste sollte über die Collections bereits abgefangen werden. Zum Beispiel finde ich /users/horst viel besser als ein /users?name=horst. Hingegen finde ich angaben wie Sortierung oder Selektierung (user 10-100) durchaus geeignete Kandidaten für Parameter.

REST

So wenn wir nun alles zusammen packen bekommen wir folgende URL: webmail.domain.edu/mails/333?format=raw. Webmail ist unsere Applikation/unser Service und mails ist die Collection in der wir die Ressource 333 auswählen und diese im Format raw-Output. Ich muss sagen ich bin damit schon relativ zufrieden. Wir möchten also die Ressource anzeigen. Was ist aber nun wenn wir mail 333 bearbeiten oder löschen wollen? Müssen wir dann jedes mal eine Operation als Parameter mitgeben?

Wenn man sich mal anschaut was der Browser an den Webserver schickt fällt auf, er fragt nicht nur nach der URL sondern gibt davor auch explizit an was er nun möchte. Meistens wird dies ein GET sein. Seltener mal ein POST und alles andere (DELETE, PUT,...) ist meistens schon gar nicht mehr implementiert. Über diese Methode kann ich in meinem HTTP Request also explizit sagen was ich gerne mit der Ressource die ich anfrage tun möchte. Wenn ich sie einfach Auflisten möchte schickt man ein GET und wenn man sie eben löschen möchte ein DELETE. Eigentlich eine super Idee die sich Representational State Transfer nennt.

Aber da passt was nicht zusammen! Wie schon geschrieben unterstützen die meisten Browser die Methoden gar nicht mehr vollständig. Das Problem liegt aber weniger an den Browsern. Ich denke mal so gut wie alle Webseiten verwenden HTML. HTML definiert Links auf andere Seiten. Allerdings ist HTML nur ein Markup Format welches nichts darüber aussagt wie es transportiert ist. Ich gebe nun in meinem HTML ein Link an und implizit wird angekommen ich bekomme dort mit einem GET Request genauere Informationen. Dies ist aber nur eine mögliche Sichtweise. Wenn man zum Beispiel Webseiten über XMPP, IMAP oder SMTP (ich hätte da echt nette Projektideen) austauscht dann könnte der Link zum Beispiel eine ganz andere Bedeutung haben. Allerdings deckt ein Link nur ein HTTP-GET ab. Möchte man nun ein DELETE auf eine URL aufrufen ist es mir nicht möglich dies in HTML kenntlich zu machen. Dies ist auch gut so, dann wie wir gerade gehört haben soll HTML ja gar nichts von dem darunter liegenden Transportprotokoll wissen. Der Parameter action in HTML Forms bildet hier wieder so ein Protokollbruch da ich hier explizit sagen kann ob ich ein GET oder POST Request mit den Daten starten will.

So das war nun ein bisschen viel auf einmal und vor allem alles sehr spekulativ. Was haltet ihr davon? Nutzt ihr SRV-Records? Schon Erfahrungen mit SNI gemacht? Und vor allem: Was denkt ihr über URL’s?

Comments:

(howto comment?)