Anon: RESTful Index

Bin grade dabei, meine ersten RESTful-Architekturen zu entwerfen. Dabei bin ich auf zwei Hürden gestoßen, die bestimmt schon von anderen vor mir genommen worden sind; habe dazu aber im REST-Wiki nix gefunden.

Fall 1.
Es existieren vergeschwisterte, aber diskrete Ressourcen. Deren Namensraum habe ich bequemerweise auf einer Adressebene abgebildet, z.B.:
http://example.com/Diagramme/Frobnitzer
http://example.com/Diagramme/Transmogrifizierer
http://example.com/Diagramme/Handtuch_(flauschig)

Fall 2.
Es existiert eine Ressource, die sich über die Zeit ändert. Ich möchte nicht nur die jeweils aktuelle Version anbieten, sondern auch die vorhergehenden. Dazu bilde ich den Zeitstempel auf die URI ab, weil eine UA-seitige Auswahl durch HTTP-Header (Accept-* usw.) nicht gegeben ist.
http://example.com/foo
http://example.com/foo/2009-02-11
http://example.com/foo/2009-02-10
http://example.com/foo/2009-02-09

Für beide Fälle: Was ist der kanonische Weg, einen Index über diese Ressourcen anzubieten? Muss ich dafür mein eigenes HTTP-Verb erfinden oder gibt es schon etwas standardmäßiges in Benutzung? Welche URI wähle ich, was wäre ein geeigneter Content-type für den Index?

Forum, das ist deine Gelegenheit, zu glänzen. Go go!

  1. Hallo,

    Bin grade dabei, meine ersten RESTful-Architekturen zu entwerfen. Dabei bin ich auf zwei Hürden gestoßen, die bestimmt schon von anderen vor mir genommen worden sind; habe dazu aber im REST-Wiki nix gefunden.

    Fall 1.
    Es existieren vergeschwisterte, aber diskrete Ressourcen. Deren Namensraum habe ich bequemerweise auf einer Adressebene abgebildet, z.B.:
    http://example.com/Diagramme/Frobnitzer
    http://example.com/Diagramme/Transmogrifizierer
    http://example.com/Diagramme/Handtuch_(flauschig)

    Fall 2.
    Es existiert eine Ressource, die sich über die Zeit ändert. Ich möchte nicht nur die jeweils aktuelle Version anbieten, sondern auch die vorhergehenden. Dazu bilde ich den Zeitstempel auf die URI ab, weil eine UA-seitige Auswahl durch HTTP-Header (Accept-* usw.) nicht gegeben ist.
    http://example.com/foo
    http://example.com/foo/2009-02-11
    http://example.com/foo/2009-02-10
    http://example.com/foo/2009-02-09

    Für beide Fälle: Was ist der kanonische Weg, einen Index über diese Ressourcen anzubieten? Muss ich dafür mein eigenes HTTP-Verb erfinden oder gibt es schon etwas standardmäßiges in Benutzung?

    Ich würde sagen, das ist ein Fall von „zuviel Bäume“. Der REST-Stil berührt keine Indizes von Ressourcen, er beschäftigt sich nur mit dem gleichen Zugriff auf Ressourcen. Selbst WebDAV, dessen collections als Indizes gelten können, nutzt GET.

    Welche URI wähle ich ...

    Ein Index von Ressourcen ist wieder eine eigene Resource. Eine Resource hat eine URL. Welche URL? Das ist wurst, wichtig ist aus REST-Sicht nur, dass man GET darauf ausführen kann. Für den REST-Stil ist die Syntax der URI opak, REST beschäftigt sich nicht mit Namen:

    “Semantics are a by-product of the act of assigning resource identifiers and
      populating those resources with representations. At no time whatsoever do the
      server or client software need to know or understand the meaning of a URI —
      they merely act as a conduit through which the creator of a resource (a human
      naming authority) can associate representations with the semantics identified
      by the URI.”
      REST: 6.2.4 Binding Semantics to URI

    Anders gesagt, man kann auch RESTig sein, wenn man URLs nach dem Schema http://example.com/E20B5654-4CB0-4A19-9282-7368B4FE14BE.DE-de.html münzt. Das ist natürlich nicht toll zum Debuggen oder zu Orientierung von Nutzern, insofern kann man seine eigene Semantik in den URL-Pfad legen. Ich würde mich an den best practice Muster des real existierenden Webs orientieren. Im ersten Fall dann http://example.com/Diagramme/ (Ich persönlich finde den trailing slash überflüssig; viele Tools des tatsächlicen Webs beziehen ihn aber ein). Im zweiten Falle könnte http://example.com/foo als Resource und gleichzeitig als Index dienen, zumindest in der Repräsentation HTML. Oder /foo/versions. Oder, oder. Ich privat hab die Vorstellung, dass Pfad-Segmente Nomen sind, die durch Query-Parameter parametrisiert werden; /foo?version=2009-02-12 wäre also auch eine Möglichkeit. Aber wie gesagt: In REST sind alle URIs gleich.

    ... was wäre ein geeigneter Content-type für den Index?

    Das ist eine interessantere Frage. Letztendlich wohl der Typ, von dem erwartet werden kann, dass eventuell drauf zugreifende Klient sie verarbeiten kann. Oder in der Umkehrung der Last: Klienten, die den vorgegebenen Content-Type verarbeiten können. ;)

    Praktischerweise wäre es sinnvoll zu gucken, wo woanders die Probleme gelöst werden und warum. In WebDAV gibt es collections, allerdings baut man damit eine Erwartungshaltung auf die anderen Features von WebDAV auf, die man möglicherweise nicht erfüllen will. Eine andere Variante wäre es zu gucken, was die minimalen Anforderungen an einen Eintrag bzw. an die Metadaten eines Eintrages im Index sind. Tatsächlich ist so ein anderes Format gestartet, dass sich auch für Indizes eignet, Atom Feeds. Ein Eintrag hat hier eine global eindeutige Identität (atom:id), die letzte Änderung (atom:updated), einen Titel (atom:title) und am wichtigsten mit atom:link eine Möglichkeiten, andere Ressourcen zu referenzieren. Für weitere Metadaten kann man weitere Elemente nutzen oder beliebig erweitern z.B. andere Feed-Erweiterungen zur Interoperabilität nutzen. Tatsächlich wird das Atom Feed Format als Index in einer REST-basierenden API genutzt, die auf Einträge in Kollektionen operiert – der Atom API.

    Und natürlich kann man in einer RESTigen Welt auch mehrere Content-Typen anbieten. Allerdings muss man in anderen Metasyntaxen oft das Rad neu erfinden. Für JSON z.B. zur Verwendung im Browser muss man sich die Strukturierung und deren Semantik selbst bauen; für HTML sowieso. Den einzig glücklich machenden Content-Type gibt es im REST-Land nicht. Man beachte auch die Bedeutung des Ts in REST. ;)

    Tim

    1. Hi,

      Im ersten Fall dann http://example.com/Diagramme/ (Ich persönlich finde den trailing slash überflüssig; viele Tools des tatsächlicen Webs beziehen ihn aber ein). Im zweiten Falle könnte http://example.com/foo als Resource und gleichzeitig als Index dienen, zumindest in der Repräsentation HTML. Oder /foo/versions. Oder, oder.

      genau. Oder die Semantik einführen, dass das Schlagwort "index" (resp. "Index") auf den Index schließen lässt: http://example.com/Diagramme/index, http://example.com/foo/index - das ist i.d.R. auch gut automatisierbar. Wenn Du den Index dann noch in verschiedenen Formaten ausliefern möchtest (HTML, Text, CSV, ...), könnte dies beispielsweise zu .../index.html, .../index.txt, .../index.csv und so weiter führen.

      »» ... was wäre ein geeigneter Content-type für den Index?

      Beim letztgenannten Vorschlag ergibt sich das von selbst ;-)

      Cheatah

      --
      X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
      X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
      X-Will-Answer-Email: No
      X-Please-Search-Archive-First: Absolutely Yes
    2. Dies war e(?:in|r)leuchtend. ⇒ Tim++