216 votes

Comment réaliser une application web en Clojure ?

Je suppose que c'est une question étrange pour l'immense majorité des programmeurs qui travaillent quotidiennement avec Java. Ce n'est pas mon cas. Je connais Java-le-langage, parce que j'ai travaillé sur des projets Java, mais pas Java-le-monde. Je n'ai jamais créé une application web à partir de rien en Java. Si je dois le faire avec Python, Ruby, je sais où aller (Django ou Rails), mais si je veux faire une application web en Clojure, non pas parce que je suis obligé de vivre dans un monde Java, mais parce que j'aime ce langage et que je veux essayer, quelles bibliothèques et quels frameworks dois-je utiliser ?

1 votes

Je me demandais si vous souhaitiez utiliser les API natives de Java ou celles de Clojure ?

0 votes

Ande : Je ne suis vraiment pas sûr, car je connais très peu le monde Java à cet égard (mais j'utilise Java, le langage, depuis un certain temps déjà au travail).

0 votes

Je pense que ce serait bien si cette question se terminait par une liste de frameworks web Clojure, avec une réponse chacun, et que chacun puisse voter pour son préféré. Je pense que la réponse de Meredydd est définitivement celle de Compojure. Je vais en ajouter une pour Webjure et ce serait bien d'avoir une comparaison.

179voto

Ross Goddard Points 2565

Compojure n'est plus un framework complet pour le développement d'applications web. Depuis la version 0.4, Compojure a été scindé en plusieurs projets.

Bague fournit la base en faisant abstraction du processus de demande et de réponse HTTP. Ring analysera la demande entrante et générera une carte contenant toutes les parties de la demande telles que l'uri, le nom du serveur et la méthode de demande. L'application va ensuite traiter la demande et, en fonction de celle-ci, générer une réponse. Une réponse est représentée par une carte contenant les clés suivantes : status, headers, et body. Ainsi, une application simple ressemblerait à ceci

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

Une autre partie de Ring est le concept d'intergiciel. Il s'agit du code qui se situe entre le gestionnaire et la demande entrante et/ou la réponse sortante. Parmi les intergiciels intégrés, citons les sessions et le suivi de pile. L'intergiciel de session ajoute une clé :session à la carte de requête, qui contient toutes les informations de session de l'utilisateur effectuant la requête. Si la clé :session est présente dans la carte de réponse, elle sera stockée pour la prochaine demande effectuée par l'utilisateur actuel. L'intergiciel de suivi de la pile capture toutes les exceptions qui se produisent pendant le traitement de la demande et génère un suivi de la pile qui est renvoyé en réponse si des exceptions se produisent.

Travailler directement avec Ring peut être fastidieux, alors Compojure est construit au-dessus de Ring en faisant abstraction des détails. L'application peut maintenant être exprimée en termes de routage, ce qui donne quelque chose comme ceci :

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

Compojure travaille toujours avec les cartes de demande/réponse afin que vous puissiez toujours y accéder si nécessaire :

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

Dans ce cas, la partie {uri :uri} accède à la clé :uri dans la carte des requêtes et définit uri à cette valeur.

Le dernier composant est Hiccup ce qui facilite la génération du html. Les différentes balises html sont représentées sous forme de vecteurs, le premier élément représentant le nom de la balise et le reste étant le corps de la balise. "<h2>A header</h2>" devient [:h2 "A Header"] . Les attributs d'une balise se trouvent dans une carte facultative. "<a href='http://stackoverflow.com/login'>Log In Page</a>" devient [:a {:href "/login"} "Log In Page"] . Voici un petit exemple utilisant un modèle pour générer le 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)))

Voici un lien vers un brouillon de documentation en cours d'écriture par l'auteur de compojure qui pourrait vous être utile : Compojure Doc

104voto

Compojure est de loin le meilleur framework web Clojure que j'ai rencontré jusqu'à présent : http://github.com/weavejester/compojure/tree/master

Il est petit mais puissant, et possède une syntaxe élégante. (Il utilise Jetty sous le capot, mais il vous cache l'API Servlet à moins que vous ne le vouliez, ce qui ne sera pas souvent le cas). Allez voir le README à cette URL, puis téléchargez un instantané et commencez à jouer.

48voto

elithrar Points 2931

Il y a aussi "Noir" ( http://www.webnoir.org/ ), qui est un nouveau framework web Clojure (si nouveau que la documentation n'existe pas encore). Venant de Django/Rails, j'apprécie la syntaxe simple et directe et c'est assez léger.

0 votes

Webnoir est en fait très utile ! Il est très facile à prendre en main - on peut le développer un peu en fait comme on semble développer du php - il suffit de démarrer un serveur (cette fois avec leiningen), d'éditer vos fichiers et de recharger votre navigateur pour voir ce que vous avez obtenu.

0 votes

Puisque @elithrar a répondu, Noir a maintenant les docs disponibles : webnoir.org/docs

18 votes

Pour mémoire, il semble que Noir ait été déprécié et ne soit plus maintenu.....

25voto

Michael Easter Points 7482

Considérez le Cadre web Luminus . Je n'ai aucune affiliation mais j'ai entendu de bonnes choses de la part d'amis que je respecte.

21voto

nha Points 898

Ma bibliothèque web préférée est maintenant yada .

Si vous débutez, le serveur d'introduction est le suivant Compojure . Je le vois comme le apache de serveurs web dans le monde Clojure (dans ce cas, yada/aleph serait nginx). Vous pouvez utiliser Luminus comme modèle. Il en existe des variantes, comme compojure-api .

J'ai essayé de Pedestal et j'en étais globalement satisfait. Je ne prétends pas le maîtriser, mais il a une syntaxe agréable, semble très cohérent et semble avoir de grandes performances. Il est également soutenu par Cognitect (la société Clojure/Datomic où travaille Rich Hickey).

J'ai trouvé Aleph pour présenter une abstraction intéressante, et la rétropression intégrée semble intéressante. Je n'ai pas encore joué avec, mais c'est définitivement sur ma liste.

Après avoir joué un peu avec différents serveurs web, voici ma liste rapide des avantages et inconvénients :

Réponse courte : consultez le site Luminus pour démarrer rapidement, puis passer à autre chose en fonction de l'évolution de vos besoins (Yada peut-être).

Compojure

  • Pros (1) :

    • facile, beaucoup de modèles/exemples (ex. Luminous)
  • Cons (2) :

    • Pas performant (un thread par requête), attendez-vous à des performances légèrement supérieures à celles de rails.
    • Pas simple, le modèle d'intergiciel présente des inconvénients

Piédestal

  • Pros (3) :

    • modèle d'intercepteur, syntaxe agréable pour ajouter des intercepteurs à un sous-ensemble de routes
    • routeur performant
    • supporte les formulaires json/transit/multipart de manière transparente, sans rien demander. Très cool !
  • Cons (4) :

    • pas de support pour les websockets (encore), le retour des canaux core.async serait bienvenu
    • un peu lent à recharger si on le met dans un composant de Stuart Sierra (je pense que vous êtes censé utiliser l'intercepteur de rechargement)
    • pas de possibilité de test pour les intercepteurs asynchrones
    • nécessite une adhésion ( ?)

Aleph

Pro (3) :

  • Performant
  • contre-pression
  • Support de Websocket/SSE lors du retour d'un flux de manifold

Cons (1) :

  • Bas niveau, style do it yourself (c'est-à-dire qu'il vous donne juste un moyen de faire faire quelque chose à vos gestionnaires. Pas de routeur, pas de rien). Ce n'est pas vraiment un inconvénient, il suffit d'en être conscient.

Yada

Pro (3) :

  • construit sur Aleph
  • négociation du contenu
  • intégration de swagger
  • bidi est tout à fait correct (bien que je préfère la syntaxe des routeurs sur socle)

Cons (1) :

  • documentation (bien que pas aussi mauvaise que celle de nginx-clojure, s'améliorant rapidement).

HttpKit

Pro (2) :

  • Écrit en Clojure ! (et en Java...)
  • les performances semblent bonnes (voir le post sur les 600K connexions simultanées)

Cons (2) :

  • Pas de support CORS
  • Des bogues ? De plus, il n'y a pas beaucoup de commits récents

Nginx-Clojure

Note : Je n'ai pas joué avec, principalement à cause du manque de documentation. Il semble intéressant cependant, et très performant.

Pros (2) :

  • Nginx (performant, offload ssl, restart workers...)
  • Ce modèle pourrait-il permettre des mises à jour sans temps d'arrêt ? Ce serait vraiment génial !

Cons (1) :

  • Documentation (en cours d'amélioration). De plus, je ne veux pas programmer dans des chaînes intégrées dans un fichier de configuration nginx si c'est la seule façon de le faire.
  • Cela complique probablement un peu le premier déploiement ( ?).

Immutant

Note : Je n'ai pas joué avec.

Pros :

  • intégré (mise en cache, messagerie, programmation, déploiement wildfly)

Cons :

  • pas de client http

Catacumba

Note : Je n'ai pas joué avec, bien que la documentation semble excellente. Je vais probablement l'essayer ensuite. Il y a des exemples de projets de chat qui ont l'air intéressants, leur utilisation intensive de protocoles m'a rebuté au début en tant que novice en Clojure.

Pros (6) :

  • la documentation ! Comme tous les projets funcool, la doc est très agréable à lire.
  • syntaxe de routage de type piédestal
  • doit être performant (en plus de Ratpack)
  • contre-pression
  • websockets, sse, cors, sécurité, ssl...
  • caractéristiques uniques à creuser : postal

Cons (2) :

  • Je ne suis pas tout à fait sûr que la syntaxe ct/routes soit agréable, ni de l'abandon de la spécification Ring (soi-disant pour l'histoire de l'asynchronisme, mais je pensais que les gars du piédestal avaient réglé ce problème).
  • Je ne suis pas sûr de la manière dont on pourrait intégrer le swagger, etc.
  • quand je l'ai essayé, je n'ai pas réussi à le faire fonctionner tout de suite

Nota : a benchmark des serveurs web Clojure est disponible, si les performances brutes sont tout ce qui compte.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X