Shownotes & Links
- Das Buch
- Benson Coffee
- Blog Post: Rails is Omakase
- thoughtbot
- Hashrocket
- ActiveJob
- Redis
- Sidekiq
- GoodJob
- RabbitMQ
- The Rails Foundation
- Active Record Pattern
- Data Mapper Pattern
- minitest
- RSpec
- capybara
- ViewComponent
- Blog Post: Cookie-based Spring Security Session
- Content Security Policy
- Rails Security Guide
- INNOQ Security Podcast: Adventskalender
- RailsDiff
Transkript
Robert: Hallo, Lucas.
Lucas: Hallo, Robert.
Robert: Hallo, liebe Hörerinnen und Hörer. Wir sind’s wieder, mit dem INNOQ Podcast. Heute drehen wir den Spieß wieder leicht um, aber niemand interviewt hier irgendwen, sondern wir führen ein Gespräch auf Augenhöhe. Ich bin mal nach Längerem wieder da. Lucas ist auch wieder da. Der ist hier viel öfter als ich. Wir unterhalten uns heute über eins unserer Lieblingsthemen.
Lucas: Genau. Wir wollen heute ein bisschen über Ruby on Rails sprechen. Das ist eine gemeinsame Leidenschaft von Robert und mir, neben dem Kaffee, die wir immer teilen.
Robert: Deswegen ganz vorneweg - nicht abschalten. Stopp! Falls ihr keine Rails Erfahrung habt, falls ihr in ganz anderen Programmiersprachen, mit ganz anderen Frameworks arbeitet, vielleicht auch noch nie Ruby gesehen habt, gehört habt oder benutzt habt, bleibt bitte dran. An euch richtet sich diese Folge. Wir versuchen hier heute nicht “unter uns zu bleiben” und einfach über die Rails Neuerungen zu sprechen, sondern wir wollen das heute etwas anders machen. Und zwar heißt die Folge “The Rails Way”, der Rails Weg. “Weg” hätte ich jetzt fast gesagt. Götz, das brauchst du nicht rauszuschneiden. So viele Fehler erlauben wir uns heute. Deswegen, bleibt uns bitte erhalten. Wir versuchen eine Folge für alle zu machen, die für alle interessant ist und für alle hoffentlich einen Mehrwert hat. Lucas, du hast gerade schon gesagt: Kaffee ist im Glas. Was ist denn heute im Glas oder in der Tasse?
Lucas: Ja, ich habe heute einen leckeren Kaffee aus Peru. Von einem Röster aus Köln. Benson Coffee, unbezahlte Werbung, den ich wirklich toll finde. Wenn ihr da in der Nähe mal seid, dann holt da auf jeden Fall auch mal einen Kaffee. Der macht wirklich hervorragende Kaffees und genau den trinke ich heute schön zum Podcast. Und du?
Robert: Ja, ich brauche da auch mal so einen. Wir nehmen nachmittags auf, bei -5 Grad und 90% Luftfeuchtigkeit draußen. Ich brauche da auch einen Kaffee zum Warmwerden. Ich habe tatsächlich Costa Rica im Glas. Ein traditionell “Washed Coffee”. Auf der Packung steht: Schmeckt nach Chocolate Ganache und Feige. Ich unterschreibe das, es stimmt.
Lucas: Oh, interessant.
Robert: Ich habe auch mal wieder meine Aeropress ausgemottet. Für die kleinen Mengen am Nachmittag funktioniert das irgendwie besser als der V60.
Lucas: Das stimmt, das stimmt. Das mache ich eigentlich auch ganz gerne am Vormittag eine V60 und am Nachmittag eine Aeropress, wenn es dann noch drin ist.
Robert: Das ist ganz gut, wegen den Mengen am Nachmittag. Wenn ich mir da nochmal 250 Milliliter gönne, dann schlafe ich schlecht.
Lucas: Das stimmt, das stimmt. Daran merkt man, dass man alt wird.
Robert: So, jetzt lass uns zum Thema übergehen.
Lucas: Genau. Ich habe gerade noch mal auch über das nachgedacht, was du gesagt hast. Mir ist eine Sache auch wichtig und das ist auch eine Sache, die ich vor allem in meiner Zeit bei INNOQ gelernt habe. Jedes Ökosystem erfindet irgendwie die gleichen Dinge immer noch mal. Irgendwann kommt jede Programmiersprache darauf: Ich brauche jetzt einen Paket Manager. Und dann braucht man ein Paket Manager. Da ist es leider viel zu oft so, dass man zu wenig darauf guckt, was in den anderen Ökosystemen in dem Bereich vielleicht schon passiert ist und was man daraus mitnehmen kann. Man muss es nicht kopieren, man muss nicht 1:1 das Gleiche machen. Aber ich finde es gut, wenn man eine informierte Entscheidung darüber trifft. Was wurde schon probiert? Was waren Vor- und Nachteile? Und dann darauf aufbaut und nicht einfach so tut, als hätte es das noch nie gegeben, als hätte noch nie jemand dieses Problem gelöst. Das fand ich bei INNOQ auch auf den Events so interessant. Einfach mit Leuten zu sprechen, die mit ganz anderen Technologien Tag für Tag arbeiten und einfach zu hören: Was haben die für Probleme? Was haben die für Lösungen? Und das auch einfach offen aufzunehmen, zu hören: Das ist auch eine gute Idee, das zu machen. Das kann nicht so sein, dass man da dann immer auf die gleiche Lösung kommt und dass man sich einig ist, dass das die beste Lösung ist. Es gibt auch immer verschiedene Lösungen, aber ich fände es wirklich schön, dass wir uns auch ein bisschen mehr als eine Community sehen. Also gerade jetzt die Leute, die Webanwendungen bauen. Unsere Probleme sind sich doch relativ ähnlich. Und dann einfach zu schauen: Was machen die anderen? Wie wollen wir das lösen? Und an welchen Stellen wollen wir vielleicht auch mal einen ganz anderen Weg ausprobieren? Ich würde sagen bei Paket Manager muss man jetzt nicht mehr so viele Experimente machen. Da haben wir schon ganz gut rausgefunden, was da gut funktioniert und was nicht. Aber in Web Frameworks, da gibt es eben doch Bereiche, wo die Ideen weit auseinandergehen oder vielleicht auch der Fokus von verschiedenen Web Frameworks auf verschiedenen Teilen von Webanwendungen liegt. Das finde ich cool, wenn man da mehr Austausch hat. Das ist ein bisschen das, was wir mit hier reinnehmen wollen. Es geht jetzt nicht darum zu sagen: Das was Rails macht, ist die einzige Lösung und alles andere ist irgendwie Quatsch. Vielleicht einfach Ideen mitzugeben und zu schauen: Wie ist das denn in meinem Web Framework? Gibt es da auch Lösungen, vielleicht muss ich dafür noch eine Library installieren, um das zu bekommen. Oder vielleicht finde ich das auch doof. Da hören wir auch gerne von euch: wenn ihr sagt: “Hey, das und das ist einfach eine furchtbare Lösung. In dem Framework, in dem ich am liebsten arbeite, da ist das anders gelöst”, das hören wir gerne. Schreibt uns da auch gerne eine Mail zu, wenn ihr da was auf dem Herzen habt.
Robert: Genau, schreibt uns unbedingt eine Mail an [email protected]. Wir hören sehr gerne von euch. Wir tun das leider viel zu selten, weil wir viel mehr auffordern müssen. Wir tun das jetzt auch, wir wollen wirklich wissen, da melden wir uns im Laufe der Sendung noch mal zu. Habt ihr von Rails was gelernt oder habt ihr euch zumindest inspirieren lassen? Oder wisst ihr von Dingen, wo ihr sagt: Das kann nicht wahr sein, so macht man das nicht. Schreibt uns, wir freuen uns, von euch zu hören. Wir haben einen Aufhänger, wir hätten uns heute auch um ein anderes Framework drehen können, aber wir wählen Rails aus einem gewissen Anlass. Das schicken wir als kleinen Disclaimer noch mal hier, bevor wir richtig einsteigen, vorne raus. Der Lucas ist Autor, Co-Autor eines Buchs. Das nennt sich “The Rails 7 Way” und ist jetzt gerade in der Finalversion erschienen auf Leanpub, richtig?
Lucas: So ist es, genau.
Robert: Du hast ein Railsbuch geschrieben. Das heißt, du wirst auch ein paar Dinge über die Framework Interna wissen. Du schreibst auch schon mit deinen Co-Autoren, die sind, vielleicht magst du noch mal nennen?
Lucas: Genau, das Buch ist ursprünglich in der ersten Edition von Obie Fernandez geschrieben worden und seit dem “Rails Six Way” ist das Team vergrößert worden. Da sind der Tom Henrik Aadland und ich dazugekommen als weitere Autoren. Und jetzt sind wir zu dritt und arbeiten zu dritt an dem Buch.
Robert: Okay. Das Buch ist aber jetzt final fertig. Vielleicht gibt es natürlich noch iterative Updates.
Lucas: Absolut, genau. Es ist jetzt inhaltlich vollständig. Wenn jetzt irgendjemand einen Fehler findet, dann werden wir den natürlich korrigieren. Das ist auch der große Vorteil bei Leanpub, dass das möglich ist. Da muss man nicht auf eine Webseite schreiben “Auf der Seite war ein Fehler”. Wenn ihr das Buch liest und ihr seht irgendwas, was nicht stimmen kann, sagt gerne Bescheid, dann korrigieren wir das auch gerne. Es ist jetzt erst mal inhaltlich vollständig. Es folgt jetzt noch ein Vorwort, da haben wir eine tolle Person gefunden, die das für uns schreibt, ist aber noch eine Überraschung. Das kommt noch dazu, aber sonst ist es vollständig.
Robert: Okay, super. Und weil Lucas und ich nur von zwei Dingen leben können, nämlich Kaffee und euer Feedback, schreibt uns bitte, denn wir verlosen unter allen Leuten, die uns Feedback zu dieser Folge geben, Fragen schicken, Anmerkungen oder Erfahrungsberichte, haut einfach eine Email raus, verlosen wir fünf Exemplare dieses Buchs.
Lucas: Genau.
Robert: So, jetzt steigen wir ein, weil wir beide, wie gesagt, nicht wirklich objektiv sind. Lucas, du machst auch schon viele, viele Jahre lang Rails und Ruby. Ich auch. Ich bin damals in Version 2 eingestiegen. Bist du schon früher dabei gewesen?
Lucas: Ich bin mit Rails 1.0 eingestiegen.
Robert: Wow, deswegen sind wir beide nicht so ganz objektiv. Deswegen haben wir eine kleine Umfrage gemacht bei uns, bei INNOQ. Und zwar haben wir einen Dev Channel in unserem Slack. Da kann man über Entwicklungsthemen diskutieren. Da habe ich einfach mal gefragt “Liebe Kollegys, die vielleicht kein Ruby und kein Rails machen. Was sagt euch der Begriff “The Rails Way”? Was verbindet ihr damit? Was denkt ihr, hat Rails mit dem Ökosystem gemacht und vielleicht auch mit dem Ökosystem weit über das Ruby Ökosystem hinaus? Hat es vielleicht andere Sprachen und Frameworks positiv befruchtet oder hat es Dinge negativ geprägt? Was verbindet ihr mit diesem Begriff “The Rails Way”?” Und da haben ganz schön viele Kollegys mir Antworten geschickt im Thread. Die hast du auch gesehen und da greifen wir uns einfach mal ein paar zum Einstieg raus, würde ich sagen. Ganz oft wurde genannt, dass Rails das Prinzip Convention over configuration geprägt hat. Was sagst du dazu, stimmt das?
Lucas: Ich würde sagen, das ist eine von den Sachen, die definitiv irgendwie aus dieser Welt gekommen sind. Viele Frameworks haben diese Eigenschaft gehabt zu dem Zeitpunkt, dass man riesige Konfigurationsfiles anlegen muss. Man muss aber auch ganz klar sagen, dass es auch ganz viele Leute gab, die gar keine Konfiguration haben. Wenn man zu dem Zeitpunkt zum Beispiel PHP gebaut hat, dann hat man sowieso from scratch Sachen gebaut oder man hatte so ein ganz kleines Framework. Das war schon zu dem Zeitpunkt sehr unterschiedlich. Aber viele von den größeren Frameworks hatten doch ganz schön viel Konfiguration. Die Besonderheit war, dass Rails dieses Paradigma hatte von Convention over configuration. Das heißt also, jedes Konfigurationsparameter hat erst mal einen default value. Das heißt, du musst nicht erst einen wählen, sondern wenn du keinen wählst, dann hat es erstmal ein default value. Da gibt es jetzt auch verschiedene Begriffe dafür. Vielleicht sagt man heute über ein Framework mal, dass es opinionated ist, also dass dieses Framework eine bestimmte Meinung vertritt. Das war auch bei Rails so. Rails ist auch ein opinionated framework, das bestimmte Sachen auf eine bestimmte Art und Weise gelöst hat. Der Erfinder von Ruby on Rails, der David Heinemeier Hansson, hat seine Präferenzen in dieses Framework eingebacken. Gerade ganz am Anfang war es so, dass man manche Sachen davon auch gar nicht ändern konnte. Da war das einfach festgelegt und wenn du das nicht mochtest, hattest du halt Pech gehabt. Das hat sich über die Zeit geändert. Gerade dann später bei Rails 3 sind sehr viele Sachen austauschbar geworden, wo man dann sagen konnte: Das Testframework, was da drin ist, das mag ich nicht, ich möchte lieber ein anderes. Oder: die Templatesprache mag ich nicht, ich möchte lieber eine andere. Solche Sachen. Das war am Anfang wesentlich eingeschränkter. Das hat dazu geführt, zum einen, der Autor hat irgendwann einen Blogpost geschrieben, Rails is Omakase , dass Rails ein Menü ist, was der Koch und der Koch ist er selbst, einem serviert. Und wenn man es nicht mag, hat man Pech gehabt, dann muss man in ein anderes Restaurant gehen. Interessant dabei ist und da kommen wir auch ein bisschen auf die Historie von diesem Buch, dass es starke Stimmen in der Community gab, die an bestimmten Stellen gesagt haben: Nee, das was du am besten findest, finden wir nicht am besten. Das ist nicht die perfekte Lösung. Da muss man hervorheben. Gerade die beiden Firmen thoughtbot und Hashrocket, das sind zwei US amerikanische Consultancy Firmen, die am Anfang nur Rails gemacht haben. Mittlerweile glaube ich auch andere Sachen machen, aber ist auch egal. Gerade was das Testframework angeht, hatten sie eine andere Meinung. Was die die Templatingsprache angeht hatten sie eine andere Meinung. Und mit der Möglichkeit das auszutauschen hat sich die Möglichkeit ergeben, tatsächlich von diesem Weg abzuweichen. Das ist auch das, weswegen der Rails Way als Begriff auch eine interessant Art und Weise ist, weil Obie Fernandez eben zu diesem Camp gehört. Er war der Gründer von Hash Rocket und hat gesagt: In diesem Buch schreibe ich nicht einfach hin, wie das in Rails ist, sondern wie ich denke, wie es in Rails sein sollte. Das ist natürlich zum großen Teil so, wie es in Rails auch ist, es ist natürlich nicht vollständig anders, aber es gibt eben doch signifikante Teile, wo es eben voneinander abweicht. Das ist auch bis heute so. Auch in der heutigen Version von diesem Buch steht drin, in dem Framework gibt es das und das, aber wir empfehlen stattdessen bitte das zu benutzen. Darum kann man das so ein bisschen abgrenzen zwischen diesem Omakase, diesen DHH Weg etwas zu tun und dem Rails Way, der so der Stil ist, der vor allem von Hashrocket und thoughtbot geprägt wurde, aber auch von vielen anderen verfolgt wird. Da sind auch Empfehlungen drin für Libraries, die man benutzen sollte, über das hinweg, was in Rails dabei ist, was bei vielen anderen Rails Büchern nicht so ist. Die halten sich einfach strikt an das, was im Framework drin ist und nehmen das einfach an. Da gehen wir einen anderen Weg und diese Tradition verfolgen wir einfach weiter.
Robert: Rails ist mittlerweile auch so umfangreich geworden. Das liefert auch Antworten, für die es früher keine Antworten gab. Und du hast vollkommen recht, DHH ist ein very opinionated guy, kann man so sagen.
Lucas: Ja definitiv.
Robert: Es hat dem Framework auch viele, viele Jahre sehr gut getan, dass da ein Art wohlwollender Diktator agiert. Bis zu einer gewissen Grenze ist so was gut, weil gerade völlig dezentral organisierte Open Source Projekte leiden oftmals auch ein bisschen unter einem Mangel an Leadership oder Decision Makership oder wie man das nennen will. Wie der Diktator dann agiert, das variiert über die Diktatorensippe hinweg. Da gibt es einige, die entscheiden sofort und schnell und dann ist das Thema tabu, aber sie treffen keine informierten Entscheidungen. Sie kennen wahrscheinlich nicht die Optionen, über die sie entscheiden sollten. Und dann gibt es das andere Ende der Skala, das sehr informierte Entscheidungen vielleicht nicht so schnell getroffen werden. Aber um zurück zu meinem Punkt zu kommen. Wir hatten neulich unter Kollegen eine interessante Diskussion. Da hatte jemand gefragt: Was nutze ich denn heutzutage in Rails, wenn ich asynchrone Jobs laufen lassen will? Und ich dachte immer bis heute: Okay, Rails hat mittlerweile ein Backend dafür schon seit ein paar Jahren, Active Job nennt sich das. Aber das beantwortet diese Frage nur bis zu einer gewissen Grenze und sagt dann: Da musst du jetzt hier ins Backend was dranstecken. Wir liefern den Stecker mit, der sieht immer so aus. Ein ISO zertifizierter Stecker quasi. Die eigentliche Antwort, nämlich die Library, die das asynchrone Processing macht, der eigentliche Worker, den müsst ihr dranstöpseln, da kümmern wir uns nicht drum. Das war irgendwie schon neu, da war so ein definiertes Ende von Rails da, aber gleichzeitig auch mit einem definierten Stecker, was die Erweiterbarkeit leicht macht. Ich sage immer: Ich schlag in deinem Buch nach, dabei frage ich dich einfach nur. Da war mir die Option neu, die dann in dieser Diskussion mit dem Kollegen rauskam, ich dachte immer man nimmt Sidekiq bis zum Verderben. Aber das bringt natürlich auch einige Sachen mit, ich brauche wieder eine Redis, der diese Jobs persistiert werden von Sidekiq. Das ist natürlich eine gewisse große Abhängigkeit. Dann muss ich das wieder installieren. Der typische Rails Stack sieht heute aber so aus, dass ich ein Rails Prozess habe, mit wahrscheinlich mehreren Threads und einer PostgreSQL Datenbank und da hast du mir gesagt: Aber schau doch mal, es gibt mittlerweile einen Worker, den du auch an Active Jobs stecken kannst, der einfach die Jobs in der PostgreSQL persistiert, durch eine PostgreSQL Einheit, die nicht blockiert wird. Wie hieß das nochmal?
Lucas: Du sprichst jetzt über GoodJob. Ich würde kurz noch mal einen Schritt zurückgehen, damit wir nicht die Leute verlieren, die jetzt noch keine Rails Erfahrung haben. Robert hat gerade gesagt: Active Job, das müsst ihr euch einfach vorstellen. Das ist ein Interface quasi, dass eine Klasse zur Verfügung steht, das ist der Job und der hat quasi eine Methode, die sagt: Führe bitte diesen Job aus. Aber wer den ausführt, zu welchem Zeitpunkt, das bestimmt dieses Ding eben nicht. Der große Vorteil, würde ich jetzt gerne drauf eingehen, überhaupt so ein Interface zu haben, was sehr, sehr klein ist und sehr, sehr schmal. Man kann da auch verschiedenste Backends dahinterhängen, ist, dass ihr beispielsweise eine Bibliothek installieren könnt und die Bibliothek, die weiß, dass ihr Rails benutzt, die weiß aber nicht welches Job Backend ihr benutzt, das ist dem völlig egal. Aber es kann eben sagen: Ich möchte bitte diesen Job jetzt im Hintergrund ausführen. Wenn ihr jetzt eine Authentifizierungs-Library habt und die will irgendwie im Hintergrund eine Mail rausschicken, dann kann die das halt machen, ohne dass Probleme da sind: Wie schickt man eine Mail raus? Das muss es gar nicht wissen, es muss sich nur an diesen sehr einfachen Kontrakt halten, wie man überhaupt einen Job definiert. In vielen Ökosystem benutzt man eine spezifische Software wie eine RabbitMQ, also ein Message Broker oder so was, um Hintergrundjobs abzubilden. Und in Rails haben sich Leute relativ früh dafür entschieden, stattdessen Redis dafür zu benutzen. Redis ist ein Datenstrukturserver. Da hat man Datenstrukturen wie eine Liste und Set. Und damit kann man relativ einfach eine kleine Job queue bauen. Man sagt einfach: Hier ist eine Liste und wenn du einen neuen Job hast, lege ihn bitte in diese Liste. Über die Zeit hat sich da herauskristallisiert eine Lösung, die Sidekiq heißt mit Q hinten. Für die Leute, die es googlen wollen, aber kommt auch in die Shownotes. Die vor allem darauf optimiert ist, sehr viele Jobs zu verarbeiten. Wenn ihr ein hohes Volumen an Jobs habt und die Jobs jeweils relativ kurz sind, dafür ist Sidekiq einfach eine super Lösung. Das hat eine super Performance, das kann das sehr gut abarbeiten. Und Sidekiq hat eben diese Konsequenz, dass man eben eine Redis braucht. Für viele war auch die Argumentation: Eine Redis hat man sowieso oft irgendwie am Laufen. Vielleicht speichert man da Caching Daten rein oder so was, dann hat man die eh schon. Deswegen ist das gut. Dann braucht man wenigstens nicht noch eine RabbitMQ. Aber über die Zeit hat sich das eben gewandelt, dass auch die Datenbank wieder mächtiger geworden ist. Und in der Datenbank PostgreS oder PostgreSQL gibt es die Funktionalität von Listen und Notify. Damit können sich verschiedene Clients, die mit der Datenbank verbunden sind, gegenseitig Nachrichten schicken. Das ist die Mechanik, die dahinter steckt. Und das ist so performant, dass man für die meisten Use Cases gar nicht mehr braucht. Das Charmante daran ist eben, ich habe meine Rails Prozesse und ich habe im Hintergrund meine Datenbank und mehr brauche ich dann eben nicht. Dann bin ich schon fertig und das ist eben das, was in Good Job implementiert ist. Das empfehle ich als Einstieg, wenn man einfach erst mal loslegt mit seiner Rails Anwendung und man hat jetzt nicht irgendwie unfassbare Mengen von Jobs, die man da abarbeitet, sondern man schickt selbst ein paar Mal die Minute Mails raus. Dann braucht man dafür nicht unbedingt einen Sidekiq. Ja, dann kann man auch sowas wie Good Job benutzen. Deswegen haben wir das auch im Buch so empfohlen, dass man mit Good Job anfängt und nur wenn man diese Probleme hat, dass man dann in Sidekiq einsteigt. Und bei Sidekiq ist es eben auch so, das sollte man noch erwähnen, dass das eine Open Source Library ist, genauso wie Good Job. Aber das ist eben ein Open Core Modell. Bei Sidekiq gibt es auch ein kommerzielles Offering, das man darüber hinaus bezahlen muss, im Abo Modell. Bestimmte Sachen, die ich als wichtig sehen würde, sind leider erst in der bezahlten Version drin, die aber bei Good Job schon im Open Source mit dabei ist, da gibt es gar keine kommerzielle Version. Das heißt also, auch aus diesem Kostengrund ist es vielleicht auch eine attraktive Möglichkeit, da einfach ein bisschen was zu sparen, weil man es einfach nicht braucht. Wenn man es braucht, ist meiner Meinung nach auch immer noch gut investiertes Geld in Sidekiq zu investieren, aber muss nicht an Tag 1 sein, wenn man vielleicht auch gar nicht weiß, ob das, was man da baut, überhaupt Geld abwerfen wird.
Robert: Ich bin direkt natürlich voll abgedriftet und danke, dass du das jetzt noch mal für alle Hörerinnen und Hörer ausdekliniert hast, worüber wir hier reden. Lass uns doch wirklich mal versuchen, ich reiß mich jetzt zusammen, dabei zu bleiben, was ist der Rails Way? Wir gucken uns noch ein paar Punkte der Kollegys an, die sie uns genannt hatten, was für die der Rails Way ist, was sie so mitgenommen haben, obwohl sie nie Rails gemacht haben. Ganz am Anfang hatten wir Convention over configuration, du hast das auch erklärt, was das bedeutet. Meine Frage ist jetzt: Wenn ich in ein Java Projekt gehe oder in ein Python Projekt oder was macht man denn heute noch? Ist das immer noch so, dass das Team am Anfang entscheidet: Unsere Modelle legen wir jetzt in dem Ordner ab, wir benennen die so. Unsere Controller, wenn ich dann das MVC Pattern befolge und unsere Views legen wir da ab, werden diese Entscheidungen immer noch getroffen in den Mainstream Frameworks oder so sind wir da mittlerweile ein bisschen weiter?
Lucas: Projekterfahrung mit Frameworks oder auch Libraries, das ist schon wieder eine Unterscheidung, die man da irgendwie trifft, habe ich mit Ruby on Rails, mit Go und mit NodeJS. Go und Node lehnen eher sowas wie Rails ab, das sehen die eher als eine schlechte Idee. Die wollen eher Libraries haben, die man sich dann selbst zusammensteckt. Ich glaube, das bekannteste Beispiel dafür ist Express.js. Das ist so, dass das “Framework”, was man in Node immer noch am häufigsten trifft. Ich glaube, auch bei den letzten Umfragen ist es immer noch das häufigste Framework. Das hat eben einen viel kleineren Funktionsumfang, als das jetzt ein Django, ein Springboot oder ein Rails hat. Das ist einfach viel weniger und im Kern ist das vor allem würde ich sagen, eine Routing Library. Eine Möglichkeit zu sagen: Wenn diese Route aufgerufen wird, bitte ruft diesen Code aus. Da ist aber nicht so was dabei wie Active Job, das abstrahiert, wie man einen Job im Hintergrund abschickt, das ist überhaupt nicht vorgesehen. Ich glaube, das sind einfach zwei grundlegend unterschiedliche Philosophien. Dieser Library approach und dieser Framework approach, da kann man keinen Mittelweg finden. Beide haben ihre Vor- und Nachteile. Wenn man diesem Framework folgt, dann hat man immer eine bestimmte Einschränkung. Bestimmte Dinge muss man so tun, wie das Framework das möchte, sonst wird es einfach nicht funktionieren. Dann geht einfach was kaputt. Das heißt, wenn man sehr viele eigene Vorstellungen hat, wie das zu funktionieren hat, dann wird man damit vielleicht nicht glücklich, weil das vielleicht nicht zu dem passt, was man sich da wünscht. Auf der anderen Seite kenne ich das aus wirklich jedem von diesen Node und Go Projekten, dass man dann erst mal eine Phase hat, in der man entscheidet und debattiert, welche einzelnen Teile man da zusammenstellt. Um jetzt einfach mal schnell zu starten, ist das jetzt nicht der beste Weg. Es ist auch nicht unbedingt so, dass dabei jetzt natürlich die perfekte Lösung rauskommt, weil viele von diesen Entscheidungen, die jetzt in einem großen Framework drin sind und damit meine ich jetzt wirklich nicht Rails allein, sondern auch andere, da sind schon viel mehr Diskussionen eingeflossen, die bis zu diesem Punkt geführt haben, diesen Weg zu verfolgen oder diese Lösung zu nehmen. Wenn man das in einer ad hoc Diskussion in seinem Projekt irgendwie macht, dann hat man das vielleicht noch nicht alles beachtet. Das ist eben ein Trade off, bei dem man sich für den einen oder den anderen Weg entscheidet. Aber ich muss auch sagen, von diesen umfangreichen Frameworks habe ich Praxiserfahrung mit Rails. Aber ich vermute, dass das ähnlich gilt für die anderen Frameworks, dass man an den Stellen, wo man jetzt wirklich eine andere Meinung hat, das tatsächlich umkonfigurieren kann. Bestimmte Sachen sind einfach so, die wirst du nicht ändern können. Zum Beispiel in Rails gibt es ein Autoloader, das ist ein Ding, was dafür sorgt, dass du nirgendwo Import statements in deinem ganzen Code hast, oder Required statements würde man jetzt das in Ruby nennen, aber in den meisten Programmiersprachen sprechen wir von Import Statements, wenn man in ein Rails Projekt reinkommt, dann gibt es die einfach nicht. Jede Datei fängt einfach mit Class quasi an und das kannst du nicht ausbauen. Wenn du das nicht magst, dann ist glaube ich Pech. Aber wenn du die Datenbanklösung nicht magst, dann kannst du die austauschen. Aber da muss man auch ganz klar sagen, bei Rails gibt es Sachen, wo ich das nicht empfehlen würde. Beispielsweise Rails zu verwenden, ohne Active record zu verwenden kann ich nicht empfehlen, weil das an so vielen Stellen einfach miteinander vernetzt ist, dass man sich damit keinen Gefallen tut. Wenn man sich für Rails entscheidet, dann sollte man sich auch für Active Record schon entschieden haben und damit auch für eine relationale Datenbank, sonst passt es einfach nicht so gut.
Robert: Wenn man eine braucht.
Lucas: Klar, vielleicht braucht man auch keine und liest einfach aus dem File System. Da gab es auch mal ein CMS, was das getan hat, habe ich gehört. Im Kern glaube ich, sollte man damit einverstanden sein. Es ist nicht so, dass man jetzt bis ins Allerletzte mit allen Entscheidungen einverstanden sein muss, weil man sie dann doch überschreiben kann. Ich würde das ein bisschen relativieren, aber grundsätzlich geht man schon dieses Trade Off ein.
Robert: Meine persönliche Meinung ist. Persönliche Meinung, immer dieser blöde Disclaimer. Ich kann es ja einfach sagen. Ich finde Convention over configuration vereint so viel. Autoloading, das muss auch erst mal erfunden und fehlerfrei entwickelt werden. Da hat es in Rails über viele Jahre auch echt geknarzt. Viele Seiteneffekte, vieles was man nicht nachvollziehen konnte. Nur um keine required statements zu haben ist schon ein ganzer Ball Magie am rollen.
Lucas: Ja.
Robert: Da bin ich auch nicht einfach, dass ich sage: Sollte jedes Framework so machen, sollte jedes Projekt so machen, dass es immer die geilste Variante. Nee, würde ich nicht sagen. Aber ich will doch, wenn ich in ein neues Projekt komme oder für einen Kunden, da finden sich auch meistens neue Teams zusammen. Da gibt es so viel, sich kennenzulernen, Teamrituale zu schaffen. Wann treffen wir uns? Architekturentscheidungen zu dokumentieren, da will ich doch nicht noch den Sauerstoff als Team veratmen und darüber diskutieren: Wo legen wir die Templates ab? Wo legen wir die Models ab? Verwenden wir camel case files oder underscored files? Ganz ehrlich, das muss ein Framework vorgeben, sonst führt es einfach wieder zu Entwicklydiskussionen. Wie siehst du das?
Lucas: Ja, ich glaube das auch, dass der Trade off sich in den meisten Fällen auszahlt, zu sagen: Ich nehme etwas, wo schon die Entscheidungen getroffen sind. Du musst bestimmte Entscheidungen treffen, du kannst die nicht einfach nicht treffen, das ist keine Option. Dann sollte man, wenn man ein Framework gefunden hat, wo die meisten der Entscheidungen zu dem passen, was wir gut finden, dann sollten wir damit auch zufrieden sein und nicht sagen: Hey, aber an der Stelle, deswegen können wir das nicht machen und deswegen machen wir alles from scratch quasi, jede Entscheidung treffen wir selbst. Gerade in dem Go Ökosystem, mit dem ich aktuell unterwegs bin, in einem Projekt, da ist mir das eher unangenehm aufgefallen. Dass man sehr, sehr viele von diesen Diskussionen lange führen muss und dadurch, dass diese Libraries relativ kleinteilig sind. Vielleicht auch an Stellen, die wieder revidieren muss, weil dann diese eine Library doch nicht mehr funktioniert und vielleicht nicht mehr maintained ist usw. Wenn man auf ein Ökosystem setzt, wo man ein relativ großes Framework hat, wie Rails. Dass Rails nicht mehr maintained wird halte ich für fast unmöglich, wenn man überlegt, welche Firmen das in Produktion einsetzen, wie GitHub, Gitlab und so weiter, das wird schon weiterlaufen. Shopify…
Robert: So viele Firmen weltweit. Die kann man sich gar nicht ausmalen. Du kennst das, du googlest eine bestimmte Reissorte, ein Kaffeeanbaugebiet. Du kommst es auf eine Rösterei, die ihren Kaffee heute einfach im Web verkaufen kann. Nach Röstdatum, da steht schon relativ oft Shopify dahinter, ohne statistische Analysen herausgeben zu wollen. Ich sehe das sehr, sehr oft. Und das sind alles Rails Shops, wo Shopify nicht hinter Rails steht, aber Rails einsetzt.
Lucas: Auch hinter Rails steht. Das ist ja eine Sache, die jetzt letztes Jahr passiert ist. Eine Foundation wurde gegründet, die sich darum kümmert, dass Geld da ist, um bestimmte Entwicklungen weiterzutreiben. Da haben sich eben verschiedene Firmen zusammengeschlossen, unter anderem eben auch GitHub und Shopify, die da jetzt einfach Geld geben, damit dafür gesorgt wird, dass Security Audits gemacht werden. Sachen, die nötig sind, damit die wissen: Unsere Anwendungen funktionieren weiter und deswegen baut man da eine sehr stabile Grundlage auf. Man weiß, das skaliert bis zu einem GitHub. Das sollte für die meisten reichen. GitHub wird nicht einfach von heute auf morgen sagen: Wir bauen das jetzt mal in einem anderen Framework um. Das heißt, wir können auch davon ausgehen, dass die weiterhin interessiert daran sind, dieses Framework weiterzuentwickeln und dass das nicht einfach eingestellt wird. Das ist eben ein Risiko, was man eingeht, wenn man auf ein kleineres Framework oder eine kleinere Library setzt, wo vielleicht auch nur eine einzelne Person hinter steht, die dann einfach vielleicht einfach keine Lust mehr hat, ihre Freizeit da zu investieren. Dort gibt es eben Leute, die auch Vollzeit dafür bezahlt werden, dieses Framework weiterzuentwickeln. Das ist einfach ein Kriterium, was man im Hinterkopf behalten sollte. Und damit sage ich nicht: Setzt auf keinen Fall eine Library ein, die nur von einer Person entwickelt wird, das sage ich gar nicht. Aber um so zentraler diese Komponente in unserer Anwendung ist, umso mehr möchte ich sicherstellen, dass das auch für eine gewisse Zeit weiter existiert, damit ich dann nicht all meinen Code umschreiben muss. Eine Rails Anwendung, wenn Rails nicht mehr funktionieren würde, dann müsstest du die vollständig neu schreiben. Das ist so darin vernetzt, das geht gar nicht anders.
Robert: Liebe Hörerinnen und Hörer an der Stelle. Was habt ihr für Erfahrungen mit Convention over configuration gemacht? Beherzigt ihr das? Welche Sprachen, welche Frameworks nutzt ihr? Arbeiten die nach diesem Prinzip? Sind die nach diesem Prinzip aufgebaut? Verlangen die von euch: Legt bitte eure Sachen da und da ab, benennt die so. Wie findet ihr das? Schreibt uns doch bitte einfach mal. Wir hangeln uns weiter an den vielen, vielen Sachen, die unsere Kollegy uns genannt haben. Was Rails für die bedeutet oder bekannt gemacht hat, ohne dass die große Erfahrung mit Rails hätten. Hier sagt zum Beispiel jemand: Eine vergleichsweise hohe Produktivität. Die Person hat auch mit Rails bisher nichts gemacht, aber das ist wohl durchgedrungen. Das kommt vermutlich durch Dinge wie Convention over configuration, aber bestimmt auch durch andere. Omakase ist hier genannt. Das haben wir auch gerade kurz behandelt. Für alle, die nicht mit der japanischen Küche oder Küchen, es sind ja mehrere vertraut sind. Lucas hat das vorhin genannt. Der Chef oder die Chefin bestimmt in einem Omakase Restaurant darüber, was an dem Abend serviert wird. Man könnte es auch nennen “Friss oder stirb”.
Lucas: Das klingt aber nicht so schön.
Robert: Aber das bietet natürlich auch aus Sicht eines Betriebes, eines Chefs Vorteile. Ich kann mich an der Frische der Produkte orientieren. Ich kann eine Zusammenstellung machen, die optimal funktioniert und zusammenspielt. Wenn ich einen Gast habe, der oder die sich zur Vorspeise, zum Hauptgericht und zur Nachspeise jeweils Schnitzel bestellen will, dann geht das eben in einem Omakase Restaurant nicht. Die Person kriegt leider ihren Willen nicht erfüllt, kann sich den aber woanders erfüllen. Die Wette und die Hypothese ist ein bisschen: Dir entgeht dadurch aber auch ganz viel. Weil du denkst, das so für dich entscheiden zu müssen. Deswegen lass es doch lieber Leute entscheiden, die diese Entscheidung informiert getroffen haben. Das nimmt dir auch Arbeit im Projektalltag ab. Wir entscheiden uns für Gerichte oder Komponenten, Framework, Bestandteile, die getestet sind, wo wir wissen, zu 80% lösen die dein Problem. Und das kriegst jetzt alles von uns.
Lucas: Das Zusammenspiel, also neben bestimmte Entscheidungen schon getroffen, ist, dass das Ökosystem an Libraries, die man zu Rails sich dazu nehmen kann, wirklich umfangreich ist. Bevor in Rails das eingebaut war, dass man File Uploads vernünftig löst. Und das bedeutet zum Beispiel diese Uploads entgegennehmen, sie auf S3 kompatiblen Storage ablegen, vielleicht sogar noch anzubieten, dass Bilder resized werden oder was auch immer. Das war in Rails schon möglich, obwohl es nicht in Rails drin war, weil es da sehr gute Libraries gab, die man einfach verwendet hat. Das musste man nicht selbst erfinden. Es hat keinen keinen großen Sinn gehabt, in einem Rails Projekt zu sagen: Hey, lass uns das doch mal selber bauen, weil die Lösungen wirklich schon gut etabliert waren, in wesentlich größeren Projekten, als im eigenen dann schon im Einsatz waren und dann auch schon ihre ganzen Bugs usw. abgeschüttelt haben. Ich glaube, das ist teilweise auch deswegen möglich, weil das Framework schon eine Reihe von Entscheidungen getroffen hat. Das heißt also, es ist einfacher als Library, sich in dieses Ding einzuhaken und zu sagen: Ich bin jetzt ein Plugin und ich weiß schon X, Y und Z sind wahr, also kann ich mich darauf verlassen, dass es da ist und darauf aufbauen. Wenn du jetzt stattdessen Express hast, dann könntest du das nicht, da sind bestimmte Sachen eben nicht klar. Wie mache ich einen Background Job? Hat Express keine Antwort drauf. Wenn du ein Upload Gerät bauen möchtest, was dann zum Beispiel sagt: Bitte mach das später, dass die Bilder resized werden oder in ein anderes Format umgewandelt werden, dann geht das immer in Rails, es gibt Active Job, da kann ich mich darauf verlassen. Da kann ich also dafür sorgen, dass das Bild irgendwann später umgewandelt wird. Und das ist für mich wirklich auch eine sehr große Stärke. Ich glaube, wenn man sich mit Ruby on Rails beschäftigt und dann sieht, für die üblichen Probleme, die man in so einer Webanwendungen hat, was es da für Libraries gibt, dann ist man wahrscheinlich schon überrascht, wie viel das ist und wie verbreitet das auch ist. Meistens gibt es dann für solche Sachen 2 bis 4 Auswahlmöglichkeiten, jetzt aber auch nicht hunderte, sondern 2 bis 4. Die sind dann verschiedene Geschmacksrichtungen und davon wählt man eine aus. Mit einer hohen Wahrscheinlichkeit ist man auch mit jeder davon zufrieden. Also bei der Authentifizierung, da gibt es große Streitigkeiten zwischen Rails Entwicklern, welche davon jetzt die Beste ist und welche man auf keinen Fall nutzen dürfte. Objektiv betrachtet, jede davon funktioniert sehr gut. Klar, gibt es vielleicht ein, zwei Nachteile, aber das sind alles gut abgehangene Lösungen, wo ich mir dann darum keine Gedanken mehr machen muss. Wenn ich zum Beispiel eine Library suche, die ein Vollpaket hat, da sind dann so Sachen dabei, wie Two-Factor-Authentification ist integriert. Verschiedene Möglichkeiten, sich zu authentifizieren, sowohl über ein OpenID-Connect von woanders sich zu verbinden, als auch eine lokale Datenbank zu benutzen. Und so weiter und so fort. Das ist einfach alles dabei. Dann muss ich dafür keine Entwicklungszeit aufwenden, sondern kann das eben darauf verwenden, mein Produkt so zu bauen, dass es die inhaltlichen Requirements erfüllt und nicht Technikdinge im Hintergrund zusammen zu schrauben. Das ist glaube ich auch der Grund, warum der Kollege oder die Kollegin auf diese Produktivität hinweist, weil du innerhalb von zwei Wochen schon eine sehr umfangreiche erste Version von deinem Produkt bauen kannst, wo dann aber auch nicht alles quietscht und wackelt, weil du auf Sachen setzt, die funktionieren.
Robert: Es gab aber auch noch eine eher negativ geprägte Anmerkung, die wahrscheinlich so ein bisschen dahin zielt. „Ich assoziiere damit ein enges Korsett, an das ich mich halten muss, sonst mache ich es nicht “richtig”.“ So ein Eindruck kann wahrscheinlich entstehen in einem Tümpel, der sehr kuratiert ist, einem sehr viel Konvention auferlegt. Wahrscheinlich entsteht diese Wahrnehmung aber auch aus früheren Rails Zeiten, wo das einfach noch nicht so viele Stecker nach außen angeboten hat. Heute kann ich mir sehr viel einfacher mein Backend aussuchen, mit dem ich X Y laufen lassen will.
Lucas: Ja, ich möchte aber das auch nicht ganz wegreden. Es ist so, bestimmte Sachen sind festgelegt. Es gibt zwei übliche Patterns, um seine Modell Layer zu gestalten. Entweder man folgt dem Active Record Pattern oder man folgt dem Data Mapper Pattern. Das sind so die zwei, die bei Martin Fowler vorgestellt wurden als Kerndinge. Rails hat sich für das Active Record Pattern entschieden. Ich bin mir sicher, jemand der etwas baut, was nicht auf diesem Pattern aufbaut, der wird damit auch nicht so richtig glücklich werden. Da sind einfach Sachen, da knarzt es eben, weil Rails erwartet, dass bestimmte Sachen in deinem Model drin sind und nicht woanders. Wenn man sich darauf einlässt, auf bestimmte Meinungen, aber das sind nicht Hunderte, das sind eben eine kleine Menge an Meinungen und sagt: Das ist okay für mich. Dann wird man auch damit fein sein. Ich glaube, das ist diese Wahrnehmung von früher, dass super viele Entscheidungen fertig getroffen sind. Und das ist eben nicht mehr so. Man kann sich entscheiden, was für eine Session Storage man benutzt. Das konnte man ganz früher eben nicht. Da war halt einer festgelegt und fertig, aber das kann man heute umkonfigurieren. Wenn man das immer noch im Kopf hat, vielleicht heute auf das Framework gucken, ob sich das immer noch so anfühlt, dass man da so wenig Wahlmöglichkeiten hat. Ich glaube, das haben wir beide auch schon am Anfang gesagt. Du hast diesen vorgegebenen Weg. Und das ist auch angenehm, dem erst mal zu folgen, wenn du daran jetzt nichts auszusetzen hast. Und trotzdem hast du die Möglichkeit, davon abzuweichen.
Robert: Es gibt noch eine Bemerkung. Ich verbinde mit dem Rails Way, dass Rails der Wegbereiter von TDD und BDD war. Test-driven development und Behavior-driven development. Damit meint die Person vermutlich genau das, was sie sagt. Eben, dass Rails auch da eine Entscheidung getroffen hat. Tests liegen da und es ist sehr einfach, erst deine Tests zu schreiben und dann die Implementierung dessen, was du testest, weil es durch viele Konventionen von uns vorgegeben wird. Man kann das auch umgekehrt machen, aber es wird einem schon sehr einfach gemacht. Und mit Behavior-driven development ist gemeint, dass es ganz früh schon eine sehr bekannte Library gab, die sich Cucumber nannte und nennt, wo ich in menschlicher Sprache DSL mäßig meine Behaviors definieren konnte und die wurden dann ausführbar gemacht. Tests in menschlicher Sprache, wenn man so will. Und irgendwann hat Rails sowas auch im Core versucht mit zu bringen, dass ich zumindest meinen Testnamen als freien String vergeben konnte. Das ist jetzt eine positive Anmerkung, aber unter den negativen finde ich gleich auch etwas, was vielleicht genau in diese Ecke zielt. „Ruby ist für mich, für die Person, die das genannt hat, eher so eine negative Wahrnehmung von außen, weil es exzessives Testen nötig macht, weil es eine dynamische Programmiersprache ist und keinen Compiler gibt. Damit auch keine Typsicherheit.“ Was denkst du? Ist dieses ganze Testen einfach nötig, weil ich keine Typ Sicherheit habe, weil Ruby so ist, wie es ist?
Lucas: Ja, das ist auf jeden Fall eine faire Beobachtung. Es gibt bestimmte Sachen, die können in Ruby passieren, die können dir in Java nicht passieren. Die können dir erst recht nicht in Haskell passieren. Ich möchte ganz kurz auf das Thema TDD, BDD eingehen. In Rails ist es so, da ist das Test Framework mit eingebaut. Ich muss nichts installieren, sondern ich kann loslegen und dann kann ich meine Tests schreiben. Und wenn ich irgendwie einen Controller anlege, dann legt er automatisch den Test dafür an und da ist auch Testing Unterstützung mit eingebaut, das eben dafür sorgt, dass sie sagen können: Hey, render doch mal diesen Controller und ich möchte jetzt wissen, ob der Satz so und so da drin steht. Solche Sachen sind da einfach mit eingebaut und das macht es sehr angenehm. Genau, da gibt es auch noch Diskussionen in der Community. Da gibt es zwei beliebte Frameworks. Das eine ist Minitest, das ist im Core von Ruby mit eingebaut und RSpec als Alternative dazu. Viele würden sagen, dass Minitest diesen TDD weg geht und RSpec diesen BDD Weg. “Given, when, then..”, das kennt man vielleicht. Wenn das da ist und das passiert, dann passiert das. So schreibt man dann in diesem BDD Weg und RSpec hilft einem dabei, diesen Weg zu verfolgen. Das erstmal als Seitennotiz dazu. Ist es so, dass man in Ruby untergeht, wenn man keine Tests schreibt? Ich glaube, das kann man so nicht sagen. Ich habe viel Erfahrung mit Ruby und in JavaScript und beides sind Sprachen, die kein statisches Typsystem haben. Ich muss ganz klar sagen, es verhält sich einfach anders. Manche Sachen, die einem in JavaScript passiert, passieren einem in Ruby nicht. Oder die Fehler sind auch nicht so, dass man sie nicht so einfach finden kann. In JavaScript gibt es immer mal wieder das Problem, irgendwas versucht man aufzurufen, dann ist es keine Funktion, dann macht es irgendwie puff. Das passiert natürlich in Ruby auch, aber die Fehlermeldung ist sehr klar. Ich verstehe sehr schnell, was das Problem ist, was dahintersteckt. Deswegen habe ich, wenn ich Ruby schreibe, seltener dieses Gefühl, wenn mich da ein Compiler davon abgehalten hätte, dann wäre es besser. Ich bin aber persönlich davon überzeugt, dass man, wenn man eine Webanwendung schreibt, man auf jeden Fall in einer Akzeptanz Testsuit investieren sollte. Bestimmte grundlegende Anforderung, dass die von Tests automatisch abgetestet werden und dabei auch den vollen Stack mit einbeziehen. Ich habe eine Suche, dann führe auch bitte die Datenbank aus und gucke, dass das Suchergebnis bei rauskommt. Gerade in diesen ganzen Sachen, die zwischen diesen Ebenen stehen, da gehen die Sachen meistens kaputt und ich bin davon überzeugt, dass das gut investierte Zeit ist. Ob man jetzt jedes einzelne Modell, jede einzelne Methode testen muss, ist glaube ich, bei vielen Anwendungen gar nicht notwendig. Aber eine gute Akzeptanz Testsuit, die ist es wert. Da gibt es in der Ruby on Rails Welt Capybara, das ist eine Library, es gibt diesen Begriff von Domain specific language, dass man etwas schreibt, was so ein bisschen aussieht wie Text. Und da schreibt man zum Beispiel sowas hin, wie: Fill in Robert into field name. Schreibt man in Ruby Syntax, aber so lesbar, dass es da so steht. Dann submit und dann füllt er das Formular aus, sucht halt das Formular raus anhand von dem Label, was daneben steht und drückt den Knopf, der darunter steht. Solche Tests finde ich sehr wertvoll, weil man dann feststellen kann, dass das, was unsere Endanwender und Endanwenderinnen mit unserer Anwendung machen, dass das tatsächlich auch funktioniert und nicht nur irgendeine Business Logik im Hintergrund funktioniert. Wenn man eine sehr komplexe Stelle hat, dann lohnt es sich natürlich auch, die jetzt ganz explizit zu testen und da auseinanderzunehmen. Diese grundlegenden Workflows, die möchte ich gerne als Full Stack Test sehen. Da hilft einem Rails sehr bei und ich habe das Gefühl, das hat sich auch mehr verbreitet, dass Frameworks sowas unterstützen. Und nicht nur dieses Assert a = b. Das ist nett, aber das reicht eben nicht, um genau diese Probleme da zu finden. Und das ist sehr gut integriert in die Testing Sachen von Rails, egal ob man jetzt Minitest oder RSpec verwendet, kann man auf solche Funktionalität zugreifen. Das Coole dabei ist, dass man heutzutage sogar sagen kann entweder: Mach das doch mit Ruby Code, dann lädt er sich das HTML runter, sucht sich das raus und schickt den Request ab. Oder starte einfach mal einen ganzen Browser. Starte Firefox und mache das mal und dann automatisiert er dieses ganze Klicken durch den Firefox durch und sagt, ob das nachher funktioniert hat. Und das ist eine Funktionalität, die finde ich schon sehr, sehr cool und mit der kann man wirklich stabile Tests schreiben. Ich finde die Kritik nur so halb richtig, weil ich selten in diese Situation gekommen bin, wo ich gesagt habe: An der Stelle musste ich jetzt so den Test schreiben, weil ich ja eine dynamische Programmiersprache habe. Und ich würde da auch noch mal darauf hinweisen, dass wenn man als dynamischer Programmiersprache nur JavaScript kennt, dann sollte man sich auf jeden Fall auch noch mal so was wie Python oder Ruby anschauen, wo es einige von den Problemen, die man aus JavaScript kennt, eben nicht gibt. Das ist was anderes als JavaScript, wo man dann schon irgendwann das Bedürfnis hat, vielleicht so etwas wie TypeScript zu haben.
Robert: In Ruby gibt’s wenigstens nur Nil und nicht auch noch NaN.
Lucas: Ich wusste, dass du das jetzt sagst.
Robert: Wo du gerade fill in gesagt hast. Filled uns doch auch mal in. Schickt uns eine Mail an [email protected], wir verlosen fünf Bücher ‘The Rails Seven Way’. Was ist der Rails Way für euch? Auch wenn ihr kein Rails machen, kein Ruby macht. Was nehmt ihr so mit? Was hört ihr aus der Community schallen? Was findet ihr cool? Was habt ihr vielleicht gesehen? Habt mittlerweile in eurem Framework Einzug gehalten in Spring Boot, in einem Go Web Framework, das ich vielleicht noch nicht kenne, schreibt uns. Ich würde gerne aber noch mal anknüpfen an die Meinung, die uns mitgeteilt wurde, an die Aussage, dass Ruby und Rails exzessives Testen notwendig machen. Da bist du auch gerade drauf eingegangen. Vielleicht werde ich auch altersmilde, aber wenn ich jetzt in einem Template bin und ich greife auf eine Variable zu und denke, in dieser Variable steckt ein Array oder ein Array typartiges Element. Ein enumerable nennt sich das in Ruby. Es gibt nicht nur Arrays, es gibt auch noch Sets. Hash zählt glaube ich auch dazu. Die teilen sich alle gewisse Methoden. Wenn ich jetzt auf diese Variable zugreife und schreib ein eckiges Klammernpaar dahinter, weil ich erwarte, ich kann mit eckigen Klammern auf einen gewissen Index in diesem Element zugreifen. Nun kann es passieren, dass da doch kein enumerable dahinter steht, kein Array, was ich eben erwarte, sondern vielleicht eine Nil, also Null. Schlimmer noch was ganz anderes, was vielleicht keine eckigen Klammern bietet als API. Bei so was denke ich immer: Ja, man muss halt wissen, was da kommt oder man muss super defensiv programmieren oder man muss Ducktyping machen. Also erst mal fragen: Hört dieses Element auf spitze Klammer auf, spitze Klammer zu? Das geht ja auch alles in Ruby. Aber Fakt ist, ich will das nicht den ganzen Tag so schreiben. Klar, ich habe mir das antrainiert, aber ich würde schon mal jetzt für diese Stimme Partei ergreifen und sagen, wenn man aus der Java Community kommt, dann verlässt man sich darauf, dass sein Compiler, seine IDE sagt: An der Stelle kann eine Null kommen und da kannst du nicht mit eckige Klammer auf und zu drauf zugreifen, das fliegt dir um die Ohren. Deswegen fange ich das jetzt für dich ab, das baut einfach nicht. Das kann ich schon verstehen, das hat seinen Reiz. Es ist einfach nur ein betriebswirtschaftliches Argument, es spart Zeit.
Lucas: Ja, da stimme ich zu. Ich glaube schon, dass es wirklich Fälle gibt, wo ein Typ System einem Sachen abnehmen kann. Ich beobachte aber auch manchmal, dass es einem dann vielleicht auch so ein bisschen ein falsches Gefühl von Sicherheit gibt. Nehmen wir jetzt mal diesen typischen Fall vom Empty Screen. Du baust etwas und in all deinen Testfällen hast du natürlich eine volle Seite. Alles ist voller Daten und alles ist cool, weil du deine Datenbank auch schon befüllt hast. Aber jetzt kommt jemand in dein Produkt und legt seinen Account an und erst mal ist da noch nichts, hat noch keine Sachen. Dann gibt es auf jeden Fall irgendwie diese Frage: Wie gestalte ich denn den leeren Bildschirm? Und das ist eine Frage, die viel größer ist als das Nil. Die Frage ist: Wie soll das überhaupt aussehen, wenn noch gar nichts da ist? Und deswegen beantwortet das Typsystem immer nur einen Teil dieser Frage und wir müssen uns sowieso damit beschäftigen. Ich glaube, vielleicht ist man dann als Mensch, der weiß, dass alles da kaputt gehen kann, weil es könnte Nil sein, ist man da vielleicht an ein paar Stellen auch mal ein bisschen paranoider und sagt: Hey, was wäre eigentlich, wenn das da stehen würde? Hat also auch seine Vorteile, wenn man sich nicht darauf verlassen kann. Aber ich stimme grundsätzlich zu. Man kann damit Fehler vermeiden, aber ich glaube, es wird oft ein bisschen überbetont, wie viele Fehler das sind. So oft steht da jetzt auch nicht Nil an irgendeiner Stelle, sondern meistens ist es dann doch eher ein leeres Array und kein Nil, wenn man jetzt irgendwo drüber iteriert.
Robert: Du hast noch nicht genug Pair programming mit mir gemacht. Bei mir knallt es deutlich öfter.
Lucas: Okay.
Robert: Bevor wir in Typ Sicherheitsdiskussionen abdriften, die man potenziell endlos führen kann. Lass uns doch noch mal ein bisschen umgucken. Was nehmen die Leute so wahr? Community wurde als sehr positiv erwähnt und ich glaube, das stimmt bis heute. Ich habe die Ruby Community persönlich auch immer als extrem nett, sehr menschlich, sehr sozial stark und vor allen Dingen auch als inklusiv wahrgenommen. Klar, gibt es immer mal wieder Spitzen, die da das Gegenteil beweisen, aber im Groben ist das meine Wahrnehmung.
Lucas: Ja, das nehme ich auf jeden Fall auch so wahr. Es gibt auch garantiert Leute, die da nicht dem entsprechen, die gibt es auch in jeder Community. Was für mich auch eine Sache ist, die für diese Community spricht. Wir haben vor ein paar Jahren zum Beispiel die Ruby on Ice Konferenz organisiert im Süden von Deutschland und da waren ganz viele Leute dabei, die heute gar kein Ruby mehr machen, die heute vielleicht Elixir machen oder Clojure oder was auch immer. Vielleicht früher auch mal Ruby gemacht haben, aber die halt sich auch immer noch in dieser Community einfach zu Hause fühlen und wohlfühlen und gerne einfach die Leute dort treffen. Es geht ihnen gar nicht jetzt darum, dass diese Programmiersprache jetzt bis heute ihre Lieblings-Programmiersprache ist, sondern dass einfach diese Community ihnen etwas bedeutet. Und ich glaube, das ist auch ein Zeichen dafür, dass da irgendwas hinter steckt, dass da irgendwas ist, was die Leute einfach sich wohlfühlen lässt. Und ich glaube, zu einem Zeitpunkt, wo viele Konferenzen noch sehr strikt auf: Es gibt Vorträge, dann gibt es Catering, dann gibt es Vorträge und dann gibt es vielleicht noch ne After Party und dann ist halt Ende. Wurde in der Community schon viel damit experimentiert. Was ist denn, wenn man mal eine gemeinsame lange Mittagspause macht, an der man zum Beispiel Bootfahren kann oder so was? Ich möchte gar nicht sagen, dass das jetzt in anderen Communitys nicht da ist. Ich glaube, das gibt es heute auch an anderen Stellen, aber ich glaube, da ist es auch wieder so ein bisschen ein Wegbereiter gewesen, da sich auch ein bisschen zu öffnen und zu sagen: Hey, probieren wir was aus. Auch die gesamte Rails Girls Bewegung als einen Weg, Leute ins Programmieren zu holen, die das vielleicht sich vorher nicht getraut haben. Das ist, glaube ich, nicht zufällig in diesem Ökosystem entstanden. Auch da gibt es natürlich wieder sehr gute Beispiele aus anderen Communities, möchte ich auch gar nicht schlechtreden, aber ich glaube, da war es auch wieder etwas, wo es früh dabei war. Eine Sache, wo Rails auch früh dabei war und wo ich aber auf der anderen Seite leider auch immer noch sehe, dass da auch andere Ökosysteme leider immer noch hinterherhinken, ist die Frage, ob man das Frontend ernst nimmt. Rails hatte sehr früh eine Asset Pipeline eingebaut, also die Möglichkeit irgendwie sein CSS umzuwandeln, vielleicht aus mehreren CSS Dateien eine zu machen, das in JavaScript irgendwie umzuwandeln und wenn man unbedingt will, Coffee Script zu schreiben. So was gab es in diesem Ökosystem sehr früh und wurde sehr früh ernst genommen. Auch sehr früh wurde ernst genommen, dass man eine Templating Sprache braucht, die eine hohe Mächtigkeit hat, wo man einfach alles dran machen kann. Ich glaube auch das ist eine Stärke und etwas, was es immer noch von anderen abhebt, die sehr stark sich darauf fokussieren, die Entwicklung im Backend so angenehm zu machen wie möglich. Aber dann im Frontend dann einfach zu sagen: Hey, wir haben eine Template Sprache, deal with it. Da gab es eine Kritik auch von einem Kollegen, der eben gesagt hat, dass es ein bisschen stehengeblieben ist und sich nicht weiterentwickelt hat. Ich glaube, das ist auch bis zu einem gewissen Grade fair zu sagen. Die erste Pipeline, die in Rails eingebaut ist, um diese ganzen Tasks zu machen, die wurde sehr lange nicht mehr richtig weiterentwickelt. Und jetzt in der letzten Version, in Rails 7 kamen dann auf einmal direkt fünf Möglichkeiten, aus denen man auswählen kann und da widerspricht es dann so ein bisschen diesem Omakase Weg, weil dann sage ich: Hey, welches davon soll ich denn jetzt nehmen? Jetzt muss ich jetzt auch wieder auswählen. Und auch die Entscheidung wird eigentlich nicht so richtig einfach gemacht. Da hoffe ich darauf, dass sich das jetzt auch wieder verbessert, dass man da auch wieder einen Weg findet. Wir haben natürlich im Buch einen Weg vorgeschlagen, das ist nun mal das Konzept von dem Buch, aber ich hoffe, dass das auch in dem Core wieder besser wird. Die andere Stelle, wo der Core auch ein bisschen hinterherhinkt, ist die Frage, wie baue ich ein modulares Frontend, also was aus Komponenten besteht. Etwas, was wir jetzt in React oder Angular heute als völlig selbstverständlich sehen, ist leider bei vielen Backend Sprachen immer noch nicht selbstverständlich, wo man einfach Templates hat und vielleicht Partials, Möglichkeiten Teil-Code aufzurufen. Das ist auch immer noch in Rails so im Core, der einzige Weg damit umzugehen. Aber da sehe ich eine sehr positive Entwicklung. Die Library ViewComponents, die wir auch verlinken werden, die einfach ermöglicht so modulare Frontends zu bauen. Das würde ich mir sehr wünschen, wenn das andere Backend Frameworks auch einfach ernst nehmen und auch anfangen das zu machen. Und vielleicht sogar den Rails Core vielleicht noch mal überdenkt, ob so was nicht vielleicht ein guter Weg wäre, das auch per Default anzubieten. Aber wie gesagt, dort gibt es eine Library, die löst das und die löst das meiner Meinung nach auch in einem sehr guten Weg. Einfach mal als Beispiel für etwas, wo vielleicht ein bisschen über die Zeit die Luft raus gewesen ist aus dem Drive, aber ich hoffe einfach, dass das jetzt ein bisschen wiederkommt, dass sich das wieder fängt an, dass man da das ernst nimmt.
Robert: Was du gerade so geheimnisvoll mit Ruby on Ice, eine Ruby Konferenz im Süden Deutschlands mit verklausuliert hast. Das war natürlich der Tegernsee, der Süden Deutschlands.
Lucas: Da sitzen sensationelle Rails-Entwickler habe ich gehört.
Robert: Altersmilde. Würdest du sagen die Ruby Community ist der Schönheit und dem Schönen eher zugewandt? Weil du auch gesagt hast, dieser Frontend Fokus. Nicht, dass das Frontend jetzt für Schönheit steht, aber es ist eben die Projektionsfläche, auf der Schönheit gespielt werden kann. Ist die der eher zugewandt als andere Communities? Wieso sehe ich keine Java Konferenz? Wieso sehe ich keine Go Konferenz am Tegernsee? Wieso gibt es keine Frameworks, die schon seit langer Zeit Lösungen für das Thema Frontend und die Verzahnung mit dem Backend liefern, die einfach Antworten liefern und das nicht einfach brach lassen?
Lucas: Ich weiß nicht, ob ich da eine richtige Antwort dazu habe. Ein Kollege hatte auch geschrieben, dass Rails einen krankhaften Fokus auf schön lesbaren Code hat, dem andere Sachen hinterher geordnet werden. Code Ästhetik ist irgendetwas, was vielen Ruby Entwicklern und Entwicklerinnen sehr wichtig ist. Es soll auch schön zu lesen sein, nicht einfach runtertippen, irgendwie soll es schön sein. Ruby hat auch als Programmiersprache dieses Ziel von Developer Happiness. Dass es wichtiger ist, dass der Code schön aussieht, als dass er der allerschnellste der Welt ist. Ich weiß nicht, wo die Sachen da ineinander spielen. Ich weiß nicht, ob es da einen direkten Zusammenhang dazu gibt, ob man jetzt eine Konferenz am Tegernsee macht statt in der Messehalle, das weiß ich nicht. Aber es ist auf jeden Fall so, dass bestimmte Sachen ein Fokus bei vielen Leuten hat, die in anderen Communities das vielleicht nicht haben. Da würde ich vor allem hervorheben Frontend als Thema und vielleicht auch Code, DSL’s schöner lesbar machen. Das sind so Sachen, wo das, glaube ich, schon deutlich hervortritt. Ich glaube, das andere ist Küchenpsychologie.
Robert: Mit Sicherheit, aber man muss es vielleicht nicht immer nur auf Schönheit münzen, wie ich das gerade gemacht habe, sondern vielleicht auch auf Inklusivität. Ein Fokus auf schön lesbaren Code kann auch die Inklusion steigern, wenn neue Leute ins Projekt kommen oder Leute, die keine Ruby Erfahrung haben, die gucken sich ein Rails Projekt an, gucken sich die Modell Schicht mal durch und sehen da ganz viele Modelle. Book belongs to Author steht da. In der Class Book steht eine Zeile ‘belongs to author’, verstehe ich sofort. Ich weiß nicht, was das ist. Das scheint mir Code zu sein, der ausgeführt wird. Wenn ich ein bisschen Erfahrung habe, kann ich ahnen, dass das eine DSL artige Geschichte ist. Wie das dann implementiert wird, ist erst mal gar nicht so wichtig, aber ich glaube, solche Sachen können die Inklusion verbessern. Dass neue Menschen schnell reinkommen. Es hat eine andere Zugänglichkeit, als würde da stehen: Require das andere Modell, nämlich Author, auf das ich mich beziehe und dann irgendwelche Aufrufe. Das ist schon schöner. Es hilft mir vielleicht auch, einfach einen schnelleren Start zu kriegen in so einem Projekt, weil ich mir schnell einen Überblick verschaffen kann und nicht darauf vertrauen muss, dass einer eine liebevolle Dokumentation geschrieben hat.
Lucas: Ja, dieser Fokus auf Lesbarkeit ist auf jeden Fall etwas, was die Einstiegshürde senkt, das glaube ich schon. Und vielleicht ist das auch einer der Gründe, warum es sich dann eben anbietet, einen Workshop zu machen. In vier Stunden baust du deine erste vollständige Web Anwendung. Das ist in vielen Frameworks, glaube ich, eher schwer möglich, wo man dann in den vier Stunden es gerade geschafft hat, dass man den ersten HTTP Call macht oder so. Da gibt es schon gewisse Verbindungen. Bestimmte Entscheidungen wurden schon getroffen. Das ist auch für den Einstieg sehr gut. Ich muss als jemand, der gerade loslegt mit Webentwicklung, alle diese Entscheidungen selber zu treffen. Damit bin ich völlig überfordert, weil ich weiß noch gar nicht: Was ist denn jetzt besser? Welchen Weg sollte ich denn gehen? Wenn ich jetzt erst mal mit dem Default gehe, der in diesem Framework eingebaut ist, dann habe ich auf jeden Fall erst mal nichts falsch gemacht, weil es ist auf jeden Fall ein Weg, der schon viele Webanwendungen bis in die Produktion gebracht hat und der grundlegend funktioniert. Wenn ich dann zwei Jahre Erfahrung habe, sage ich an der Stelle das würde ich heute anders machen, weil das ist doof, man konfiguriert es um, aber ich musste nicht erst ein Jahr lang tausende verschiedene Meinungen lesen dazu, wie man jetzt am besten mit seinen Sessions umgeht. Ich folge erst mal dem Default Weg und dann bin ich erst mal zufrieden. Und ich glaube, da gibt es schon gewisse Zusammenhänge.
Robert: Die Person, die das genannt hat, diesen krankhaften Fokus auf schön lesbaren Code, die sagt natürlich auch, das haben wir bisher vorenthalten. Dahinter steckt oft ziemlicher Meta Programmierungs-Sumpf. Sehr viel geniale Magie, Aber irgendwann muss man das ganze doch verstehen. Einerseits glaube ich, das stimmt. Klar, wenn da steht ‘belongs to author’ und author ist ein String oder ein Symbol, dann muss das Framework irgendeine Magie bereitstellen, die aus diesem Parameter, der ein String oder ein Symbol ist, eben gewisse Massagen durchführt, um dann auf die Code Klasse zu schließen, auf die sich dieser Aufruf eigentlich bezieht. Und das Ganze kann man noch viel weitertreiben. Die muss laufen, die Magie, die holt man sich da mit rein. Ob man sie dann aber immer auch verstehen muss, um sie anzuwenden, das weiß ich nicht.
Lucas: Und auch da würde ich sagen, an bestimmten Stellen hat sich das auch gewandelt über die Zeit. Ich erinnere mich noch daran, vor sieben Jahren oder so, da war es in AirSPEC noch so, da war quasi alles mit Meta Magie. An jedes einzelne Objekt im gesamten Ding war so was wie Punkt Should drangehängt, dass ich die Methoden darauf aufbauen kann. Das hat sich eben erwiesen als eine schlechte Idee, das ist heute auch nicht mehr so. Bestimmte Sachen wurden da auch einfach zurückgerollt, wo dann vielleicht ein bisschen zu enthusiastisch in die Meta Programmierungskiste gegriffen haben. Gerade die Kritik an diesem Has Many (kein Menu) und so weiter, das in den Methoden drinsteht, die teile ich tatsächlich einfach nicht. Dass das eine schlechte Idee ist, glaube ich nicht. Man muss eigentlich nur ein Konzept verstanden haben, dass diese Klassenmethoden einfach in der Kindklasse in dem Körper aufgerufen werden können. Wenn man das verstanden hat, dann weiß man was da steht. In anderen Programmiersprachen muss ich dafür so was verstehen wie Decorators oder Annotations, die auch ihre ganze Komplexität haben. Es ist jetzt nicht so, als gäbe es das da nicht. Deswegen finde ich den Teil der Kritik nicht ganz fair. Aber ich glaube, dass die Kritik an zu viel Meta Programmierung in früheren Versionen der Ruby Tools durchaus wahr ist. Meine Wahrnehmung ist, dass da viele Sachen heute gar nicht mehr so sehr in diese Trickkiste rein greifen, weil sie sich das als nicht so toll erwiesen hat. Da würde ich auch noch mal sagen vielleicht einfach heute noch mal reingucken, ob das immer noch so ist. Das ist natürlich klar, wir gucken uns alle irgendwelche Tools, irgendwelche Programmiersprachen zu einem Zeitpunkt an, das speichern wir im Kopf ab und da guckt man es nicht jedes Jahr noch mal neu an, dafür haben wir alle gar keine Zeit, alles nochmal jedes Jahr neu anzuschauen. Ich glaube, an der Stelle lohnt sich da noch mal der Blick, ob das tatsächlich heute noch so exzessiv ist, wie das vielleicht damals war.
Robert: Interessant fand ich noch die Themen. Das sind gleich zwei, die möchte ich so ein bisschen verbinden. Einmal wurden die Cookie basierten Sessions positiv erwähnt, also dass eine Session komplett in einem Cookie steckt und keine Referenz mehr in irgendeiner Datenbank Tabelle hat, wo dann die eigentlichen Daten stehen. Der Cookie ist quasi atomar, kann nicht weiter zerlegt werden und da steht alles drin, was ich in meiner Session mitschleppen möchte, sofern ich das brauche. Damit war Rails glaube ich wirklich das erste Web Framework, was diese Entscheidung getroffen hat. Die war bestimmt auch mutig, weil die mussten auch verschlüsselt sein. Es hieß am Anfang auch: Schreibt bitte keine hypersensitiven Sachen da rein. Die sind zwar verschlüsselt mit der und der Methode, die ist auch nicht mehr aktuell. Mittlerweile gibt es ganz andere Methoden, um diesen Cookie zu verschlüsseln. Wann wurde das eingeführt, mit Rails 3? Das ist auch gar nicht so wichtig, gibt es schon eine ganze Weile. Meiner Wahrnehmung nach sieht man das immer noch nicht in vielen anderen Frameworks und vielen anderen Programmiersprachen. Wo ich mich immer frage: Warum eigentlich nicht? Es bringt so viel Vorteile mit. Ich habe automatisch dieses Skalierungsproblem gelöst, dass ich mich durch eine Sticky Session an gewisse Server oder ein gewisse Datenbank dahinter binde, habe ich einfach nicht. Es ist egal, wo meine Requests mit dem Handy auflaufen, ob auf Server 1 oder Server 100, interessiert keinen am Backend. Warum machen das nicht alle so? Warum dauert das so lang?
Lucas: Ja, es ist auf jeden Fall eine interessante Frage. Ich möchte vorgreifen und einfach dich davor schützen, dass Leute Mails schreiben. Die sind nicht unbedingt verschlüsselt, das ist eine Option. Man kann sie tatsächlich verschlüsseln oder man kann so etwas wie HMAC benutzen und dann sind sie nicht verschlüsselt. Sie zu verändern auf der Client Seite fällt auf dem Server auf und dann können wir den ablehnen. Nicht dass nochmal ein Special vom Security Podcast, nur wegen uns stattfinden muss.
Robert: Aber ich will ja, dass Leute mir Emails schreiben. Vielleicht war das gerade meine Finte.
Lucas: Achso, okay dann nehme ich alles zurück. Warum sich das nicht durchgesetzt hat? Manchmal habe ich das Gefühl, das liegt vielleicht ein bisschen daran, dass es tatsächlich einen technischen Grund hat, dass in Rails es früher gar nicht so ohne Weiteres möglich war, jetzt auf Thread basierend zu skalieren, sondern dass man auf Prozessen basierend skaliert hat. Und dass man sich sehr früh Sorge darum machen muss. Was ist denn, wenn das jetzt irgendwie ein anderer Prozess abbekommt, diese Nachricht, wie gehe ich damit um? Man da sich eben sehr früh darauf besonnen hat, dass man diesen Prinzipien von Roy Fielding aus dem Rest Paper folgt, dass es eben alles stateless ist und dass diese Kommunikationen eben nicht darauf abzielt, welcher Server diese Anfrage entgegennimmt. Wenn man eine Programmiersprache hat, wo es relativ problemlos möglich ist, einen sehr großen Server sich zu kaufen, darauf super viele Threads zu starten und dazwischen dann Informationen miteinander zu teilen, dass das einfach ist. Sobald man den zweiten Server daneben stellt, muss man dann über so was wie Sticky Sessions nachdenken. Das ist glaube ich, der kulturelle Grund, warum das vielleicht auch früh passiert ist. Warum das nicht in mehr Frameworks eine Option ist, das einfach anzuklicken, zu sagen: Hey, ich möchte gerne in meine Sessions gerne einen Cookie ablegen, das weiß ich nicht, das frage ich mich auch. Obwohl ich das Gefühl habe, dass auch gerade in dem Go und JavaScript Universum, dass sich das da auch ein bisschen mehr durchgesetzt hat, dass man das als Option anbietet, die Session in einen Cookie zu legen. Das ist glaube ich Spekulation. Ich glaube, daher kommt es zumindest, warum das in Ruby passiert ist und nicht woanders.
Robert: Wir haben nämlich einer der meistgelesenen Artikel auf innoq.com ist von unserem Kollegen Torsten ein Artikel, der sich mit Cookie basierten Sessions in Springboot auseinandersetzt und Hilfestellung gibt, wie man die konfiguriert und damit möglich macht. Aber es ist ein bisschen mehr als eine Option zu setzen, die du dir jetzt gerade gewünscht hättest. Es ist weder Default, noch gibt es einen einfachen Schalter, den ich umlegen kann. Ich muss konfigurieren. Damit ist es erst mal für viele wahrscheinlich raus. Ich müsste erst mal wissen, dass es diese Option gibt. Ich müsste mir die Mühe machen, es zu konfigurieren. Ich muss darüber aufgeklärt sein, dass man so eine Architekturentscheidung treffen kann. Ob das heute anders ist, wissen wir beide glaube ich gerade nicht genau. Ich mutmaße das nur, weil es immer noch ein sehr, sehr, sehr erfolgreicher Artikel von uns ist. Wie sind eure Erfahrungen mit dem Framework und der Programmiersprache eurer Wahl? Nutzt ihr Cookie basierte Sessions? Wisst ihr es vielleicht nicht oder tut ihr das bewusst nicht? Was bringen eure Frameworks denn so mit? Lasst es uns wissen. [email protected]. Vielleicht gewinnt ihr ja Lucas‘ Buch.
Lucas: Genau.
Robert: Und das zweite, was ich dann ein bisschen daran knüpfen wollte ist, das hat eine Security Facette, diese Cookie basierten Sessions. Dann kam noch eine positive Erwähnung von einem Kollegen, der sich sehr viel mit Security Systemen täglich auseinandersetzt und der sagt: „Diese ganzen Ruby Security Themen, die ich kenne. Die Dokumentation, die Themen, mit denen die Ruby und vor allem die Rails Framework Leute sich beschäftigen, erklären in meiner Wahrnehmung immer erst mal sehr gut das Problem und dann erst, warum und wie das in Ruby on Rails gefixt oder umgesetzt wird.“ Da gibt es wohl ein tiefsitzendes Verständnis und auch hohe Prioritäten Security Lösungen Teil des Frameworks sein zu lassen. Das wurde hier besonders lobend erwähnt. Das ist auch so meine Wahrnehmung. Da ist mittlerweile in Rails super viel drinnen. Von dem Cookie Anti-Tainting Schutz, den du gerade erwähnt hast mit HMAC und alles, von Message encryption über Encryptiion at rest. Ich kann mittlerweile ganz einfach meine bestimmte Spalten in meiner Datenbank Tabelle verschlüsseln. Da gibt es eine API in Active Records. Wahnsinn, was es da mittlerweile so alles gibt im Core von Rails. Zum Beispiel erinnere ich mich daran, dass es auch eine CSP, also eine Content Security Policy gab. Wenn man sich Rails Anwendung neu generiert mit dem Code Generator, ist die standardmäßig immer noch auskommentiert, aber ich habe da alles drin, was ich brauche, um mir eine CSP zu konfigurieren. Sollte man heute unbedingt tun, für eine öffentliche Webanwendung.
Lucas: Ja, genau. Da finde ich das auch sehr positiv, dass man da nicht noch eine Library braucht. In Node gibt es dieses Helmet, da kann man sowas damit machen. Das muss man dazunehmen, das ist eben nicht dabei. Und hier ist es dabei und man wird auch ein bisschen dazu geschubst. Hey, willst du nicht vielleicht eine Content Security Policy für deine Anwendung definieren? Security kann niemals von dem Framework für dich gelöst werden. Das ist nichts, wo man einfach sagt: Ich habe das Framework, ich brauche mich nicht mehr darum zu kümmern. Ganz viele von diesen Sachen, da wird entweder Schutz aufgebaut, sowas wie ein CSRF Token, das ist auch in vielen anderen Frameworks Standard, aber das ist einfach alles eingebaut, ist dort aber gut erklärt, warum es das überhaupt gibt. Das ist das, was ich auch sehr positiv finde. Auf der anderen Seite gibt es viele Sachen, wo man zumindest in die richtige Richtung schon mal geschubst wird oder bestimmte Sachen da sagt das Framework: Hey, du kannst das jetzt nicht einfach an das Model übergeben, dann könnte alles hier rein geschrieben werden in die Datenbank. Da gibt es dann einen Fehler und da muss man erst mal an bestimmten Stellen sagen: Ja, das ist erlaubt, das ist erlaubt. Dann darfst du es durchgeben. Das finde ich auch sehr positiv, dass es einen einfach dazu auffordert, über bestimmte Sachen nachzudenken. Das ist glaube ich auch ein guter Weg, Security zu verbessern. Einfach alle Leute darauf hinzuweisen, an der Stelle sollst du daran denken. Aber es ist immer so, dass man selbst immer noch darauf achten muss, dass man Security beachtet. Das kann das Framework nicht verhindern, das geht nicht.
Robert: Was du gerade angesprochen hast, ist glaube ich die Parameter Allow List.
Lucas: Genau.
Robert: Dass du sagst folgende get post, was auch immer für Parameter, erlaube ich, dass die über ein Mass Assignment in mein Datenbank Modell laufen. Da hat Rails wirklich mal reagiert und nicht proaktiv agiert. Da gab es auch mal einen ganz dicken Vorfall auf GitHub, glaube ich sogar. Der Standard Rails Boilerplate Code. Da kann man jetzt auch wieder negatives zu Boilerplate Code sagen, wurde von einigen Kollegen. Der sieht so aus: Bei einem Update von einem beliebigen Datenbank Model. Bei GitHub war es tatsächlich das User Model. Der Standard Rails General Code sieht so aus, dass alle Attribute, die ein HTTP Formular schickt, ein HTML Formular schickt, in das Model gestopft werden. Ob ich die ändern will oder nicht, das ist einfach komfortabel. Ich kann mein Formular um Felder erweitern. Das geht durch den Controller ins Model rein und alles wird geupdated, super easy. Ich spare mir diese ganzen blöden Zeilen user.name=parents.name und so weiter und so fort. Das wurde aber ausgenutzt. Und zwar hat jemand einfach das Formular in seinen Dev Tools oder wie auch immer um die Felder Passwort und Passwort Confirmation erweitert. Ein bisschen Guesswork war da glaube ich auch nötig. Dann wurden einfach bei GitHub User Accounts die Passwörter ersetzt. Irgendwie so was, wenn ich mich richtig erinnere.
Lucas: Das müsste ich nachschauen.
Robert: Erst dann hat das Rails Team diese Parameter Allow Listen eingeführt. Aber das ging auch relativ schnell.
Lucas: Ja.
Robert: Das ist auch kein Vorwurf, dass man nicht aus Fehlern lernen kann.
Lucas: Ja.
Robert: Aber die Reaktion in der Rails Community war natürlich erst mal ein Stöhnen, weil man natürlich schon wieder mehr Code schreiben muss. Ich vergesse dauernd, wenn ich meine Modelle um Spalten erweitere über die Jahre hinweg, dass ich das immer in diese Allow Listen packen muss.
Lucas: Dann gehen bestimmte Sachen kaputt und das ist besser so rum, als wenn per Default erst mal irgendwas durchgeleitet wird, was du nicht wolltest. Dann nervt es dich eben mit Security Themen, damit du zumindest mal eine Entscheidung treffen musst. Und das ist glaube ich, der beste Weg, der ein Framework eingehen kann, um Leute eben bei Security so ein bisschen zu sensibilisieren. Einfach an bestimmten Stellen einfach nachzufragen, zu nerven.
Robert: Und an dieser Stelle würde ich gerne noch mal auf die Shownotes was setzen, und zwar die Ruby on Rails Security Guides. Das ist, glaube ich ein Teil der Framework Dokumentation, den man sich aber dringend auch mal angucken sollte, wenn man überhaupt gar nicht mit Ruby on Rails entwickelt. Den hat auch glaube ich der Kollege gemeint, der diese Security Facetten lobend erwähnt hat. Da kann man sehr viel über die Security von Webanwendungen an sich lernen, ohne dass man Rails API Doku liest. Von Eingabe - Ausgabe Absicherung. Wenn man bei unseren Kollegys vom INNOQ Security Podcast mal anklopft und fragt die: Was ist denn das eine Ding, wenn ihr euch nur ein Ding aussuchen dürftet oder könntet, wie man was sicherer macht im Web, dann würden die wahrscheinlich Eingabe - Ausgabe sichern. Das ist in Rails Standard. Wenn ich in meinem Template irgendwas ausgebe, was aus der Datenbank kommt, dann wird das gefiltert. Wenn da HTML oder JavaScript Text drin landen, dann werden die einfach gesichert ausgegeben, aber so, dass sie vom Browser nicht mehr interpretiert werden können. Da fällt man erst mal hin, wenn man erwartet, dass das funktioniert. Man muss dann wirklich Opt-In mäßig sagen: Ich will aber, dass das roh hier rauskommt, sonst kommt es eben nicht roh raus. Das ist so ein Framework Default, der glaube ich, immer eine gute Idee ist.
Lucas: Ja, auf jeden Fall. Aber da muss man auch klar sagen, dass das schon in vielen Frameworks mit eingebaut ist. Das ist, glaube ich, kein Alleinstellungsmerkmal. Da gibt es einfach ein paar Sachen, die noch darüber hinausgehen, dafür zu sorgen, dass das passiert. Aber grundsätzlich stimme ich dem schon zu.
Robert: Ich hab persönlich super viel über Security erst durch Rails gelernt, muss ich gestehen. Also dadurch, dass eben immer neue Features kamen, man verfolgt das so ein bisschen, beschäftigt man sich überhaupt erst mit diesen Themen. Ich hätte mich, glaube ich, nie mit dem Allow Listing beschäftigt, nie mit sicherer Ein- und Ausgabe, wenn das nicht von Rails so verordnet oder verdonnert worden wäre. Dann hätte ich mich damit nicht beschäftigt. Wahrscheinlich erst spätestens dann, wenn mir ein böser Fehler passiert. Das finde ich ja auch eigentlich ganz schön, dass man durchs Framework auch so Best Practices für die Entwicklung von Webanwendungen lernt.
Lucas: Ja, definitiv. Das ist eben der Vorteil daran, dass es so ein Gesamtpaket ist, wo eben alles mit dabei ist. Dann muss man sich auch mit allem beschäftigen. Dann fragt man sich: Warum ist das eigentlich so? Warum ist das eigentlich so? Und dann lernt man auch neue Dinge. Wenn man das alles selbst zusammenstellt aus Libraries, die man aus seinem Paketmanager zieht, dann vergisst man vielleicht auch einfach einen Aspekt. Da habe ich einfach nicht daran gedacht und da ist er schon mit dabei. Da muss man zumindest mal drüber nachdenken, warum er da ist. Das ist eben auch ein Vorteil an dieser Gesamtpaketphilosophie. Da ist irgendwas dabei, das irgendwie dafür sorgt, dass Model Layer und Controller Layer miteinander sprechen. Und dann wird da eben auch schon mal was gemacht, worüber man zumindest mal nachdenken muss. Wenn man das Model Layer und das Control Layer aus zwei völlig unterschiedlichen Quellen zieht aus seinem Paket Manager, die wissen nichts voneinander und dann können die auch solche Sachen gar nicht machen. Das ist glaube ich auch etwas, was manchmal unterschätzt wird, dass das einfach die Leute noch mal zum Nachdenken bringt. Und ich habe ganz, ganz viele Sachen in Ruby on Rails über Webentwicklung gelernt, weil es einen in bestimmte Richtungen drängt. Es drängt einen dazu, darüber nachzudenken: Hey, warum hat denn diese Route hier eigentlich nur einen Get und nicht einen Put oder Post? Das bringt einen dazu, darüber nachzudenken. Wenn man dasselbe in einem Express-artigen Framework wie Sinatra mache, das drängt einen überhaupt nicht diese Richtung. Da baut man einfach so viele Routen dazu, wie man möchte und da wird das einem nicht nahegelegt. Das sind, glaube ich, schon wichtige Aspekte, die auch dazu geführt haben, dass bestimmte Sachen in die Köpfe gekommen sind. Wie gestalte ich eine URL? Gibt es bestimmte Sachen, wie die URLs per default aussehen? Ob das jetzt perfekt ist oder nicht, hat schon jemand darüber nachgedacht. Man macht es nicht ad hoc und guckt einfach mal, wie es so geht. Und das sind glaube ich Sachen, wo Rails eben ein Wegbereiter war und vielleicht auch immer noch ist, um bestimmte Aspekte einfach hervorzuheben.
Robert: Übrigens, ich habe es gerade kurz erwähnt, um das Thema Security hier auch abzuschließen, hört unbedingt in den INNOQ Security Podcast rein. Das ist unser zweiter Podcast Kanal mit der Lisa und dem Christoph. Da ziehe ich persönlich mein Ganzes, um up to date zu bleiben. Was ist in Security wichtig für mich zu wissen, als gemeiner Entwickler. Das ziehe ich heute daher. Bin ich auch froh, dass es den gibt. Das ist für mich genau die richtige Tiefe, die ich brauche, um so Webanwendungen weiter hoffentlich sicher zu entwickeln. Hört da unbedingt mal rein. Die haben jetzt auch gerade einen Adventskalender herausgebracht mit 24 Minifolgen. Da gibt es überhaupt keine Ausreden, diese Folgen mal kurz zu hören, weil die gehen wirklich nur ganz kurz und man tankt auch sofort Wissen. Das war der schamlose Werbeblock. Widmen wir uns doch jetzt mal noch vielleicht zwei anderen Sachen und dann sprengen wir hier auch schon wieder die erlaubte Zeit, die es eigentlich gar nicht gibt, die wir uns aber selbst verordnen. Es hatten noch Leute gesagt, mehrfach gab es die Erwähnung. „Aus meiner Wahrnehmung und ich habe kein Rails gemacht, aber haben die als erste CLI Tooling bereitgestellt, um Boilerplate Codes zu generieren.“ Was ist damit gemeint? In Rails gibt es ganz viele Tasks, also Befehle, die ich in meinem Terminal ausführen kann. Die generieren mir Code in meiner Applikation, damit ich das nicht alles tippen muss, zum Beispiel für Datenbank Migration. Ich kann mir meine ganze Rails Anwendungen mit einem Kommando erzeugen lassen. Dann fällt dann die Ordnerstruktur für meine Model Views Controllers raus. Es ist alles schon vorgegeben, da wird alles von einem Boilerplate Generierungskommando erzeugt. Das haben mehrere Leute positiv erwähnt. Es gibt aber gleichzeitig auch noch eine negative Erwähnung, dass genau das eben doof wäre, dass Rails das so populär gemacht hat. Boilerplate Code hat Vor- und Nachteile. Ich muss viel nicht selber schreiben, aber viel bleibt auch eben geschrieben für die Ewigkeit. Aus meiner Wahrnehmung kann man das auch so sehen, weil Rails hat da auch Schwachstellen. Zum Beispiel wenn ich die Versionen update, muss ich immer noch meine Environment Konfigurationsdateien mühsam diffen und gucken, welche neuen Optionen gibt es? Nehme ich die hier vielleicht rein? Rails bietet mir beim Update eigentlich nur an, die zu überschreiben, aber da sind Sachen drin, die möchte ich behalten. Und zeilenweise Update gibt es auch nicht. Deswegen gehe ich immer noch so vor, dass ich das mühsam, da gibt es eine Seite, für die benutze ich schon ganz lange, railsdiff.org heißt die, wir packen die in die Shownotes. Da kann ich mir den Diff von allen Framework Boilerplate Dateien anzeigen lassen, über Rails Versionen hinweg, sogar Patch Level Version. Das hilft mir immer und das zeigt auch, dass das immer noch eine Schwäche ist. Zumindest den Konfigurations-Code, dass der mühsam zu updaten ist. Wenn man schon viele Jahre Rails Anwendungen betreibt, die schon viele Rails Major Versionen gesehen hat. Bin ich da falsch unterwegs, oder was sagst du dazu?
Lucas: Ich glaube, das sind auch zwei leicht unterschiedliche Sachen. Das eine ist eben einen grundlegenden Controller Boiler Plate zu erzeugen und das andere ist der Boiler Plate, den die Konfiguration mit sich bringt. Ich glaube das mit dem Controller, das nehmen wenige Leute als was Negatives wahr, dass das unfähig ist. Das würde man wahrscheinlich in vielen Programmiersprachen mit der IdE generieren. Und in der Rails Welt war frühzeitig Texteditor als Hauptwerkzeug dabei. Textmate mal kurz erwähnt als ein Editor, den viele Leute in der frühen Rails Zeit sehr viel eingesetzt haben, wo es dann einfach solche Sachen nicht gab mit Code Generierung und dann ist es sehr logisch das auf dem Command Line zu machen. Das Charmante daran ist eben, dass man dann unabhängig ist von all dem anderen Kram, den man da so braucht. Das heißt, man ist nicht gebunden daran, eine IdE zu benutzen, sondern man kann auch den Texteditor benutzen oder VS Code oder was auch immer. Das ist irgendwie das schöne daran. Aber ja, das mit der Konfiguration, das ist so ein Wermutstropfen, den mal immer wieder mal merkt, wenn man dann eben eine Major Version von Rails updated. Da muss man halt doch noch mal gucken. Hat man all seine ganzen Parameter mit rüber gezogen, muss man irgendwas beachten? Aber ich glaube, die Schmerzen sind irgendwie immer schrittweise weniger geworden. Von 2 zu 3 war das ein sehr großer Schmerz. Von 3 zu 4 war es auch immer noch ein ziemlicher Schmerz, aber nicht mehr so schlimm. Und jetzt irgendwie von 5 auf 6 und von 6 auf 7. Da ist das jetzt nicht mehr als 20 Minuten Arbeit, da zu gucken, dass diese Konfigurationsparameter kommen. Und es kommt jetzt auch nicht jedes Jahr eine neue Major Version raus, sondern eher so alle 2 bis 3 Jahre. Das ist ein Nachteil, da stimme ich zu. Aber es ist nicht so gravierend im Alltag, dass es einem weh tut.
Robert: Ich bin faul, deswegen tut es mir vielleicht auch nur weh. Gut. Danke für die Einordnung. Wie ist es mit euren Frameworks und euren Programmiersprachen? Wie ist es da mit Boilerplate? Belehrt uns gerne auch über unser mangelhaftes Spring Boot Einsichten. Ich hoffe, wir haben hier heute keine falschen Sachen wiedergegeben. Bitte gebt uns Feedback, Meldet euch unter allen Einsendungen, egal was ihr habt, auch wenn es euch einfach nur gefallen hat. Wenn euch die Sendung nicht gefallen hat, wenn ihr was beitragen wollt, was bedeutet der Rails Way für euch? Schreibt uns, egal was. Wir verlosen unter allen Mails an [email protected] zu dieser Folge das Buch “The Rails Seven Way”. Und zwar fünf Stück davon. Lucas, haben wir noch was? Wir könnten noch endlos hier uns an den Punkten lang hangeln, aber wir machen hier mal einen Cut, würde ich sagen.
Lucas: Ja, würde ich auch sagen. Ich glaube, wir haben genug abgedeckt von den ganzen Sachen, die diskutiert wurden.
Robert: Gut. Lasst uns wissen, wie ihr es fandet. Wir freuen uns über euer Feedback, eure Zusendungen und sagen mal bis zur nächsten Folge. Mindestens mal mit Lucas, irgendwann vielleicht mal wieder mit mir oder uns beiden. Mal gucken, wer noch so kommt.
Lucas: Genau. Dann einen schönen Tag noch, Robert.
Robert: Dir auch. Bis dann. Tschüss.
Lucas: Tschüss.