Clojure-Programmierung: Frameworks und andere Tools
Obwohl alle diese Bibliotheken darauf abzielen, Clojure-Programmieraufgaben zu vereinfachen, können sie Anfänger verwirren. Manchmal ist es schwierig zu verstehen, wie man sie alle zusammenfügt und eine optimale Lösung für eine bestimmte Aufgabe findet. So, jetzt möchte ich Ihnen meine Lieblings-Tools für die Programmierung in Clojure zeigen.
- Arbeiten mit Webserver und Endpunkten
- Interaktion mit Webserver und Datenbank
- Routing auf Server
- Verwenden von GraphQL in der Clojure-Programmierung
- Unterstützung der modularen Architektur
Beginnen wir die Reise in die Clojure-Programmierwelt!
Hinweis: Wenn Sie von Java und anderen ähnlichen Sprachen wechseln, sollten Sie wissen, dass es in Clojure keine traditionellen Frameworks gibt. Alles basiert auf Bibliotheken und ihren Sammlungen. Dies macht die Sprache flexibler und vielseitiger.
Das Clojure-Ökosystem enthält Bibliotheken unterschiedlicher Komplexität. Einige von ihnen sind nur eine Reihe zusätzlicher Funktionen (z. B. eine Bibliothek zum Arbeiten mit der Zeit). In der Zwischenzeit bieten Systembibliotheken eine Plattform für die Erstellung des gesamten Frameworks. Solche Bibliotheken ermöglichen es dem Programmierer, eine Anwendung als eine Reihe von Komponenten darzustellen, die Verbindungen zwischen ihnen zu beschreiben und so weiter. Die Bibliothek selbst stellt die Erstellung von Abhängigkeitsgraphen sicher. Zum Beispiel kann es Komponenten in verständlichere Dinge wie Funktionen umwandeln.
Zweck: komfortables Arbeiten mit Webserver und Endpunkten
Code: https://github.com/ring-clojure/ring
Die HTTP-Server-Abstraktion ist ein Schlüsselelement von Clojure Web Stack. Es ermöglicht ein einfaches Arbeiten mit Webservern und Endpunkten, was für eine erfolgreiche App-Entwicklung unerlässlich ist. Ring wurde in Analogie zu WSGI (Python) und Rack (Ruby) erstellt und abstrahiert die Informationen von HTTP in eine klare, einheitliche API. Infolgedessen kann der Webentwickler modulare Systeme aufbauen, die aus Komponenten bestehen, und diese Komponenten für verschiedene Server und Anwendungen freigeben.
- Wie funktioniert Ring?
- Gründe für die Verwendung von Ring
- Http-kit
- Wie funktioniert Http-kit?
- Gründe für die Verwendung von Http-kit
- Compojure und Bidi
- Wie funktionieren Compojure und Bidi?
- Was ist der Unterschied zwischen ihnen?
- Lacinia
- Wie wirkt Lacinia?
- Gründe für die Verwendung von Lacinia
- HoneySQL und HugSQL
- Wie funktionieren HoneySQL und HugSQL?
- Was ist der Unterschied zwischen ihnen?
- HugSQL pros
- HugSQL cons
- HoneySQL pros
- HoneySQL cons
- danielsz/system
- Wie funktioniert danielsz/system?
- Gründe für die Verwendung von danielsz/system
Wie funktioniert Ring?
Es ruft HTTP-Anforderungen ab und gibt HTTP-Antworten zurück. Ring ist also kein sogenanntes Webanwendungsframework.
Gründe für die Verwendung von Ring
Als dominante Webbibliothek in der Clojure-Programmierung ist Ring eine gute Wahl für Anfänger. Zuallererst besteht seine Hauptfunktion darin, eine bequeme Schnittstelle für eine breite Palette von Webservern bereitzustellen. Unter diesem Gesichtspunkt ist die Technologie äußerst nützlich und funktioniert perfekt.
Eine weitere Ring-Funktion ist die Bereitstellung einer Reihe von Modulen (‘Middleware’). So können Sie verschiedene vorgefertigte Bibliotheken verwenden, die miteinander kompatibel sind.
Die meisten Clojure-Programmierer wählen Ring für Endpunkte, da es Middleware verwenden kann. Mit diesen Modulen können beispielsweise erforderliche Parameter von einer URL in die Clojure-Codezuordnung umgewandelt werden. Ein Webentwickler kann problemlos neue Middleware schreiben und in das Ökosystem integrieren. Mit der cemerick / friend-Bibliothek können Sie beispielsweise den Autorisierungsprozess vollständig verwalten, verschiedene Strategien anwenden (beginnend mit Login und Passwort bis hin zu OAuth) usw. Ring Middleware hilft, den Prozess bequem zu beschreiben und zu starten. Es schließt alle Endpunkte, die für nicht autorisierte Benutzer verboten sind.
Erfahrung in der Verwendung von Ring ist wichtig für die Arbeit mit anderen Clojure-Technologien. Es ist das erste, was Sie verwenden können, um eine App in Bewegung zu bringen.
Http-kit
Zweck: Serverstart
Code: https://github.com/http-kit/http-kit
Die ereignisgesteuerte, hochwirksame HTTP-Server / Client-Bibliothek umfasst WebSocket sowie asynchrone Unterstützung.
Wie funktioniert Http-kit?
Es ist eine Bibliothek zum Organisieren einer ordnungsgemäßen Webserver-Interaktion. Http-kit eignet sich für hoch gleichzeitige asynchrone oder synchrone Anwendungen. Für WebSocket und HTTP Long Polling / Streaming ist es besser, eine einheitliche API zu verwenden.
Gründe für die Verwendung von Http-kit
Flexible Lösung
Http-kit bietet die Möglichkeit, sowohl mit synchronisierten als auch mit asynchronen Systemen zu arbeiten. Die erste Option ist einfach, während die zweite schneller arbeitet. Sie können also eine Auswahl treffen, die auf Ihrem spezifischen Zweck basiert. Darüber hinaus können Sie die Bibliothek mit Ring verwenden. Es funktioniert fast wie der Jetty Adapter.
Komfortable Nutzung
Die Bibliothek gewährleistet die Unterstützung von WebSockets sowie die perfekte Verarbeitung von HTTP-Anfragen. So wird das Erstellen einer Echtzeit-App einfacher. Darüber hinaus ist es ein Open-Source-Projekt. Die Bibliothek ist auf GitHub unter der Apache License Version 2.0 verfügbar.
Hervorragende Ergebnisse
HTTP-kit zeigt hohe Leistung und arbeitet trotz großer Belastung schnell. Gleichzeitig benötigt jede Verbindung nur wenige kB Speicher. Ein Client / Server, der von Grund auf neu geschrieben wurde, ist als einzelnes ~ 90-KB-JAR mit 0 Abhängigkeiten und ~ 3 KB Zeilen klarem Code verfügbar.
Viele Softwareentwickler betrachten HTTP-kit als grundlegendes Werkzeug für die Clojure-Programmierung.
Compojure und Bidi
Zweck: Routing auf dem Server
Code: https://github.com/juxt/bidi, https://github.com/weavejester/compojure
Sowohl Compojure als auch Bidi sind Technologien für das Routing in Web-Apps. Die erste Bibliothek ist in der Community sehr beliebt, während die zweite als praktische Lösung zum Schreiben in ClojureScript bekannt ist.
Wie funktionieren Compojure und Bidi?
Diese kleinen Bibliotheken stellen das Routing auf einem Webserver sicher. Infolgedessen kann ein Softwareentwickler Anwendungen schreiben, die aus mehreren separaten Teilen bestehen.
Was ist der Unterschied zwischen ihnen?
Die 2 Bibliotheken führen dieselbe Funktion aus. Aber im Gegensatz zu Compojure, Bidi:
- unterstützt sowohl clj als auch cljs
- ist isomorph und erweiterbar
Der Hauptunterschied besteht darin, dass es sich bei Bidi-Routen um Datenstrukturen handelt. Hier gibt es keine Makros. Die Bibliothek bietet also einen bequemen bidirektionalen Ansatz und andere Vorteile. Einige Webentwickler bevorzugen Bidi, da es jede Route eines bestimmten Handlers anzeigt. Darüber hinaus besteht die Möglichkeit, die Routen aus einer Konfigurationsdatei zu lesen, zu generieren und durch Funktionen und Introspect zu transformieren. Sie arbeiten unabhängig von bearbeiteten Anfragen. Der Entwickler kann also Dinge abgleichen, die nicht unbedingt Handler sind (z. B. Schlüsselwörter).
Lacinia
Zweck: Implementierung von GraphQL in der Clojure-Programmierung
Code: https://github.com/walmartlabs/lacinia
Diese beliebte Clojure-Bibliothek ist nützlich für diejenigen, die GraphQL implementieren möchten, während sie mit Web-APIs arbeiten.
Wie wirkt Lacinia?
Ursprünglich wurde GraphQL in JavaScript geschrieben. Lacinia ist ein offizieller Hinweis auf diese Implementierung. Es ist in Analogie zur ursprünglichen Spezifikation geschrieben. Es kann als Backend-agnostische GraphQL-Abfrageausführungs-Engine bezeichnet werden. Die Bibliothek stellt also den Kontakt zwischen Ihren Daten und dem GraphQL-Client her.
Gründe für die Verwendung von Lacinia
Mit GraphQL können Sie ganz einfach eine umfangreichere, kompliziertere Web-API erhalten. Lacinia vereinfacht die API-Entwicklung, da es Inline- / benannte Abfragefragmente, GraphQL-Schema-Introspektion, Abonnements, Schnittstellen, Vereinigungen, Aufzählungen, Eingaben und benutzerdefinierte Skalare unterstützt.
Die Bibliothek ist in einer EDN-basierten Schemasprache geschrieben und funktioniert perfekt mit GraphQL-Abfragen. Es basiert auf Antlr4. Lacinia hilft bei der effizienten asynchronen Abfrageausführung. Sie können es in jede Clojure-HTTP-Pipeline einstecken und die Begleitbibliothek lacinia-api für die HTTP-Unterstützung verwenden.
HoneySQL und HugSQL
Zweck: erfolgreiche Datenbankinteraktion
Code: https://github.com/jkk/honeysql, https://github.com/layerware/hugsql
Viele Webprogrammierer fühlen sich wohler mit SQL-Technologien wie Oracle, MS SQL, MySQL, PostgreSQL, SQLite usw. HoneySQL und HugSQL sind Abfrage-Builder, die stabilen Zugriff auf SQL-Datenbanken in Clojure-Anwendungen bieten.
Wie funktionieren HoneySQL und HugSQL?
Beide Bibliotheken stellen sicher, dass SQL in der Clojure-Programmierung unterstützt wird. So können Sie SQL-Datenbankbefehle auch in Clojure-Webanwendungen schreiben.
Was ist der Unterschied zwischen ihnen?
Mit HugSQL schreiben Sie zunächst separate SQL-Dateien und fügen sie in Ihre Anwendung ein. Der Query-Konstruktor ist von einer anderen beliebten Bibliothek, YeSQL, inspiriert. Es analysiert nicht nur SQL-Dateien in Clojure-Funktionen, sondern eignet sich auch für mehr Anwendungsfälle als YeSQL. HugSQL wird aktiv gepflegt. Es verfügt über protokollbasierte Adapter, die mehrere Datenbankbibliotheken unterstützen.
HugSQL hat mehrere Vorteile aufgrund von 2 grundlegenden Funktionen:
- die Abfragen werden direkt geschrieben, eine Abfrage für jede erforderliche Funktion;
- Die Abfragen werden in SQL geschrieben.
HugSQL pros
HugSQL bietet eine Trennung der Clojure-Syntax und der SQL-Semantik (WAS und WIE).
- Wir beschreiben, WAS in Clojure zu tun ist
( get-user-emails-nach-Benutzername “Alexandr Petrov”) ;->
- Wir beschreiben, wie dies in SQL zu tun
— : name get-user-emails-nach-Benutzername 😕 :*
wählen Sie user_emails.e-Mail von user_emails wo user_emails.user_id = :id
Infolgedessen können wir die Logik des Abrufs der Daten direkt in SQL ändern, ohne den Clojure-Code neu zu schreiben. Dies ist nützlich, wenn ein Datenbankschema geändert wird und die alte Abfrage nicht die erforderliche Struktur zurückgibt.
Darüber hinaus ist SQL selbst ein viel leistungsfähigeres Werkzeug für die Arbeit mit einem bestimmten DBMS. Es ermöglicht das Schreiben großer komplexer Abfragen mit “Join”, Aggregationen und Fensterfunktionen, was in Clojure äußerst schwierig sein kann.
Darüber hinaus ermöglicht SQL die Verwendung von Vorteilen eines bestimmten DBMS (z. B. Postgres). Dies ist wichtig, wenn Sie sicher sind, dass die Datenbank nicht geändert wird.
HugSQL cons
- Es ist schwierig, DBMS in der Mitte des Projekts zu ändern. Es wird notwendig sein, viele Anfragen zu überprüfen und die Syntaxunterstützung und die spezifische Ausgabe sorgfältig zu testen.
- Sie können Parameter an SQL-Abfragen übergeben. In einigen Fällen müssen die Teile der Abfragen jedoch von bestimmten Bedingungen abhängen. Obwohl HugSQL-Snippets das Ausführen dieser Aufgabe ermöglichen, müssen Sie dies häufiger mit Clojure tun.
HoneySQL bietet keine solche Trennung von SQL- und Clojure-Code. Sie sehen die Abfragen als Karte.
HoneySQL pros
- Es ist unabhängig von einer bestimmten Implementierung des DBMS, da es normalerweise direkte SQL-Abfragen vermeidet. Stattdessen verwendet es spezifisches DSL.
- Es ermöglicht die Verwaltung Ihres eigenen DSL basierend auf Clojure-Funktionen / Makros. Sie können auch einen Abfrage-Builder erstellen, in dem Zwischenanforderungen auf der Clojure-Seite gespeichert werden. Wenn Sie beispielsweise einen Benutzer nach ID oder einer anderen komplexen Logik definieren müssen, können Sie einen Teil der HoneySQL-Struktur speichern. Es wird zeigen, dass wir genau den Benutzer brauchen, nicht die Waren oder andere Daten. Dieses “Fragment” kann durch die erforderlichen Abfragen ersetzt werden. Als Ergebnis erhalten Sie einen kürzeren Code.
HoneySQL cons
- Es kann schwierig sein, die Vorteile eines bestimmten DBMS zu nutzen und komplexe Abfragen zu schreiben (z. B. mit Fensterfunktionen)
- Der Clojure-Programmierer muss den Code zum Abrufen von Daten und den Code zum Verarbeiten dieser Daten trennen. Die Trennung führt zu zusätzlichen Arbeiten am Refactoring.
danielsz/system
Zweck: Unterstützung der modularen Architektur
Code: https://github.com/danielsz/system
Hilfreiche Technologie zur Entwicklung hochmodularer Anwendungen in Clojure. Das Framework unterstützt eine effektive Interaktion zwischen Modulen und ist gut mit anderen Teilen des vielfältigen Clojure-Ökosystems kompatibel.
Wie funktioniert danielsz/system?
Die Bibliothek ermöglicht es einem Webprogrammierer, einen komponentenbasierten Ansatz zu verwenden. Sie können also eine Anwendung mit Modulen / Komponenten und den Verbindungen zwischen ihnen erstellen. Jede Komponente ist ein besonderes Objekt. Es hat seinen eigenen Lebenszyklus. Der Programmierer beschreibt, wie er startet, was er starten muss und wie er aufhört.
Unsere Anwendung besteht beispielsweise aus einem Webserver und einer Datenbank. Es macht keinen Sinn, den Webserver zu starten, bevor die Datenbank aktiviert wird. Wir beschreiben die Datenbankkomponente, beschreiben die Serverkomponente und die Abhängigkeit des Servers von der Datenbank. Beim Starten des Projekts geben wir an, dass wir den Webserver starten müssen. Die Bibliothek versucht automatisch, die Datenbank zu aktivieren. Dann wird, wenn möglich, der Server gestartet und die fertig aktivierte Datenbankkomponente an die Webserverkomponente übertragen. Dann wird das System bei Bedarf gestoppt.
Gründe für die Verwendung von danielsz/system
Im Gegensatz zur Beschreibung der gesamten Anwendung mit einer Reihe gewöhnlicher Clojure-Funktionen erleichtert die Projektbeschreibung als Komponenten das Ersetzen einer Komponente durch eine andere. Zum Beispiel, wenn Sie eine Anwendung testen, eine Datenbank durch eine andere ersetzen oder sie vollständig ausschalten und durch die aktuellen Daten ersetzen.
Bei Funktionen würden Sie alte Funktionen durch neue ersetzen. Sie werden den gleichen Namen haben, was oft Fehler verursacht. danielsz / system ist ein vorgefertigter Satz von Lösungen (für einen Webserver, eine Datenbank und vieles mehr), die als eine Reihe von Komponenten organisiert sind.
Ich hoffe, Sie verstehen jetzt besser, wie Sie Clojure verwenden und welche technischen Lösungen in Ihrem Projekt implementiert werden sollten. Meine weiteren Artikel werden die Vorteile dieser leistungsstarken und schönen Sprache sowie einige Tipps zur Entwicklung von Webanwendungen, Diensten und APIs enthalten. Abonnieren Sie also den FreshCode-Blog, wenn Sie mehr über die Clojure-Programmierwelt erfahren möchten.