Wie erstellt man eine Webanwendung in Clojure? [geschlossen]


216

Ich nehme an, dies ist eine seltsame Frage für die große Mehrheit der Programmierer, die täglich mit Java arbeiten. Ich nicht. Ich kenne Java-the-language, weil ich an Java-Projekten gearbeitet habe, aber nicht Java-the-world. Ich habe in Java nie eine Web-App von Grund auf neu erstellt. Wenn ich es mit Python, Ruby machen muss, weiß ich, wohin ich gehen soll (Django oder Rails), aber wenn ich eine Webanwendung in Clojure erstellen möchte, nicht weil ich gezwungen bin, in einer Java-Welt zu leben, sondern weil ich mag die Sprache und ich möchte es versuchen, welche Bibliotheken und Frameworks soll ich verwenden?


1
Ich habe mich gefragt, ob Sie Java Native API oder Clojure Native verwenden möchten.
Ande Turner

Ande: Ich bin mir wirklich nicht sicher, da ich in dieser Hinsicht so wenig über die Java-Welt weiß (aber ich benutze Java, die Sprache, schon seit einiger Zeit bei der Arbeit).
Pupeno

Ich denke, es wäre schön, wenn diese Frage eine Liste von Clojure-Webframeworks mit jeweils einer Antwort ergeben würde und jeder seinen Favoriten wählen könnte. Ich denke, Meredydd's ist definitiv die Antwort des Compojure. Ich werde eine für Webjure hinzufügen und es wäre schön, einen Vergleich zu haben.
Pupeno

Pupeno! Ich bin hier auf der Suche nach "Webanwendungen mit Clojure" angekommen. Diese Seite war das erste Ergebnis in Google.
Sebastián Grignoli

Antworten:


104

Das mit Abstand beste Clojure-Webframework, auf das ich bisher gestoßen bin, ist Compojure: http://github.com/weavejester/compojure/tree/master

Es ist klein, aber leistungsstark und hat eine wunderschön elegante Syntax. (Es verwendet Jetty unter der Haube, aber es verbirgt die Servlet-API vor Ihnen, es sei denn, Sie möchten es, was nicht oft der Fall ist.) Schauen Sie sich die README-Datei unter dieser URL an, laden Sie einen Schnappschuss herunter und beginnen Sie zu spielen.


16
War Richards Kommentar für diese Antwort gedacht? Ich verstehe es nicht
John Cromartie

26
@ Richard Dein Argument ist ziemlich dumm. Ja, wenn Sie sich für die Verwendung von Java-Bibliotheken entscheiden, geben Sie in vielen Fällen die Funktionsfähigkeit auf. Der Sinn dieser Bibliotheken ist jedoch, dass Sie es nie wieder tun müssen . Beispielsweise ist Ring ein Clojury-Wrapper um Servlets, sodass Sie Servlets nicht direkt verwenden müssen. Würden Sie vorschlagen, das Webentwicklungsrad von Grund auf neu zu erfinden, anstatt die perfekt guten Java-Tools von Clojure aus benutzerfreundlich zu machen? Wo ist die Logik darin? Darüber hinaus , wie wird mit der Option , diese Bibliotheken eine schlechte Sache mit? ...
Rayne

15
@Richard Ihr gesamtes Argument impliziert, dass nicht funktionierender Nicht-Clojure-Code von Natur aus so schlecht ist, dass selbst das Vorhandensein unter einer Bibliothek eine Kontamination darstellt. Ich verstehe diese Argumentation nicht. Viele Java-Bibliotheken sind nützliche und leistungsstarke Codeteile. Warum sollten wir diese von Grund auf neu schreiben, wenn wir einfach unsere eigenen Wrapper-Bibliotheken bereitstellen können, die es ermöglichen, sie elegant und funktional von Clojure aus zu verwenden?
Rayne

10
@Richard, zögern Sie nicht, einen reinen Clojure-http-Server zu erstellen.
Gtrak

5
In Lisp / Clojure-Begriffen hat eine Funktion keine Nebenwirkungen. (siehe gigamonkeys.com/book/… ). Wie im Land von Lisp ( landoflisp.com/trade_func.png ) ausgeführt, ist ein rein funktionales Programm jedoch normalerweise nicht sehr nützlich, da Nebenwirkungen erforderlich sind, um Dinge wie das Schreiben von Datenbankeinträgen, das Herunterladen von Dateien und das Posten in einem zu tun REST-Server, Bilder generieren, etc ...
lfalin

179

Compojure ist kein vollständiges Framework mehr für die Entwicklung von Webanwendungen. Seit der Veröffentlichung von 0.4 wurde compojure in mehrere Projekte aufgeteilt.

Ring bietet die Grundlage, indem der HTTP-Anforderungs- und Antwortprozess abstrahiert wird. Ring analysiert die eingehende Anfrage und generiert eine Karte, die alle Teile der Anfrage wie uri, Servername und Anforderungsmethode enthält. Die Anwendung verarbeitet dann die Anforderung und generiert basierend auf der Anforderung eine Antwort. Eine Antwort wird als Karte dargestellt, die die folgenden Schlüssel enthält: Status, Überschriften und Text. Eine einfache Anwendung würde also so aussehen:

(def app [req]
  (if (= "/home" (:uri req))
    {:status 200
     :body "<h3>Welcome Home</h3>"}
    {:status 200 
     :body "<a href='/home'>Go Home!</a>"}))

Ein weiterer Teil von Ring ist das Konzept der Mittelware. Dies ist Code, der sich zwischen dem Handler und der eingehenden Anforderung und / oder der ausgehenden Antwort befindet. Einige integrierte Middleware-Funktionen umfassen Sessions und Stacktrace. Die Sitzungs-Middleware fügt der Anforderungszuordnung einen: Sitzungsschlüssel hinzu, der alle Sitzungsinformationen für den Benutzer enthält, der die Anforderung stellt. Wenn der Sitzungsschlüssel: in der Antwortzuordnung vorhanden ist, wird er für die nächste Anforderung des aktuellen Benutzers gespeichert. Während der Stack-Trace Middleware alle Ausnahmen erfasst, die während der Verarbeitung der Anforderung auftreten, wird ein Stack-Trace generiert, der als Antwort zurückgesendet wird, wenn Ausnahmen auftreten.

Die direkte Arbeit mit Ring kann mühsam sein, daher baut Compojure auf Ring auf und abstrahiert die Details. Die Anwendung kann jetzt als Routing ausgedrückt werden, sodass Sie Folgendes haben können:

(defroutes my-routes
  (GET "/" [] "<h1>Hello all!</h1>")
  (GET "/user/:id" [id] (str "<h1>Hello " id "</h1>")))

Compojure arbeitet weiterhin mit den Anforderungs- / Antwortzuordnungen, sodass Sie bei Bedarf jederzeit darauf zugreifen können:

(defroutes my-routes
  (GET "*" {uri :uri} 
           {:staus 200 :body (str "The uri of the current page is: " uri)}))

In diesem Fall greift der Teil {uri: uri} auf den Schlüssel: uri in der Anforderungszuordnung zu und setzt uri auf diesen Wert.

Die letzte Komponente ist Hiccup, was das Generieren des HTML erleichtert. Die verschiedenen HTML-Tags werden als Vektoren dargestellt, wobei das erste Element den Tag-Namen darstellt und der Rest der Hauptteil des Tags ist. "<h2>A header</h2>"wird [:h2 "A Header"]. Die Attribute eines Tags befinden sich in einer optionalen Zuordnung. "<a href='/login'>Log In Page</a>"wird [:a {:href "/login"} "Log In Page"]. Hier ist ein kleines Beispiel mit einer Vorlage zum Generieren des HTML.

(defn layout [title & body]
  (html
    [:head [:title title]]
    [:body [:h1.header title] body])) 

(defn say-hello [name]
  (layout "Welcome Page" [:h3 (str "Hello " name)]))

(defn hiccup-routes
  (GET "/user/:name" [name] (say-hello name)))

Hier ist ein Link zu einem groben Entwurf einiger Dokumentationen, die derzeit vom Autor von compojure verfasst werden und die Sie möglicherweise hilfreich finden: Compojure Doc


48

Es gibt auch "Noir" ( http://www.webnoir.org/ ), ein neues Clojure-Webframework (so neu, dass die Dokumente noch nicht vorhanden sind). Ich komme aus Django / Rails und mag die einfache, unkomplizierte Syntax, die ziemlich schlank ist.


Webnoir ist wirklich sehr nützlich! Es ist sehr einfach, damit zu beginnen - Sie können es ein bisschen entwickeln, als würde man PHP entwickeln - starten Sie einfach einen Server (diesmal mit leiningen), bearbeiten Sie Ihre Dateien und laden Sie Ihren Browser neu, um zu sehen, was Sie haben.
Claj

Seit @elithrar geantwortet hat, hat Noir jetzt die Dokumente zur Verfügung: webnoir.org/docs
Alistair Collins

18
Nur zur
Veranschaulichung


20

Meine aktuelle Webbibliothek ist jetzt yada .

Wenn Sie gerade erst anfangen, ist der Einführungsserver Compojure. Ich sehe es als den apachevon Webservern in der Clojure-Welt (in diesem Fall wäre yada / aleph nginx). Sie können Luminusals Vorlage verwenden. Es gibt Varianten davon, wie compojure-api.

Ich habe es versucht Pedestalund war weltweit zufrieden damit. Ich behaupte nicht, es zu beherrschen, aber es hat eine angenehme Syntax, fühlt sich sehr zusammenhängend an und sieht aus, als hätte es eine großartige Leistung. Es wird auch von Cognitect(der Firma Clojure / Datomic, in der Rich Hickey arbeitet) unterstützt.

Ich fand Alepheine interessante Abstraktion, und der eingebaute Gegendruck scheint interessant zu sein. Ich habe noch nicht damit gespielt, aber es ist definitiv auf meiner Liste.

Nachdem ich ein bisschen mit verschiedenen Webservern gespielt habe, ist hier meine kurze Pro / Cons-Liste:

Kurze Antwort: Schauen Sie sich Luminus an, um schnell loszulegen, und gehen Sie vielleicht zu etwas anderem über, wenn sich Ihre Bedürfnisse ändern (Yada vielleicht).

Compojure

  • Vorteile (1):

    • einfach, viele Vorlagen / Beispiele (zB Luminous)
  • Nachteile (2):

    • Nicht performant (ein Thread pro Anfrage), erwarten Sie Leistungen, die etwas besser sind als Schienen
    • Nicht einfach, das Middleware-Modell hat Unannehmlichkeiten

Sockel

  • Vorteile (3):

    • Interceptor-Modell, angenehme Syntax zum Hinzufügen von Interceptors zu einer Teilmenge von Routen
    • performanter Router
    • unterstützt Json / Transit / Multipart-Formulare sofort transparent, ohne etwas zu fragen. Sehr cool !
  • Nachteile (4):

    • (noch) keine Websocket-Unterstützung, die Rückgabe von core.async-Kanälen wäre schön
    • Das Nachladen ist etwas langsam, wenn es in die Komponente von Stuart Sierra eingefügt wird (ich denke, Sie sollten den Interloador zum Nachladen verwenden).
    • Keine Testeinrichtung für asynchrone Abfangjäger
    • erfordert Buy-In (?)

Aleph

Pro (3):

  • Performant
  • Gegendruck
  • Websocket / SSE-Unterstützung bei der Rückgabe eines vielfältigen Streams

Nachteile (1):

  • Niedriges Level, mach es dir selbst (dh es gibt dir nur eine Möglichkeit, deine Handler dazu zu bringen, etwas zu tun. Kein Router, kein Nichts). Nicht wirklich ein Nachteil, sei dir dessen einfach bewusst.

Yada

Pro (3):

  • gebaut auf Aleph
  • Inhaltsverhandlung
  • Prahlerei Integration
  • bidi ist ganz ok (obwohl ich die Syntax von Sockel-Routern besser mag)

Nachteile (1):

  • Dokumentation (obwohl nicht so schlecht wie Nginx-Clojure, schnell verbessert).

HttpKit

Pro (2):

  • Geschrieben in Clojure! (und Java ...)
  • Die Leistung sieht gut aus (siehe Beitrag über 600K-gleichzeitige Verbindungen).

Nachteile (2):

  • Keine CORS-Unterstützung
  • Bugs? Auch nicht viele aktuelle Commits

Nginx-Clojure

Hinweis: Ich habe nicht damit gespielt, hauptsächlich wegen der fehlenden Dokumentation. Es sieht jedoch interessant und sehr performant aus.

Vorteile (2):

  • Nginx (Performant, SSL auslagern, Arbeiter neu starten ...)
  • Könnte dieses Modell Aktualisierungen ohne Ausfallzeiten ermöglichen? Das wäre so toll!

Nachteile (1):

  • Dokumentation (Verbesserung). Außerdem möchte ich nicht in Zeichenfolgen programmieren, die in eine Nginx-Konfigurationsdatei eingebettet sind, wenn dies der einzige Weg ist, dies zu tun.
  • Wahrscheinlich kompliziert die erste Bereitstellung etwas? (?)

Immutant

Hinweis: Ich habe nicht damit gespielt.

Vorteile:

  • integriert (Caching, Messaging, Scheduling, Wildfly-Bereitstellung)

Nachteile:

  • kein http-Client

Catacumba

Hinweis: Ich habe nicht damit gespielt, obwohl die Dokumentation ausgezeichnet aussieht. Ich werde es wahrscheinlich als nächstes versuchen. Es gibt Beispiel-Chat-Projekte, die interessant aussehen. Ihre starke Verwendung von Protokollen hat mich zunächst als unerfahrenen Clojure-Entwickler abgeschreckt.

Vorteile (6):

  • Dokumentation! Wie bei allen funcool-Projekten ist das Dokument sehr angenehm zu lesen.
  • sockelartige Routing-Syntax
  • sollte performant sein (oben auf Ratpack)
  • Gegendruck
  • websockets, sse, cors, sicherheit, ssl ...
  • einzigartige Eigenschaften zu graben: Post

Nachteile (2):

  • Ich bin mir nicht ganz sicher, wie angenehm die ct / route-Syntax ist und wie ich die Ring-Spezifikation fallen lasse (angeblich für die asynchrone Geschichte, aber ich dachte, die Podest-Leute haben das behoben).
  • Ich bin mir nicht sicher, wie man Prahlerei usw. integrieren würde.
  • Als ich es versuchte, konnte ich es nicht sofort zum Laufen bringen

Hinweis : Ein Benchmark für Clojure-Webserver ist verfügbar, wenn nur die Rohleistung zählt.


Toller Vergleich.
Ich bin

1
@matanster Ich sehe Apache als Standard-Go-To-Server für viele Organisationen. Einfach, funktioniert für viele. Aber es ist auch älter als Nginx und verwendet ein anderes internes Modell. Compojure ist synchron (das kann sich ändern), während Yada asynchron ist. Ein weiterer Vorteil von Yada, den ich nicht erwähnt habe, ist, dass alles Daten sind, so dass es im Vergleich zu Makros wie in Compojure viel einfacher ist, zu komponieren / transformieren / inspizieren / generieren.
nha

14

In diesen Tagen Pedestal ist ein Framework einen Blick wert. Es handelt sich um ein serverseitiges Framework, das auf Ring aufbaut , aber auch die eingehende Anforderung vom ursprünglichen Thread befreit, indem diese bestimmte Anforderung angehalten und fortgesetzt werden kann (andernfalls blockiert eine langsame Anforderung tatsächlich diesen Serverthread). Vielleicht wie eine JavaBean.

Andere coole Frameworks sind hoplon.io und David Nolens Om (basierend auf React)


11

Webjure , ein Webprogrammierframework für Clojure.

Features: Dispatch Servlet ruft Clojure-Funktionen auf. Dynamische HTML-Generierung. SQL-Abfrageschnittstelle (über JDBC).

Diese Antwort ist als Platzhalter für Webjure-Informationen gedacht.


3
Ich bin mir auch nicht sicher, ob dies ein gutes Beispiel ist. Während die Codebasis flach (gut) erscheint, ist in Java genug geschrieben, dass sie die Marke zu verfehlen scheint. Ich hätte ein reines Clojure-Framework erwartet.
Richard

8

Mit Compojure habe ich eine winzige Blogging-Anwendung erstellt. Es basiert auf Sinatra, einem minimalen, leichten Webframework für Ruby. Ich habe meistens nur das Routing verwendet, das genau wie das von Sinatra ist. Es sieht aus wie:

(GET "/post/:id/:slug"
  (some-function-that-returns-html :id :slug))

Es gibt keine ORM- oder Vorlagenbibliothek, aber es gibt Funktionen, die Vektoren in HTML umwandeln.



3

Haftungsausschluss: Ich bin der Autor.

Ich habe eine Leiningen-Vorlage zusammengestellt, die Luminusweb- und Kastanien-Vorlagen kombiniert. So erhalten Sie etwas, mit dem Sie Clojure-Code und Clojurescript-Code für Front- und Backend erstellen können.
Darüber hinaus bietet es Benutzerverwaltung sowie eine einfache CRUD-Generierung und einige weitere Kleinigkeiten: https://github.com/sveri/closp


3

Ich werde meine zwei Cent für Duct einwerfen , ebenfalls von @weavejester , dem Betreuer von Compojure und Ring.

Im Kern vereint es Component und Ring Router unter einem Dach. Gründe, warum ich Duct benutze:

  • Hervorragende philosophische Grundlage: Es ermutigt Sie, Ihre App als eine Reihe kleiner Komponenten zu erstellen, und es schafft eine gute Balance zwischen wenigen Meinungen und vernünftigen Standardeinstellungen.
  • Stabiler Weg: Ich spreche für mich selbst, aber im Laufe der Jahre hatte ich das Gefühl, dass die Clojure-Community ein weniger glaubwürdiges Webframework nach dem anderen präsentiert hat. Ein Paar fühlte sich einfach zu experimentell (meine Erfahrung mit Om und dem clientseitigen Podest), um "Dinge zu erledigen" (nicht, dass sie sich später nicht als überlegen erweisen würden). Auf der anderen Seite habe ich das Gefühl, dass @weavejester Duct die gleiche Stabilität und den gleichen gemessenen Fortschritt gebracht hat wie Compojure und Ring, die in der Community hervorragend geboren wurden.
  • Es ist Super leicht und aus dem Weg meiner Komponenten.

Hauptmerkmale:

  • Organisiert Routen nach "Endpunkten", kleinen Komponenten, die Sie sich als Mini-Webserver vorstellen können (oder nach kleinen Querschnitten Ihrer HTTP-Routen).
  • Out-of-the-Box-Unterstützung für den neu geladenen Workflow .
  • Perfekte Integration mit Ring und Compojure.
  • Entwicklungs- und Produktionskonfigurationen (etwas, das ich an anderer Stelle auffällig vermisst habe).
  • Gute Dokumentation mit Beispielen.

Hinweis: Es versteht sich von selbst, aber zum Nutzen der Webentwicklung benötigen Neulinge wie die meisten Clojurey-Dinge, die Duct benötigt, ein solides Verständnis der Sprache Clojure. Ich empfehle auch, zuerst über die Komponente zu lesen.

Ich persönlich verwende Duct seit über einem Jahr in mehreren Produktionsanwendungen und bin äußerst zufrieden damit.



2

Ein weiterer interessanter Webserver ist das HTTP-Kit . Es hat eine gute Leistung, ist ringkonform und unterstützt auch WebSockets. Es wird hauptsächlich in Clojure hergestellt und es fehlen einige der seltsamen Dinge in Jetty / Tomcat.

Es ist leicht zu basteln.


2

Reframe und om.next wahrscheinlich das, wonach Sie suchen.


1

Arachne ist ein Newcomer-Webframework. Zitieren der Beschreibung der Site:

Arachne ist ein vollständiges, hochmodulares Webentwicklungsframework für Clojure. Es betont Leichtigkeit, Einfachheit und ein solides, skalierbares Design.

Es gibt eine Kickstarter-Kampagne, die behauptet, ein "Erste Schritte" -Erlebnis ähnlich wie bei Rails zu bieten. Es wird von einem Cognitect entwickelt.

Hier ist eine gute Diskussion darüber mit dem Autor von Luminus (Yogthos).


1

Ich benutze Liberator seit einiger Zeit erfolgreich in der Produktion. Es ist ein großartiger Rahmen, wenn Sie nur das Nötigste wollen, z. B. wenn Sie einen RESTful-Webdienst oder ähnliches erstellen. Es ist im Wesentlichen ein Wrapper für Ring und Compojure und bietet ein Entscheidungsdiagramm bei der Validierung eingehender Anforderungen. Es ist auch extrem schnell im Vergleich zu anderen sperrigeren Web-Frameworks. Wenn Sie irgendwo schnell und langsam anfangen möchten, ist Liberator eine gute Wahl.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.