tutorial - ¿Cómo se hace una aplicación web en Clojure?




clojurescript (11)

Supongo que esta es una pregunta extraña para la gran mayoría de los programadores que trabajan diariamente con Java. Yo no. Sé Java-the-language, porque trabajé en proyectos Java, pero no en Java-the-world. Nunca hice una aplicación web desde cero en Java. Si tengo que hacerlo con Python, Ruby, sé dónde ir (Django o Rails), pero si quiero hacer una aplicación web en Clojure, no porque me obliguen a vivir en un mundo Java, sino porque Me gusta el idioma y quiero probarlo. ¿Qué bibliotecas y marcos debo usar?


Compojure es lo que usé para construir una pequeña aplicación de blogs. Está modelado en Sinatra, que es un marco web mínimo y liviano para Ruby. Principalmente utilicé la ruta, que es como la de Sinatra. Parece que:

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

No hay ORM o biblioteca de plantillas, pero tiene funciones que convierten los vectores en HTML.


Compojure ya no es un marco completo para el desarrollo de aplicaciones web. Desde la versión 0.4, el juego se ha dividido en varios proyectos.

Ring proporciona la base al abstraer el proceso de solicitud y respuesta HTTP. Ring analizará la solicitud entrante y generará un mapa que contiene todas las partes de la solicitud, como uri, nombre de servidor y método de solicitud. La aplicación manejará la solicitud y, según la solicitud, generará una respuesta. Una respuesta se representa como un mapa que contiene las siguientes claves: estado, encabezados y cuerpo. Así que una aplicación simple se vería así:

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

Otra parte de Ring es el concepto de middleware. Este es un código que se encuentra entre el controlador y la solicitud entrante y / o la respuesta saliente. Algunos integrados en middleware incluyen sesiones y stacktrace. El middleware de sesión agregará una clave de sesión al mapa de solicitud que contiene toda la información de sesión para el usuario que realiza la solicitud. Si la clave de sesión: está presente en el mapa de respuesta, se almacenará para la siguiente solicitud realizada por el usuario actual. Mientras que el middleware del seguimiento de la pila capturará cualquier excepción que ocurra al procesar la solicitud y generará un seguimiento de la pila que se envía de vuelta como respuesta si se producen excepciones.

Trabajar directamente con Ring puede ser tedioso, por lo que Compojure está construido sobre Ring y abstrae los detalles. La aplicación ahora se puede expresar en términos de enrutamiento para que pueda tener algo como esto:

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

Compojure sigue trabajando con los mapas de solicitud / respuesta, por lo que siempre puede acceder a ellos si es necesario:

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

En este caso, la parte {uri: uri} accede a la clave: uri en el mapa de solicitud y establece uri en ese valor.

El último componente es Hiccup que facilita la generación del html. Las diversas etiquetas html se representan como vectores con el primer elemento que representa el nombre de la etiqueta y el resto es el cuerpo de la etiqueta. "<h2>A header</h2>" convierte en [:h2 "A Header"] . Los atributos de una etiqueta están en un mapa opcional. "<a href='/login'>Log In Page</a>" convierte en [:a {:href "/login"} "Log In Page"] . Aquí hay un pequeño ejemplo utilizando una plantilla para generar el 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)))

Aquí hay un enlace a un borrador de la documentación que actualmente está redactando el autor de compojure y que le puede resultar útil: Compojure Doc


Descargo de responsabilidad: yo soy el autor.

Armé una plantilla leiningen que combina luminusweb y plantillas de castaño. Así que obtienes algo con lo que puedes construir código de clojure y código de código de código para frontend y backend.
Además, proporciona administración de usuarios más un poco de generación de CRUD simple y otros más pequeños, como https://github.com/sveri/closp


Estos días Pedestal es un marco digno de una mirada. Es un marco del lado del servidor que se basa en el Ring , pero también libera la solicitud entrante del subproceso inicial al poder pausar y reanudar esa solicitud en particular (de lo contrario, una solicitud lenta en realidad bloquea ese hilo de servidor). Tal vez algo así como un JavaBean.

Otros marcos interesantes son hoplon.io y David Nolen's Om (basado en React)


Mi biblioteca web actual es ahora yada .

Si recién estás comenzando, el servidor introductorio es Compojure . Lo veo como el apache de los servidores web en el mundo de Clojure (en cuyo caso yada / aleph sería nginx). Podrías usar Luminus como plantilla. Hay variantes de él, como compojure-api .

Pedestal ou Pedestal y quedé satisfecho con todo el mundo. No pretendo dominarlo, pero tiene una sintaxis agradable, se siente muy cohesionado y parece que tiene un gran rendimiento. También está respaldado por Cognitect (la empresa Clojure / Datomic donde trabaja Rich Hickey).

Encontré a Aleph para presentar una abstracción interesante, y la contrapresión incorporada parece interesante. Todavía tengo que jugar con él, pero definitivamente está en mi lista.

Después de jugar un poco con varios servidores web, aquí está mi rápida lista de Pro / Cons:

Respuesta corta: eche un vistazo a Luminus para comenzar rápidamente, tal vez pase a otra cosa a medida que sus necesidades evolucionen (tal vez Yada).

Compojure

  • Pros (1):

    • Fácil, muchas plantillas / ejemplos (ej. Luminoso)
  • Contras (2):

    • Sin rendimiento (un hilo por solicitud), espera un rendimiento ligeramente mejor que los rieles
    • No es sencillo, el modelo de middleware tiene inconvenientes.

Pedestal

  • Pros (3):

    • Modelo de interceptor, sintaxis agradable para agregar interceptores a un subconjunto de rutas
    • enrutador performant
    • admite formularios json / transit / multipart de forma transparente y sin necesidad de pedir nada. Muy genial !
  • Contras (4):

    • no es compatible con websocket (todavía), devolver los canales core.async sería bueno
    • un poco lento para recargar si se lo pone en un componente de Stuart Sierra (creo que se supone que debes usar el interceptor de recarga)
    • no hay instalaciones de prueba para interceptores asíncronos
    • requiere buy-in (?)

Aleph

Pro (3):

  • Performante
  • contrapresion
  • Soporte de Websocket / SSE cuando se devuelve un flujo múltiple

Contras (1):

  • Nivel bajo, hágalo usted mismo al estilo (es decir, solo le da una manera de hacer que sus manejadores hagan algo. Sin enrutador, sin nada). No son realmente contras, solo tenlo en cuenta.

Yada

Pro (3):

  • construido en Aleph
  • negociación de contenido
  • integración arrogante
  • Bidi está bastante bien (aunque me gusta más la sintaxis del enrutador de pedestal)

Contras (1):

  • documentación (aunque no tan mala como nginx-clojure, mejorando rápidamente).

HttpKit

Pro (2):

  • Escrito en clojure! (y Java ...)
  • el rendimiento se ve bien (consulte la publicación de conexiones simultáneas de 600 K)

Contras (2):

  • No hay soporte CORS
  • Bichos Además, no hay muchos compromisos recientes.

Nginx-Clojure

Nota: no he jugado con él, principalmente debido a la falta de documentación. Aunque parece interesante, y muy performante.

Pros (2):

  • Nginx (ejecutante, ssl de descarga, reinicio de trabajadores ...)
  • ¿Podría este modelo permitir actualizaciones de tiempo de inactividad cero? ¡Eso sería tan increíble!

Contras (1):

  • Documentación (mejora). Además, no quiero programar en cadenas incrustadas en un archivo de configuración nginx si esa es la única manera de hacerlo.
  • Probablemente complica un poco el primer despliegue (?)

Inmutante

Nota: no he jugado con eso.

Pros:

  • integrado (almacenamiento en caché, mensajería, programación, despliegue de wildfly)

Contras :

  • no cliente http

Catacumba

Nota: no he jugado con él, aunque la documentación parece excelente. Probablemente voy a intentarlo a continuación. Hay ejemplos de proyectos de chat que parecen interesantes, su uso intensivo de protocolos me desanimó al principio como un desarrollador novato de Clojure.

Pros (6):

  • documentación! Como todos los proyectos de funcool, el documento es muy agradable de leer.
  • sintaxis de enrutamiento tipo pedestal
  • debe ser performant (encima de Ratpack)
  • contrapresion
  • websockets, sse, cors, seguridad, ssl ...
  • Características únicas para cavar: postal.

Contras (2):

  • No estoy completamente seguro de lo agradable que es la sintaxis de ct / route, y de deshacerse de la especificación de Ring (supuestamente para la historia asíncrona, pero pensé que los chicos del pedestal lo arreglaron)
  • No estoy seguro de cómo integrar Swagger, etc.
  • cuando lo probé, no pude hacerlo funcionar de inmediato

Nota : un punto de referencia de los servidores web de Clojure está disponible, si lo que importa es el rendimiento en bruto.


Otro servidor web interesante es Http-kit . Tiene un buen rendimiento y es compatible con el anillo, y también es compatible con WebSockets. Se hace principalmente en clojure, y carece de algunas de las cosas extrañas en Jetty / Tomcat.

Es fácil jugar con


Replantea y om.siguiente probablemente lo que estás buscando.


También está "Noir" ( http://www.webnoir.org/ ), que es un nuevo marco web de Clojure (por lo que los documentos nuevos aún no están disponibles). Proveniente de Django / Rails, comprendo la sintaxis simple y directa y es bastante magra.



Arachne es un nuevo framework web. Citando la descripción del sitio:

Arachne es un marco de desarrollo web completo y altamente modular para Clojure. Enfatiza la facilidad, la simplicidad y un diseño sólido y escalable.

Tiene una campaña de arranque que dice ofrecer una experiencia de "inicio" similar a Rails. Está desarrollado por un Cognitect.

Here hay una buena discusión al respecto con el autor de Luminus (yogthos).


@weavejester mis dos centavos por Duct , también de @weavejester , el mantenedor de Compojure y Ring.

En su núcleo, lleva el enrutador de Component y el anillo en un solo techo. Razones por las que uso Duct:

  • Excelente base filosófica: lo alienta a construir su aplicación como una serie de pequeños componentes, y logra un buen equilibrio entre tener pocas opiniones y proporcionar valores predeterminados sanos.
  • Ruta estable: hablo por mí mismo, pero a lo largo de los años he sentido que la comunidad de Clojure ha presentado un marco web poco creíble tras otro. Una pareja simplemente se sintió demasiado experimental (mi experiencia con Om y el pedestal del lado del cliente) para "hacer las cosas" (no es que no sean superiores en el camino). Por otro lado, siento que @weavejester ha traído a Duct la misma estabilidad y progreso medido que él hizo con Compojure y Ring, que han sido magníficamente desarrollados en la comunidad.
  • Es súper liviano y está fuera del alcance de mis componentes.

Características principales:

  • Organiza las rutas por "puntos finales", pequeños componentes que puedes imaginar como mini servidores web (o pequeñas secciones transversales de tus rutas HTTP).
  • Compatibilidad inmediata con el flujo de trabajo recargado .
  • Perfecta integración con anillo y compojure.
  • Configuraciones de desarrollo y producción (algo que encontré notoriamente perdido en otros lugares).
  • Buena documentación con ejemplos.

Nota: No hace falta decirlo, pero en beneficio de los recién llegados al desarrollo web, como la mayoría de las cosas de Clojurey, Duct requiere un conocimiento sólido de Clojure el idioma. También recomiendo leer sobre Componente primero.

En otra nota personal, he estado usando Duct en varias aplicaciones de producción durante más de un año y estoy extremadamente feliz con él.







clojure