Unterschiede Phoenix und Rails durch die Augen des Bekehrten

    Was ihm am ehesten beim begeisterten Rubisten auffiel, als er gerade mit Elixir bei Phoenix angefangen hatte.

    Hinweis


    Ich bin ein einfacher Mann und ich werde nicht tief gehen. Daher wird es Unterschiede zwischen Arbeitern und Bauern geben, aber es wird nichts zu den Unterschieden auf der Ebene des Anwendungsstarts, zu den Prinzipien der Erlang Virtual Machine und dem OTP-Protokoll gesagt.


    Haupteindruck


    Elixir / Phoenix ist Rails sehr ähnlich und sieht ihm gar nicht ähnlich. Wie einige englische Ausdrücke: einzeln sind die Wörter bekannt, aber zusammen ist es nicht klar.


    Erlang vs Ruby


    Ruby zu denken und zu versuchen, auf Elixier zu schreiben, ist schwer. Sie kommen regelmäßig in eine Sackgasse, weil das, was Sie wollten, nicht das ist, was Sie früher getan haben ... oder Sie wollen es überhaupt nicht.


    Und der Rest, über die Unterschiede zwischen Erlang und Ruby, schreiben Leute Bücher, also werde ich mich kurz fassen. Für mich waren die Haupt-Hinterhalte die "Lokomotiven" der Eisenbahn durch eine Pipe, die das Denken auf den Funktionalismus umstellten (das Gute war die alte Erfahrung von Haskell und die allgemeine Liebe zu inject/ foldr) und subjektiv strengere Anforderungen an die Datentypen (obwohl offiziell beide.) Sprache mit strenger dynamischer Typisierung).


    Das Pattern-Matching brachte keine Überraschung, und ich verstand immer noch nicht, warum so viel über ihn geredet wurde. Nur ein interessantes Werkzeug.


    Common scop


    In Elixir liegt alles in den Modulen. Keine globale Schaufel. Bounces C #.


    Mit anderen Worten: Eine flache Schiene macht es an manchen Stellen nicht möglich, eine Hierarchie zu erstellen (ich erinnere mich daran, dass es einmal Fehler bei Controllern in Modulen gab). Elixier - im Gegenteil alle von Modulen. In der Schiene wird der Zweck des Objekts von der übergeordneten Klasse und im Elixier anhand des vollständigen Namens der Klasse / des Moduls erraten.


    Kompilierbarkeit


    Zum einen fehlte mir das manchmal an der Schiene. Da Sie eine gute Hälfte der Fehler direkt beim Kompilieren finden können, und nicht zur Laufzeit in der Produktion. Auf der anderen Seite dauert das Kompilieren Zeit. Aber auf der dritten Seite braucht es etwas, und ich habe noch keine großen Projekte auf dem Elixier gesehen (und nicht gemäß Erlangs Bündnissen, um große Monolithen zu schreiben). Schließlich haben die Jungs vom Elixier den Code und die Seite dynamisch nachgeladen. Und bisher wärmt die Arbeitsgeschwindigkeit zusammen mit dem Mangel an gottlosem Zeus / Frühling meine Seele.


    Dies führt natürlich auch zu Nachteilen, die jedoch erst später zum Vorschein kommen. Irgendwo in der Produktionsumgebung und im Einsatz. Dies wird unten sein.


    Sofort gibt es einen interessanten Moment, der auf der Schiene physisch nicht passieren kann: Migrationen und andere Dinge, die in den Schienen durchgehen rake, im Elixier erfordern eine Kompilierung des Projekts, und so etwas könnte passieren: Vergessen, Routen zu schreiben, werden sie in der Ansicht durch den Pfadhelfer referenziert Migrationen sind abgefallen. Zunächst ungewöhnlich.


    Dokumentation


    Website mit Dokumentation Elixier sieht viel frische und rubidoka apidoka. Aber der Umfang der Dokumentation und Beispiele - das ist Ruby / Rails weit voraus. In Elixir gibt es viele Beispiele für alles, was etwas komplizierter ist als ein Hocker. Und die Beschreibung einiger Methoden ging tatsächlich nicht über die Signatur hinaus. Wie ich von Rubinen an eine Fülle von Beispielen und Beschreibungen gewöhnt war, war ich mit einigen Elixiermethoden schwierig. Manchmal musste ich lange Zeit herumstochern und experimentieren, um die Verwendung der einen oder anderen Methode zu verstehen, da ich die Sprache nicht gut genug kenne, um den Quellcode der Pakete frei zu lesen.


    Unabhängigkeit des Dateispeicherorts von seinem Inhalt


    Wie das Sprichwort sagt "mit großer Macht kommt große Verantwortung". Einerseits können Sie die Orgie verwirren und Objekte zerlegen, so dass der Feind nicht durchkommt. Andererseits können Sie Pfade logischer und visueller benennen, indem Sie logische Ebenen von Verzeichnissen hinzufügen, die sich nicht in der Klassenhierarchie befinden. Vor allem können wir uns an den Wegbereiter und sein Publikum erinnern, mit dem Gedanken, alles, was mit Aktion zu tun hat, an einem Ort zu kombinieren. Im Elixier kann dies ohne Bibliotheken von Drittanbietern und Klassenhaufen durchgeführt werden, indem einfach vorhandene Dateien korrekt verschoben werden.


    Transparenter Abfragepfad


    Wenn in Rails die Frage nach dem Rack ein unverzichtbares Attribut eines Interviews ist, da die Schiene die Spitze des Eisbergs ist und Sie regelmäßig Ihre Middleware erstellen möchten. Dann entsteht im Elixier eines solchen Verlangens überhaupt nichts (obwohl ich vielleicht noch jung bin und alles vor mir habe). Es gibt eine explizite Pipeline, durch die die Anforderung geleitet wird. Und dort können Sie deutlich sehen, wo die Sitzung abgerufen wird, wo die Flash-Nachricht verarbeitet wird, wo die CSRF validiert wird und all dies kann an einem Ort nach Belieben verwaltet werden. In der Schiene ist diese Farm teilweise an verschiedenen Stellen vernagelt und teilweise verstreut.


    Routen von innen nach außen


    In Rails ist die Situation die Regel, wenn eine Aktion in mehreren Formaten reagieren kann. Sie (.:format)legten sogar direkt in die Routen. In dem Elixier erscheint aufgrund der oben genannten Eigenschaft mit der Pipeline der Gedanke an das analoge Format überhaupt nicht. Verschiedene Formate gehen auf unterschiedliche Pipelines und haben unterschiedliche URLs. Für mich ist es so toll.


    Schema im Modell


    Dies ist im Allgemeinen ein Märchen. Wie werden die Felder des Modells beschrieben? Keine implizite Typenkaste. Außerdem gibt es keine Krücken, die den Zugriff auf das in der Datenbank enthaltene Feld verbieten. Aus irgendeinem Grund kann es jedoch nicht in der Webanwendung verwendet werden.


    Validierungen und Rückrufe


    Es gibt keine Rückrufe im Elixier. Es gibt immer mehr geradlinig. Und es scheint, ich mag es.


    Anstelle eines Schienenweges im Changeset- Elixier , das strong_parameters, Validierungen und einige Callbacks kombiniert. Und die Reste von Rückrufen laufen durch Multi , wodurch es möglich ist, eine Reihe von Operationen zu sammeln, transaktional auszuführen und das Ergebnis zu verarbeiten.


    Kurz gesagt, alles ist einfach anders. Zunächst ist es ungewöhnlich. Dann ist er an manchen Orten wütend, weil Sie nicht einfach einen weiteren Rückruf für alles einfügen können und nicht über verschiedene Geschäftsfälle nachdenken müssen. Und dann fängt man an, den "unerklärlichen Charme" zu bemerken , weil man es richtig machen muss und nicht wie gewohnt.


    Arbeit mit DB


    Anstelle von ActiveRecord erschienen einige Ecto.Repo , Ecto.Query und einige ihrer Gefährten. Um alle Unterschiede zu erkennen - dies ist ein separater Artikel. Deshalb werde ich die wichtigsten subjektiven Gefühle sagen.


    In Debug ist es bequemer als AR. Da es einen gemeinsamen Bereich gibt, werden die Konstanten aus dem Ladepfad geladen, wenn auf sie zugegriffen wird, und Sie können das Ergebnis einfach öffnen rails c, schreiben User.where(email: 'Kane@nod.tb').order(:id).firstund abrufen.


    In Elixir reicht die Konsole nicht aus. Wir müssen eine Reihe von Aktionen ausführen:


    • zaimportit Methode für die Erstellung von SQL-Abfrage: import Ecto.Query, only: [from: 2];
    • Füllen Sie Klassen, um nicht ihre vollständigen Namen durch den Punkt zu schreiben:
      • alias MyLongApplicationName.User- stattdessen MyLongApplicationName.Userschreiben User;
      • alias MyLongApplicationName.Repo - Ebenso für den Zugriff auf eine Klasse, die SQL ausführen kann und Ergebnisse liefert.
    • und erst jetzt kannst du schreiben from(u in User, where: u.email == "Kane@nod.tb") |> Repo.one

    Auf der anderen Seite geben diese "Formalitäten" im Anwendungscode besser lesbaren Code. Außerdem haben Sie das Gefühl, dass Sie kontrollieren, was passiert, und nicht, dass er sein eigenes Leben führt. Das heißt, Sie wählen selbst, welche Methoden, Modelle und anderen Objekte für die Arbeit benötigt werden, offensichtlich laden und verwenden Sie sie.


    Anwendungsname


    Im Image von Rails dachte ich, dass der Name der Anwendung in ein paar Configs verwendet wird und das war's. Daher wurde die Länge des Namens nicht beachtet. Und vergebens. In Elixir ist das Modul mit dem Namen der Anwendung die oberste Ebene in der Modulhierarchie der Webanwendung und wird überall angezeigt.


    Ich habe meine Sandbox Comindivion angerufen. Und jetzt leide ich ein wenig, da dies ein ziemlich langer Titel ist und Sie ihn ständig schreiben müssen. Sowohl in Klassendateien als auch in der Konsole, wenn Sie etwas aufrufen. Übrigens, ja, wen interessiert das? Hier ist eine Sandbox auf GitHub .


    N + 1


    In Rails haben wir es aus der Box heraus, aber in Elixir gibt es kein derartiges Problem. Dort können Sie in der Anforderungserstellungsphase angeben, welche Relais benötigt werden, und diese werden während der Ausführung dieser Anforderung selbst geladen. Nicht hochgeladen? Sie haben keinen Zugriff auf diesen Bericht. Alles ist einfach und schön.


    Anfragebearbeitung und Antwort


    Kurz gesagt: Im Phoenix ist alles klarer als in der Schiene.


    Überall conn


    Da der Status nicht in einem Haufen verschiedener Objekte gespeichert ist, muss er in einem Objekt mitgezogen werden. Erinnert requestan ActionController, nur umfassender. Er wird in Phoenix angerufen connection. Es enthält alles im Allgemeinen: und request, und flash, sessionund alles ist alles. Er erscheint auch im Aufruf für alles, was mit der Bearbeitung der eingehenden Anfrage zusammenhängt.


    Hier und Minus, da der erste sehr faul ist, überall zu formen connund nicht ganz zu verstehen, warum. Schiene in dieser Hinsicht korrumpiert. Sie schreiben Render oder Flash und glauben nicht, dass dies eine Aktion mit einer Verbindung ist. Und in Phoenix connerinnert es ständig daran, mit einer bestimmten Verbindung oder einem bestimmten Socket zu arbeiten, und es werden nicht nur Methoden aufgerufen, sondern auch Magie.


    Teil & Vorlage


    In Phoenix gibt es keine Trennung zwischen Partial und Template. Letztendlich funktionieren alle. Sofort gibt es noch eine weitere Schönheit: Die Schiene klettert selbst in der Prod-Umgebung ständig hinter den Ansichten auf der Festplatte und generiert IO und einen Overhead, um sie von Erb / Haml / etc in HTML umzuwandeln. Und in Elixir ist alles eine Funktion und auch Ansichten. Wir haben die Ansicht einmal kompiliert, und das ist es: Es braucht Argumente, spuckt HTML aus, es geht nicht auf die Festplatte.


    Ansichten


    Ansicht bedeutet in Rails partiell und Vorlagen, während sie sich in Phoenix in Vorlagen befindet, und in Ansichten gibt es grob gesagt verschiedene Möglichkeiten, Daten darzustellen. Insbesondere gibt es "Überschreibungen" des Renderers.


    Das heißt, der Controller gibt standardmäßig nichts aus. Alles wird explizit genannt. Wenn Sie keine partielle Version haben und diese nicht benötigen (z. B. bei Json, wenn es einfach ist, diese von der Service-Klasse zu erstellen), definieren Sie das Rendering folgendermaßen neu:


    defrender("show.json", %{groups: groups}) do
      %{
        groups: groups
      }
    end

    Und das partielle wird nicht mehr benötigt.


    Hepler


    In Phoenix sind sie nicht. Und das ist großartig! Denn bei Bahnhelfern wird normalerweise jeder Müll gesammelt, der entweder faul in die Ecken zu schieben war oder nur ein kurzes Durcheinander von etwas brauchte.


    Die Methoden im Controller, in den Ansichten usw. Sie können hinzufügen. Dies geschieht an einem besonderen Ort web/web.exund sieht ziemlich anständig aus.


    Statik


    In der Entwicklung ist alles wie üblich, außer dass im Phönix immer noch ein Live-Reload angeschraubt wird, der erste verursacht "Wow!" Wirkung. Dies ist, wenn ich CSS geändert habe, ich zum Browser zurückgekehrt bin und dort die Änderungen bereits geladen waren.


    Bei der Produktion in Phoenix unterscheidet sich das Verhalten der Statik geringfügig von dem der Schienen. Standardmäßig gibt es klar definierte Stellen, an denen Sie statische Objekte ziehen können, und Sie können nicht einfach Dateien zu Assets hinzufügen, um sie zu verteilen. Es gibt auch eine Zuordnung von Standard-Assets, sodass Sie nicht erneut durch das Dateisystem wandern, sondern die richtige Datei sofort verwenden und sie weggeben.


    Assets


    Aus dem Kasten heraus in Phoenix - Brunch . Kann durch Webpack ersetzt werden . Es ist jedoch ein wahrer Witz darüber, dass viele Projekte bei der Einrichtung eines Webpacks gebogen werden.


    Kurz gesagt, js und css werden mehr oder weniger gesammelt, aber der Rest der Statik im Brunch ist nicht sehr. Es ist entweder das Kopieren und Einfügen direkt von node_modules in das Projekt (diese Option gefällt mir überhaupt nicht), oder Sie schreiben Hooks in die Bash. Zum Beispiel so .


    Mit SSL arbeiten


    In Phoenix gibt es einen kleinen http-Server namens Cowboy . Es sieht aus wie ein rubinroter Puma . Sie haben sogar ungefähr die gleiche Anzahl von Sternen auf GitHub. Aber irgendwie bin ich nicht auf die SSL-Einstellung in den oben genannten gegangen. Speziell bei Let's Encrypt eine zusätzliche Datei der Webserver-Konfig und regelmäßige Zertifikatserneuerung. Als http-Server ist das also in Ordnung, und für ssl nehme ich einen Proxy auf localhost über apache / nginx.


    Depla


    Im Allgemeinen unterscheidet es sich von der Schiene. In Rails, in seiner minimalen Form, neigte er seine Rübe zum Server, tanzte mit einem Tamburin für ein Bündel, Konfigurationen, Assets und startete die Anwendung. Und das Elixier wird kompiliert unddie Straßenbahn begrabenBogenrübe ist keine Fahrt. Müssen Sie ein Paket erstellen. Und hier beginnt:


    • Sie erfahren, warum Anwendungen erforderlich sind mix.exs, weil sie beim Verkauf von wunderbaren Fehlern nicht richtig angegeben werden.
    • Sie erfahren, dass Umgebungsvariablen zum Zeitpunkt der Paketerstellung und nicht zum Zeitpunkt des Starts kompiliert werden. Dies führt zum ersten Mal zu einer Überraschung. dann erkennen Sie relx mit RELX_REPLACE_OS_VARS=trueeiner Bit - Ausgaben;
    • Sie sind überrascht, dass es in dem zusammengestellten Paket für die Produktion nichts wie Rake gibt, insbesondere gibt es keine Migrationen und diese müssen irgendwie separat ausgeführt werden, z. B. von einer Freundin über die Portweiterleitung in die Datenbank (oder über eDeliver , die ungefähr das Gleiche tut). .

    Und dann, wie bei dem oben beschriebenen, werden Sie verstehen, dass die Vorteile beginnen:


    • Sie können das Paket autark machen und nichts auf Abhängigkeiten von der Kampfmaschine setzen. Tarball einfach auspacken und den Inhalt ausführen; mit Ausnahme von erlang kann es notwendig sein, da die Cross-Compile-Version in der Assembly etwas trivial ist.
    • Sie können eine Upgrade-Version für die Bereitstellung ohne Ausfallzeiten durchführen.

    Debag


    Elixir hat Pry und arbeitet wie Rubine. Es gibt sogar ein Analogon rails c, das aussieht iex -S mix.


    In der Produktionskonsole müssen Sie es jedoch anders verwenden, da das Paket zusammengebaut ist und nicht mixdarin. Sie müssen sich mit einem laufenden Prozess verbinden. Dies unterscheidet sich grundlegend von der Schiene, und zu Beginn gönnen Sie sich viel Zeit, um die Elixier-Konsole in der Produktion zu starten, weil Sie nach etwas suchen, das der Schiene ähnelt. Am Ende merkt man , dass alles , was Sie anders machen müssen, und verursachen so etwas wie: iex --name trace@127.0.0.1 --cookie 'from_env' --remsh 'my_app_name@127.0.0.1'.


    Fortsetzung folgt...


    Fuh, ich habe sowieso etwas vergessen. Na ja. Sagen Sie mir besser, was Sie in Elixir überrascht hat, verglichen mit anderen Sprachen.

    Nur registrierte Benutzer können an der Umfrage teilnehmen. Bitte melden Sie sich an.

    Und wie geht es dir mit Elixir?


    Jetzt auch beliebt: