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?)