On Friday 01 June 2007, Stefan Tilkov wrote: > On Jun 1, 2007, at 7:06 PM, Michael Schuerig wrote: > > Ich habe gerade das sehr empfehlenswerte Buch "RESTful Web > > Services" von > > Leonard Richardson und Sam Ruby gelesen. > > Ah, mein Lieblingsthema :-) ... und ein gutes Buch, siehe auch > http:// www.infoq.com/articles/richardson-ruby-restful-ws > > > Für eine Frage, die mir unter > > den Nägeln brennt, habe ich dort leider keine Antwort gefunden. Die > > Frage hat auch eigentlich nicht mit einem Web*service* sondern mit > > einer Web*anwendung* zu tun. > > Genau genommen würde ich da gar keinen Unterschied sehen ;-)
Was soll ich sagen? Wenn ich einen so großen Unterschied sähe, würde ich wohl nicht fragen. :-) > > In Rails gehört es inzwischen zum guten Ton, Anwendungen REST-gemäß > > zu strukturieren. Das funktioniert allgemein für die üblichen > > Aktionen auch völlig problemlos. Nicht so einfach finde ich es für > > Ajax-Requests. Konkret habe ich zwei Fälle > > > > update_ui > > > > Manche Formulare sind dynamisch und zwar nicht nur so, dass Teile > > ein- und ausgeblendet werden könnten, sondern die > > Auswahlmöglichkeiten in Listen hängen davon ab, welcher Wert in > > einer anderen Liste ausgewählt wurden. Die genauen Zusammenhänge > > sind Teil der Geschäftslogik gehören dementsprechend in eine > > Model-Klasse. > > > > Wenn der Benutzer nun eine Eingabe vornimmt, die eine Änderung des > > Formulars erfordert, so wird ein Ajax-Request an den Server > > geschickt, der entscheidet, was passieren soll und per RJS ein > > geeignetes JavaScript an den Client zurück schickt. > > Wie strukturierst Du Deine Anwendung? Funktioniert sie auch, wenn > JavaScript deaktiviert ist? Wenn ja, lässt sich die RJS-Variante als > eine andere Repräsentation der Ressource sehen, die Du im Nicht-JS- > Fall verwendest? Nein, ohne JS läuft da gar nichts. Da es sich um eine interne Anwendung handelt ist das so auch in Ordnung. Öffentlich würde ich das anders angehen. > > poll > > > > Der Client sendet regelmäßig einen Ajax-Request an den Server, der > > u.a. > > die Versionsnummer des bearbeiteten Objekts enthält. Der Server > > prüft, ob diese Version noch aktuell ist, wenn nicht, sendet er ein > > JavaScript > > zurück, dass eine Nachricht anzeigt und das Formular sperrt. > > Ditto - wobei ich in diesem Fall fragen würde, ob das (R)JS nicht > eher in den View gehört? Das (R)JS wird im Controller erzeugt, allerdings ist das dort nur eine dünne Verpackungsschicht über den Daten, die gemäß der Geschäftslogik aus den jeweiligen Model geliefert werden. In diesem konkreten Fall haben alle relevanten Models eine Klassenmethode #stale?. Die Standardmethoden der Controller erzeuge ich dynamisch, wobei dann http://example.com/things/poll/7/10 (id/revision) von dieser Methode behandelt wird def do_poll(model_class, params) if model_class.respond_to?(:stale?) if params[:id].to_i != 0 if model_class.stale?(params[:id], params[:revision].to_i) render :update do |page| page.application.show_message "Another user has changed the #{model_class.name.humanize} in the meantime.", 'error' page.application.object_is_stale end return end end end render :nothing => true end In application.js sind var Application = { showMessage: function(...) { ... }, objectIsStale: function() { ... } }; definiert. > > Nun könnte ich möglicherweise mit ein paar Namensänderungen einfach > > behaupten, dass auch diese Requests eigentlich auf Ressourcen > > zugreifen. Und JavaScript ist ja neben HTML und XML auch nur eine > > Repräsentation unter anderen. -- Vielleicht hat aber schon jemand > > einen > > eleganten Weg gefunden. > > JS (bzw. code on demand) ist zwar durchaus RESTful, aber in Bezug auf > die Sichtbarkeit Deiner Ressourcen immer ein wenig kritisch. Kannst > Du Deinen Fall noch detaillieren? Ich konstruiere mal ein vergleichbares Beispiel, einen Konfigurator für einen Neuwagen. Angegeben werden müssen Model, Variante, Motor, Farbe, Polsterfarbe, Bereifung. Zwischen diesen Parametern gibt es einige Constraints. Für manche Varianten werden nur bestimmte Farben und Polsterfarben angeboten, wobei auch die Farbe die Polsterfarben einschränkt. Wenn der Benutzer nur einmal oder nur selten durch eine solche Konfiguration durch müsste, dann würde ich sie über mehrere Bildschirmseiten verteilen. In meinem konkreten Fall ist das anders, da sollen alle Parameter in einem Fenster sichtbar und änderbar sein, was häufig vorkommen kann. Im Augenblick handhabe ich das so, dass bei allen Parameteränderungen, von denen clientseitig bekannt ist, dass sie die Auswahlmöglichkeiten ändern, ein Request an den Server geschickt wird, der JS zurückliefert, welches wiederum das Formular geeignet anpasst. Das funktioniert nur, weil beide Seiten viel von einander wissen. Der Client weiss, explizit in JavaScript hinein programmiert, welche Änderungen er dem Server mitteilen muss; der Server weiss, wie er die clientseitige Darstellung beeinflussen kann. Für eine Web*anwendung* halte ich das so gerade für vertretbar. Für einen *Service* wäre es unbrauchbar. Es ist aber eine Anwendung (puh!). Ausserdem: als ich diesen Teil programmiert habe, war ich noch minder erleuchtet (oh!). Ein großer Vorzug ist obendrein, dass der Code insgesamt ziemlich überschaubar ist. Ich habe, sinngemäß http://example.com/cars/update_ui/7?model=X&variant=Y&... was einen RJS-generierten Mischmasch aus Funktionsaufrufen und HTML-Fragmenten liefert, die irgendwie das richtige tun. Resource-oriented könnte ich eine ganze Reihe von "algorithmischen" (berechneten, parametrisierten) Ressourcen definieren http://example.com/cars/available_motors?model=X&variant=Y&... http://example.com/cars/available_colors?model=X&variant=Y&... ... die zweifellos allgemeiner wären. Mir aber clientseitig viel mehr Mühe bereiten würden: mehrere Ajax-Requests statt nur eines einzelnen. Vermutlich mehr Arbeit, die erhaltenen Daten ins DOM einzusortieren. Da gibt es für eifrige RESTronauten sicherlich einige Hektar Spielwiese. So, ich habe viel geschrieben, aber viel schlauer bin ich trotzdem noch nicht. Michael -- Michael Schuerig mailto:[EMAIL PROTECTED] http://www.schuerig.de/michael/ _______________________________________________ rubyonrails-ug mailing list [email protected] http://mailman.headflash.com/mailman/listinfo/rubyonrails-ug
