Rest - Bilder mit Metadaten modellieren

mrBrown

Super-Moderator
Mitarbeiter
Ich bin aktuell dabei, eine REST-Schnittstelle zu modellieren, über die auch (u.a.) Bilder inklusive Metadaten abfragen lassen. Metadaten (zB Titel, Beschreibung, ...) und Bilder gehören dabei immer zu einer übergeordneten Resource

Bisher hab ich mehrere mögliche Varianten, wie man das modellieren könnte, aber sicher, welche am sinnvollsten ist, bin ich mir noch nicht...

Variante 1:
Bilddaten als Resource, Metadaten als Unterresource davon.
GET /context/images/42 -> liefert PNG
GET /context/images/42/info -> liefert JSON

Variante 2:
Variante 1 umgedreht, Metadaten als Resource, Bild als Unterresource.
GET /context/images/42 -> liefert JSON
GET /context/images/42/data -> liefert PNG

Variante 3:
Beide als eine Resource, je nach gewünschten Content-Type wird dann zB PNG oder JSON ausgeliefert.
GET "Accept: application/json" /context/images/42 -> liefert JSON
GET "Accept: image/png" /context/images/42 -> liefert PNG

Variante 4:
Eine Resource, die dann zB JSON ausliefert, wobei das Bild dann Base64-codiert eingebettet wird.
GET /context/images/42 -> liefert {data:"UG9seWZvbiB6...", name: "Blub"}

Variante 5:
Bilddaten als völlig eigene Resource, Metadaten verweisen dann auf die Bilddaten
GET /context/images/42 -> liefert {image:"/images/xyz", name: "Blub"}
GET /images/xyz -> liefert PNG



Irgendwer eine Meinung dazu, irgendwelche besonderen Vor-/Nachteile der einzelnen Varianten? Oder vielleicht sogar noch eine weitere (bessere) Variante?
 
Zuletzt bearbeitet:
X

Xyz1

Gast
Wieso lässt die nicht in den Bildern? Was Du mit "übergeordneter Ressource" meinst erschließt sich mir nicht.
 

mrBrown

Super-Moderator
Mitarbeiter

sascha-sphw

Top Contributor
Ich persönlich würde Variante 5 präferieren. Ich mag einfach die Trennung und mich würde es verwirren, wenn bei einem REST call auf einmal das Image zurück kommt.
 

mrBrown

Super-Moderator
Mitarbeiter
Ich persönlich würde Variante 5 präferieren. Ich mag einfach die Trennung
Führt halt dazu, das das Bild plötzlich keine Unter-Resource mehr ist, der Kontext verloren geht, und man immer den Weg über die Metadaten nehmen muss :/

mich würde es verwirren, wenn bei einem REST call auf einmal das Image zurück kommt.
Kommt es doch in jedem Fall, nur die Location ist unterschiedlich?
 

AndiE

Top Contributor
Ich könnte mir vorstellen, dass es eine übergeordnete Ressource A gibt, die zwei Unterressourcen hat: Einmal die Metadaten B und die Bilddatei C.

Begründung:
In der Tierdatenbank eines Tierparks hat man bestimmte Daten, die fest sind, wie Name, Geburtsdatum, Chipnummer und bestimmte Daten, die man immer nutzt, wie Fütterung usw. Das alles wäre A. Wer Vater und Mutter ist, und die Krankenakte wäre in meinem Fall B. Die Bilddatei, die ein Foto des Tieres enthält wäre dann C.
 

mrBrown

Super-Moderator
Mitarbeiter
In der Tierdatenbank eines Tierparks hat man bestimmte Daten, die fest sind, wie Name, Geburtsdatum, Chipnummer und bestimmte Daten, die man immer nutzt, wie Fütterung usw. Das alles wäre A. Wer Vater und Mutter ist, und die Krankenakte wäre in meinem Fall B. Die Bilddatei, die ein Foto des Tieres enthält wäre dann C.
In diesem Fall ist B allerdings eine Beschreibung, was auf Bild C zu sehen ist, zb ein Bild, welches ein Männchen und ein Weibchen zeigt, und die Beschreibung enthält dann, welches davon was ist und worin die sich unterscheiden ;) (und von B+c gibt es jeweils n Stück)

Davon gänzlich getrennte Resource gibt es natürlich auch noch, aber bei denen ist es jeweils ziemlich klar, wie man die modelliert.
 

mrBrown

Super-Moderator
Mitarbeiter
Warum willst Du die ID in Form von Unter-Ressourcen konstruieren, wozu brauchst Du den Kontext?
Brauchen ist vielleicht falsch gesagt, aber ohne Kontext haben sie einfach keine Bedeutung.
In DDD-Sprech: Kontext ist Aggregat, Bilder eine Entität dadrin.

Und fühlt sich irgendwie "RESTful-iger" an
 
X

Xyz1

Gast
Schau hier
2iD7U.jpg

https://stackoverflow.com/a/26410745

Es hat einer aufgemalt - und die Begrifflichkeiten sollte man auch wahren....
Unter Ressource verstehe ich nach dem Hashtag den Sprung....

Auf stack overflow steht auch iiiirgendwo das "RESTful" von Facebook erklärt.....

Eigentlich kannste machen was de willst.... nenne die Route doch nach einer Hashsum des Bilds....

BEARBEITUNG: Suche nach Rest routes best practices ---- tonnenweise wissenschaftliche Artikel und anderes!!
 

mrBrown

Super-Moderator
Mitarbeiter
Hat ein wenig gedauert, aber jetzt habe ich den Talk gefunden, den ich gesucht habe :)

Der ist ziemlich gut, danke!


Naja, die IDs sollen auch keine Bedeutung haben. Die bekommst Du doch ebenfalls über die REST-Schnittstelle.
Ja, Bedeutung ist in dem Fall hauptsächlich für Menschen gedacht.
Wobei: Kann man ohne Kontext in der URL bei einem POST zwei Resourcen einander zuordnen, ohne zwei Requests absetzen zu müssen?



Das eigentlich Problem verschiebt man so aber auch nur: Sind Bilddaten und Metadaten eine Resource und nur unterschiedliche Ansichten davon? Oder eher zwei getrennte, in Verbindung stehende?
 

mihe7

Top Contributor
Kann man ohne Kontext in der URL bei einem POST zwei Resourcen einander zuordnen, ohne zwei Requests absetzen zu müssen?
Ja. Zum Beispiel ein Archiv mit Metadaten und Bild rüber, der Server erzeugt dann die IDs und die Zuordnung untereinander.

Sind Bilddaten und Metadaten eine Resource und nur unterschiedliche Ansichten davon?
Das ist die große Frage. Im Semantic Web/Linked Data hat man ein ähnliches Problem. Hat man eine URI für ein Objekt, dann darf diese URI nur für dieses Objekt stehen. Hat man eine URL als URI, will man aber gleichzeitig Informationen über das Objekt abrufen. Gelöst wird dies dort z. B. per Content Negotiation.

Sprich: habe ich z. B. eine ID für mein Handy in Form einer HTTP-URL http://xyz/Mihe7sHandy, steht diese URL nur für dieses Handy. Kontaktiere ich die URL nun via Browser bekomme ich erst einmal einen Location-Header, der mir z. B. sagt: Infos via HTML unter http://xyz/Mihe7sHandy.html, will ich die RDF-Darstellung (Accept-Header), bekomme ich dagegen einen Location-Header gegen http://xyz/Mihe7sHandy.rdf (oder was auch immer).
 

AndiE

Top Contributor
Ich habe den Eindruck, dass ich euch nicht folgen kann. Ich habe REST immer für eine Übertragung gehalten, wo statt der RPC auf Anforderung ein Objekt zurückgegeben wird, im allgemeinen ein XML-Objekt. Die Anwendung selbst zeigt mir nicht, dass sie Daten aus dem Netz holt. Damit ruft die Anwendung mit einem Request den Server auf, und erhält als Responce ein XML-Objekt, das dann analysiert wird. Ungefähr so:

Code:
<person>
  <data>
    <name>Meier </name>
  </date>
  <pic>
  </Binärdaten />
  </pic>
</person>

Daraus kann dann die Anwendung das Bild mit Beschreibung herstellen.

Das wäre dann so, dass ich im Gegensatz zum RPC(Remote Procedure Call) mir gleich das Ergebnis als Objekt hole.
 

mrBrown

Super-Moderator
Mitarbeiter
Ja. Zum Beispiel ein Archiv mit Metadaten und Bild rüber, der Server erzeugt dann die IDs und die Zuordnung untereinander.
Meinte nicht die Zuordnung zueinander, sondern die Zuordnung zum Kontext ;) Üblicherweise wird das ja mit 'nem POST auf den Kontext gelöst.

IDs lassen sich in diesem Fall auch vom Client generieren, werden wohl sowieso UUIDs und sollte auch Offline-Fähig sein.

Das ist die große Frage. Im Semantic Web/Linked Data hat man ein ähnliches Problem. Hat man eine URI für ein Objekt, dann darf diese URI nur für dieses Objekt stehen. Hat man eine URL als URI, will man aber gleichzeitig Informationen über das Objekt abrufen. Gelöst wird dies dort z. B. per Content Negotiation.

Sprich: habe ich z. B. eine ID für mein Handy in Form einer HTTP-URL http://xyz/Mihe7sHandy, steht diese URL nur für dieses Handy. Kontaktiere ich die URL nun via Browser bekomme ich erst einmal einen Location-Header, der mir z. B. sagt: Infos via HTML unter http://xyz/Mihe7sHandy.html, will ich die RDF-Darstellung (Accept-Header), bekomme ich dagegen einen Location-Header gegen http://xyz/Mihe7sHandy.rdf (oder was auch immer).
Das wäre ja im wesentlichen Variante 3, bis auf das setzen des Location-Headers und zeige auf entsprechende URLs (mit Status 300?)

Wäre mir bisher die liebste Variante...



Ich habe REST immer für eine Übertragung gehalten, wo statt der RPC auf Anforderung ein Objekt zurückgegeben wird, im allgemeinen ein XML-Objekt

So ganz grob: Ja.
Der Rest deiner Antwort ist aber viel zu highlevel'ig gedacht. Mir gehts nicht um das wie und was die Anwendung draus macht, sondern wie ich die Schnittstelle designe.
 

mihe7

Top Contributor
Meinte nicht die Zuordnung zueinander, sondern die Zuordnung zum Kontext ;) Üblicherweise wird das ja mit 'nem POST auf den Kontext gelöst.
Dann verstehe ich die Frage nicht: "Kann man ohne Kontext in der URL bei einem POST zwei Resourcen einander zuordnen, ohne zwei Requests absetzen zu müssen?"

IDs lassen sich in diesem Fall auch vom Client generieren, werden wohl sowieso UUIDs und sollte auch Offline-Fähig sein.
Klar kannst Du die UUIDs clientseitig generieren, Du weißt aber nicht, welche URL der Server daraus macht.

Das wäre ja im wesentlichen Variante 3, bis auf das setzen des Location-Headers und zeige auf entsprechende URLs (mit Status 300?)
Nein. Variante 3 bedeutet eine URL, die zwei verschiedene Ressourcen identifiziert -> darf nicht sein.

Anderes Beispiel: Die ISBN 978-3-608-96376-2 ist eine ID für ein Buch. Diese kann man auch als URI urn:isbn:978-3-608-96376-2 darstellen und anhand dieser URI z. B. mit RDF Aussagen über dieses Buch treffen:
Code:
<urn:isbn:978-3-608-96376-2> <http://purl.org/dc/elements/1.1/title> "Kurze Antworten auf große Fragen"
Ob die URI nun als urn:isbn oder HTTP-URL angegeben wird, spielt dabei zunächst mal keine Rolle: es ist einfach eine ID, die nicht z. B. via Internet abrufbar sein muss (ähnlich wie bei vielen XML-Namespaces).

Nehmen wir mal an, ich würde statt der URN die URL http://example.com/9783608963762 verwenden. Dann liegt es nahe, unter dieser URL entsprechende Informationen zur Verfügung zu stellen.

Würde man aber einfach z. B. eine HTML-Seite als Antwort bekommen, hat man das Problem, dass ein und dieselbe URL einerseits das Buch und andererseits die HTML-Seite identifiziert. Da dies der Natur eines Identifikators widerspricht, hat man (denke, es war Tim Berners-Lee) sich überlegt, dass der Server nicht mit Inhalten antworten darf, sondern auf entsprechende URLs verweist (303 See Other).

Beispielabrufe:
Code:
# curl -I https://www.wikidata.org/wiki/Special:EntityData/Q341
HTTP/1.1 303 See Other
Location: https://www.wikidata.org/wiki/Special:EntityData/Q341.json

# curl -I "Accept: text/html" https://www.wikidata.org/wiki/Special:EntityData/Q341
HTTP/1.1 303 See Other
Location: https://www.wikidata.org/wiki/Q341
 

mrBrown

Super-Moderator
Mitarbeiter
Dann verstehe ich die Frage nicht: "Kann man ohne Kontext in der URL bei einem POST zwei Resourcen einander zuordnen, ohne zwei Requests absetzen zu müssen?"
zB, das Bild soll dem Nutzer /user/42 zugeordnet werden.
Üblich wäre meistens dann ein POST /user/42/images. Wenn man den Kontext aus der Url weglässt, muss man entweder wieder zwei Requests absetzen, oder /user/42 in Body oder Header mitgegeben, oder nicht?

Klar kannst Du die UUIDs clientseitig generieren, Du weißt aber nicht, welche URL der Server daraus macht.
Der kann die ja als "templated Url" vorgeben.

Nein. Variante 3 bedeutet eine URL, die zwei verschiedene Ressourcen identifiziert -> darf nicht sein.
Ja, wie gesagt bis auf den Unterschied :p

Gibts nen sinnvollsten Weg, wie man POST da umsetzt?
 

mihe7

Top Contributor
B, das Bild soll dem Nutzer /user/42 zugeordnet werden.
Üblich wäre meistens dann ein POST /user/42/images. Wenn man den Kontext aus der Url weglässt, muss man entweder wieder zwei Requests absetzen, oder /user/42 in Body oder Header mitgegeben, oder nicht?

Du bekommst vom Server z. B. für einen Benutzer eine URI mitgeteilt, mit der die "Menge seiner Bilder" ;) identifiziert wird.

Ob und falls ja, dass in der URI "zufällig" die Benutzer-ID auftaucht, spielt auf Clientseite keine Rolle. Wenn der Server Dir für "die Menge der Bilder des Benutzers 42" die URI /fsda/xsj2904s statt /usr/42/images zurückgibt, und Du den POST ausführst, ist mit der URI trotzdem die "Menge der Bilder des Benutzers 42" identifiziert.

Der kann die ja als "templated Url" vorgeben.

Schon, aber wozu?
 

mihe7

Top Contributor
Hm... ich frage mich gerade: kann der Server heute wissen, unter welcher URL er morgen/nächste Woche eine Ressource bereitstellt? Theoretisch sollte das funktionieren.
 

Ähnliche Java Themen

Neue Themen


Oben