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

Antwort per Email an