Best pratices für Ajax in Rest ful designed Applications?


#1

Hallo,

derzeit stehe ich vor der Situation, eine Rails 1.2 Anwendung auf 2.2 zu
portieren. Die Ursprungsanwendung ist überhaupt nicht restful; zudem ist
JavaScript an vielen Ecken notwendig (soll auch so bleiben).
Nun wollte ich kurz in die Runde werfen, welche Designkriterien dazu
passen. Bislang sieht das ganze so aus:

A1) Wir nutzen Prototype-Helper aus Rails wo immer möglich
A2) Wir nutzen JSON nicht
A3) Jede Ajax-Action rendert ein .rjs template, dass eine Einsetzung /
Anpassung der View vornimmt.
A4) Keine Ajax-Action führt Änderungen in der Datenbank aus.
A5) Zur Verarbeitung der Ajax-Routinen, gibt es Funktionen in der
application.js, die von den .rjs Templates aufgerufen werden.

z.B.

  • Object O steht in einer belongs_to Relation B.
  • Via Ajax kann der Benutzer im Formular zu O ein passendes B suchen - o
    der er gibt an, dass er ein neues B erstellen will.
  • Die Wahl wird im Formular zu B vermerkt und bei der Verarbeitungs des
    Submits angewendet.

Dies bringt einige Probleme mit sich:
P1) Code ist ziemlich “zerhakt”. Es gibt ein labiles Zusammenspiel aus
partials, .rjs und application.js. Automatisiertes Refactoring ist
praktisch nicht möglich
P2) Die Controller sind durchzogen von AutoComplete, etc. Actions und
werden unübersichtlich

Welche Überlegungen sollte ich jetzt beim Refactoring Anwenden?

  • Gibt es Gute Alternativen zu A3)?
  • Ist es realistisch nach dem Grundsatz: “JavaScript-Code (der nicht von
    prototype-Helpern generiert wird), darf keine Attributnamen enthalten”
    zu verfahren?

Danke,
Bis Dene
Thorsten


#2

Hallo Thorsten,

was Du erzählst deckt sich eingentlich ziemlich genau mit meinen
Erfahrungen: exzessiver Einsatz von rjs führt in der Regel zu ziemlich
zerfleddertem Code. Keine Ahnung, ob man mehr (sehr viel
mehr…)Disziplin das auch in größeren Anwendungen sauber halten kann,
aber wenn man mehr Interaktion im Client hat, dann gibt es immer
irgendjemanden, der per js auf generierte ids zugreift, partials, die
zu viel tun, actions die extrem spezialisiert für einen ajax-call
irgendwas zusammen bauen usw. Ich bin immer noch der Meinung, dass das
weniger an uns liegt, als vielmehr an rjs - das taugt für eine
schnelle Demo, aber wenn’s größer wird, dann ist es kaum zu vermeiden,
dass es unübersichtlich wird.

Wir haben da irgendwann mal den Stecker gezogen und setzen seither rjs
entweder nur noch sporadisch für Prototypen oder sehr isoliert an den
Stellen ein, wo wir nur sehr wenig und dann sehr standardisiertes AJAX
brauchen. Größere Sachen machen wir eigentlich in der Regel mit ext
und frei nach Ajax-Head-Pattern (z.B.:
http://www.metaskills.net/2008/5/24/the-ajax-head-br-design-pattern)

  • ob man da jetzt ext oder dojo oder jquery oder sogar sproutcore/
    cappucino/gwt nimmt, spielt dabei eigentlich keine Rolle: Wichtig
    scheint mir dabei der Trend zu sein, deutlich mehr Funktionalität in
    den javascript-Client zu schieben und die Server-Seite dabei deutlich
    zu entrümpeln.

Bei uns hat das zu einer deutlicheren Trennung der Schichten und
loseren Kopplung geführt: Meistens kann man sich auf dem Server auf
sehr einfache(=besser wiederverwendbare) Controller beschränken), die
entweder per json oder xml die Daten zum Client hinpumpen, der dann
irgendwas damit macht und sie dann wieder zurückschreibt. Der Server
sagt eigentlich nichts mehr außer OK oder ERROR und jeder beschränkt
sich darauf, was er am Besten kann, keine Vermischung mehr, bessere
Testfähigkeit (weil weniger Kopplung), keine obskuren Code-
Generierungsprobleme und man kann damit dann auch wieder leichter
andere Clients (eine iphone-app, eine flex/air-client) usw. an die
Controller anschließen, weil eben kein rjs mehr rausgeworfen wird, mit
dem niemand was anfangen kann…

Nachteil der Geschichte ist, dass man mehr Zeit im Client mit
javascript verbringt, und nicht von Rails davor bewahrt wird, selber
javascript zu schreiben: Die Lernkurven für beinah jedes dieser
Frameworks sind schon recht steil, die API’s zum Teil kryptisch und
gewöhnungsbedürftig und mittlerweile auch einfach umfangreich -
irgendwie war’s auch schön einfach, alles aus einer Hand zu bekommen…

Vielleicht ist das kein Pattern für alles, aber bei uns hat’s an
einigen Stellen geholfen, den Wildwuchs deutlich zurecht zu schneiden…

Viele
GrüßeStefan

Am 15.02.2009 um 11:01 schrieb Thorsten Schmidt:

A1) Wir nutzen Prototype-Helper aus Rails wo immer möglich

  • o
    werden unübersichtlich
    Bis Dene
    Thorsten

rubyonrails-ug mailing list
removed_email_address@domain.invalid
http://mailman.headflash.com/listinfo/rubyonrails-ug


stefan frank


software&service
weberstr. 10
69120 heidelberg
tel. +49 (0) 6221 7277049
mobil +40 (0) 173 2383390
mail removed_email_address@domain.invalid


#3

Hallo,

Stefan F. schrieb:

uns liegt, als vielmehr an rjs - das taugt für eine schnelle Demo, aber
sproutcore/cappucino/gwt nimmt, spielt dabei eigentlich keine Rolle:
Wichtig scheint mir dabei der Trend zu sein, deutlich mehr
Funktionalität in den javascript-Client zu schieben und die Server-Seite
dabei deutlich zu entrümpeln.

Danke, für Deinen Input.
So wie ich Dich verstehe, werden bei diesem Ansatz wohl oder übel eine
ganze Reihe BO-Code in JavaScript implementiert werden.
Dies wollte ich eigentlich überhaupt nicht, denn

  • Wie modelliere ich am besten tests? Firewatir wäre eine Möglichkeit
    ist aber sehr langsam.
  • Ändere ich das DB-Schema, so muss ich den JavaScript-Code ggf. ändern.
    Dies widerspricht der ActiveRecord Philosophie, dass alles durch das
    DB-Layout definiert wird.

Nimmt man beide Punkte zusammen, so gibt dies imho eine teuflische
Mischung:
Wo knallt der JavaScript-Code, wenn ich ein Feld im DB-Schema umbenenne?

Wie löst Du das Problem?

Danke,
Bis dene
Thorsten


#4

durch das DB-Layout definiert wird.

Nimmt man beide Punkte zusammen, so gibt dies imho eine teuflische
Mischung:
Wo knallt der JavaScript-Code, wenn ich ein Feld im DB-Schema
umbenenne?

hmm, so rosig ist die Welt ja aber auch in rails ja nicht, oder?! Wenn
man in den Views explizit Felder referenziert, die dann aus der
Datenbank verschwinden oder dort umbenannt werden, dann knallt es da
auch im view - das ändert sich auch mit JavaScript als View nicht -
dein View ist also macht die DB-Felder also so oder so explizit und
ist daher auch von Änderungen abhängig. Es sei denn, man kommt
wirklich mit einer scaffolding-Lösung aus, die das ganze über
Introspektion löst. Das scheint aber in den seltensten Fällen wirklich
richtig gut bis in alle Verästelungen einer größeren Anwendung hinein
zu funktionieren, oder hat da jemand andere Erfahrungen?! Schlimmer
wird’s dann ja noch, wenn man irgendeine Art von Geschäftslogik auf
diesen Feldern abstützt (z.B. Konto nur belasten, wenn Konstostand >
0), dann lässt sich das DB-Schema erst recht nicht mehr ändern, ohne
dass es knallt - insgesamt kann ich den Satz, dass nur das DB-
Layout die Anwendung definiert, so - zumindest für uns - nicht
bestätigen.

Wo knallts’s bei uns: In der Regel an den selben Stellen, wo es auch
in normalen Views knallt: Wenn ein Feld dazu kommt, dann wird es nicht
automatisch angezeigt, da muss man in einer Tabelle das entsprechende
Feld dazu tun, den Editoren beibringen was sie wie anzuzeigen haben
usw. - die Schichten dazwischen sind davon nicht betroffen:
dem .to_json ist es natürlich egal, was es serialisiert…- knallen
tut’s daher an denselben Stellen, an denen es auch bei der Verwendung
von vielen partials und rjs knallt: Nämlich jedesmal, wenn man etwas
rendert was nicht mehr da ist oder umbenamst wurde usw.

selenium und firewatir benutzen wir nicht: das ist mir alles zu
fragil, zu kompliziert aufzusetzen und man ist eigentlich die meiste
Zeit damit beschäftigt, diese Testframeworks zum Laufen zu bringen,
aber vielleicht fehlt mir da einfach die Geduld (hat das jemand in
aller Schönheit mit Continous Integration und allem am Laufen??!)…
Wir testen komplett getrennt, erst den Server, dann die Clients.
Beinah jedes js-framework hat eigentlich ganz vernünftige unit-tests
(z.B. GWT,
http://www.ibm.com/developerworks/java/library/j-cq07247/index.html
oder sproutcore,
http://wiki.github.com/sproutit/sproutcore/unit-testing
oder auch die div. unit-test-frameworks für prototype oder jquery -
muss man zwar alles von Hand machen (gwt testen geht allerdings auch
von Eclipse aus) und es läuft nicht in der Continous Integration mit,
aber es ist viel praktikabler: Reicht in der Regel auch eigentlich
aus, weil die beiden Schichten klarer getrennt sind: Man kann ja den
Client auch erstmal ohne Server nur mit Mocks entwickeln… - sooo
teuflisch find ich das also eigentlich gar nicht: Man muss da nicht
religiös werden, wenn’s ans Testen geht: Es geht ja nicht um eine
besonders beeindruckende Toolkette, sondern nur darum, Fehler zu
finden und rauszuholen, egal wie…

Viele
GrüßeStefan