Programmazione Clojure: framework e altri strumenti
Sebbene tutte queste librerie mirino a semplificare le attività di programmazione Clojure, potrebbero confondere un principiante. A volte, è difficile capire come metterli tutti insieme e trovare una soluzione ottimale per un compito specifico. Quindi, ora voglio mostrarti i miei strumenti preferiti per la programmazione in Clojure.
- lavorare con server web ed endpoint
- interazione con server web e database
- routing su server
- utilizzo di GraphQL nella programmazione Clojure
- supporto dell’architettura modulare
Iniziamo il viaggio nel mondo della programmazione Clojure!
Nota: quando ci si sposta da Java e altri linguaggi simili, si dovrebbe sapere che non ci sono framework tradizionali in Clojure. Tutto è basato sulle librerie e sulle loro collezioni. Questo rende il linguaggio più flessibile e multi-purpose.
L’ecosistema Clojure include librerie di diversa complessità. Alcuni di questi sono solo un insieme di funzioni aggiuntive (ad esempio, una libreria per lavorare con il tempo). Nel frattempo, le librerie di sistema forniscono una piattaforma per la creazione dell’intero framework. Tali librerie consentono al programmatore di presentare un’applicazione come un insieme di componenti, descrivere le connessioni tra di loro e così via. La libreria stessa garantisce la creazione di grafici di dipendenza. Ad esempio, può convertire i componenti in cose più comprensibili, come le funzioni.
Scopo: lavoro conveniente con il server Web e gli endpoint
Codice: https://github.com/ring-clojure/ring
L’astrazione del server HTTP è un elemento chiave dello stack web Clojure. Consente un lavoro semplice con server Web ed endpoint, che è essenziale per lo sviluppo di app di successo. Creato in analogia con WSGI (Python) e Rack (Ruby), Ring astrae le informazioni di HTTP in un’API chiara e unificata. Di conseguenza, lo sviluppatore web può costruire sistemi modulari costituiti da componenti e condividere questi componenti tra vari server e applicazioni.
- Come funziona Ring?
- Motivi per usare Ring
- Http-kit
- Come funziona Http-kit?
- Motivi per l’utilizzo di Http-kit
- Compojure e Bidi
- Come funzionano Compojure e Bidi?
- Qual è la differenza tra loro?
- Lacinia
- Come agisce Lacinia?
- Motivi per usare Lacinia
- HoneySQL e HugSQL
- Come funzionano HoneySQL e HugSQL?
- Qual è la differenza tra loro?
- HugSQL pro
- HugSQL cons
- HoneySQL pro
- HoneySQL cons
- danielsz / system
- Come funziona danielsz/system?
- Motivi per l’utilizzo di danielsz/system
Come funziona Ring?
Ottiene le richieste HTTP e restituisce le risposte HTTP. Quindi, Ring non è un cosiddetto framework di applicazioni web.
Motivi per usare Ring
Come libreria web dominante nella programmazione Clojure, Ring è una buona scelta per i principianti. Prima di tutto, la sua funzione principale è quella di fornire una comoda interfaccia per una vasta gamma di server web. Da questo punto di vista, la tecnologia è estremamente utile e funziona perfettamente.
Un’altra funzione Ring sta fornendo un set di moduli (‘middleware’). Quindi, ti consente di utilizzare diverse librerie pre-scritte, compatibili tra loro.
La maggior parte dei programmatori Clojure sceglie Ring per gli endpoint a causa della sua capacità di utilizzare middlewares. Ad esempio, questi moduli consentono di trasformare i parametri richiesti da un URL alla mappa del codice Clojure. Uno sviluppatore web può facilmente scrivere nuovo middleware e integrarlo nell’ecosistema. Ad esempio, utilizzando la libreria cemerick/friend, è possibile gestire completamente il processo di autorizzazione, applicare diverse strategie (a partire dal login e dalla password, finendo con OAuth), ecc. Ring middleware aiuta a descrivere comodamente e avviare il processo. Chiude tutti gli endpoint vietati agli utenti non autorizzati.
L’esperienza nell’uso di Ring è importante per lavorare con altre tecnologie Clojure. È la prima cosa che puoi usare per far muovere un’app.
Http-kit
Scopo: avvio del server
Codice: https://github.com/http-kit/http-kit
La libreria server/client HTTP altamente efficace basata su eventi include WebSocket e supporto asincrono.
Come funziona Http-kit?
È una libreria per organizzare una corretta interazione con il server web. Http-kit è adatto per applicazioni asincrone o sincrone altamente simultanee. Per quanto riguarda WebSocket e HTTP long polling / streaming, è meglio presentare un’API unificata.
Motivi per l’utilizzo di Http-kit
Soluzione flessibile
Http-kit offre l’opportunità di lavorare sia con sistemi di sincronizzazione che asincroni. La prima opzione è semplice, mentre la seconda funziona più velocemente. Quindi, puoi fare una scelta in base al tuo scopo specifico. Inoltre, è possibile utilizzare la libreria con Anello. Funziona quasi come l’adattatore Jetty.
Utilizzo conveniente
La libreria garantisce il supporto per i WebSocket e la perfetta gestione delle richieste HTTP di lunga data. Così, la creazione di un app in tempo reale diventa più facile. Inoltre, è un progetto open source. La libreria è disponibile su GitHub sotto la licenza Apache Versione 2.0.
Risultati eccellenti
HTTP-kit mostra prestazioni elevate e funziona velocemente nonostante i grandi carichi. Allo stesso tempo, ogni connessione richiede solo pochi kB di memoria. Un client / server scritto da zero è disponibile come un singolo JAR ~90kB con 0 dipendenze e ~ 3k righe di codice chiaro.
Molti sviluppatori di software considerano HTTP-kit come uno strumento di base per la programmazione Clojure.
Compojure e Bidi
Scopo: routing sul server
Codice: https://github.com/juxt/bidi, https://github.com/weavejester/compojure
Sia Compojure che Bidi sono tecnologie per il routing nelle app web. La prima libreria è molto popolare tra la comunità, mentre la seconda è conosciuta come una comoda soluzione per scrivere in ClojureScript.
Come funzionano Compojure e Bidi?
Queste piccole librerie assicurano il routing su un server web. Di conseguenza, uno sviluppatore di software può scrivere applicazioni composte da più parti separate.
Qual è la differenza tra loro?
Le 2 librerie svolgono la stessa funzione. Ma, a differenza di Compojure, Bidi:
- supporta sia clj e cljs
- è isomorfo ed estensibile
La differenza principale è che in percorsi Bidi sono strutture dati. Non ci sono macro qui. Quindi, la libreria offre un comodo approccio bidirezionale e altri vantaggi. Alcuni sviluppatori web preferiscono Bidi perché mostra ogni percorso di un particolare gestore. Inoltre, c’è l’opportunità di leggere i percorsi da un file di configurazione, generarli e trasformarli in funzioni e introspezione. Funzionano indipendentemente dalle richieste gestite. Quindi, lo sviluppatore può corrispondere a cose che non sono necessariamente gestori (ad esempio, parole chiave).
Lacinia
Scopo: implementazione di GraphQL nella programmazione Clojure
Codice: https://github.com/walmartlabs/lacinia
Questa popolare libreria Clojure è utile per coloro, che vogliono implementare GraphQL mentre lavorano con le API web.
Come agisce Lacinia?
Originariamente, GraphQL è scritto in JavaScript. Lacinia è un riferimento ufficiale a questa implementazione. È scritto in analogia con la specifica iniziale. Può essere chiamato un motore di esecuzione di query GraphQL backend-agnostico. Quindi, la libreria fornisce il contatto tra i tuoi dati e il client GraphQL.
Motivi per usare Lacinia
Usando GraphQL, puoi facilmente ottenere un’API Web più ricca e complicata. Lacinia semplifica lo sviluppo delle API perché supporta frammenti di query in linea/denominati, introspezione dello schema GraphQL, sottoscrizioni, interfacce, unioni, enumerazioni, input e scalari personalizzati.
Scritto in un linguaggio di schema basato su EDN, la libreria funziona perfettamente con le query GraphQL. È costruito su Antlr4. Lacinia aiuta a un’esecuzione di query asincrona efficiente e ricca. È possibile collegarlo a qualsiasi pipeline HTTP Clojure e utilizzare la libreria companion lacinia-pedestal per il supporto HTTP.
HoneySQL e HugSQL
Scopo: interazione con database di successo
Codice: https://github.com/jkk/honeysql, https://github.com/layerware/hugsql
Molti programmatori web si sentono più a proprio agio a lavorare con le tecnologie SQL, come Oracle, MS SQL, MySQL, PostgreSQL, SQLite, ecc. HoneySQL e HugSQL sono costruttori di query che forniscono un accesso stabile ai database SQL nelle applicazioni Clojure.
Come funzionano HoneySQL e HugSQL?
Entrambe le librerie assicurano l’integrazione di SQL nella programmazione Clojure. Quindi, sarai in grado di scrivere comandi di database SQL anche nelle app web Clojure.
Qual è la differenza tra loro?
Utilizzando HugSQL, si inizia con la scrittura di file SQL separati e inserendoli nell’applicazione. Il costruttore di query è ispirato da un’altra libreria popolare, YeSQL. Non solo analizza i file SQL in funzioni Clojure, ma è anche adatto per più casi d’uso rispetto a YeSQL. HugSQL viene mantenuto attivamente. Ha adattatori basati su protocollo che supportano più librerie di database.
HugSQL ha diversi vantaggi grazie a 2 caratteristiche fondamentali:
- le query sono scritte direttamente, una query per ogni funzione richiesta;
- le query sono scritte in SQL.
HugSQL pro
HugSQL fornisce la separazione della sintassi Clojure e della semantica SQL (COSA e COME).
- descriviamo COSA fare in Clojure
(get-utente-email-da-username “Alexandr Petrov”) ;->
- descriviamo COME farlo in SQL
— :nome get-utente-email-da-nome utente 😕 : *
selezionare le _email utente.email da user_emails dove user_emails.user_id=: id
Di conseguenza, possiamo cambiare la logica di ottenere i dati direttamente in SQL, senza riscrivere il codice Clojure. È utile quando uno schema di database viene modificato e la vecchia query non restituisce la struttura necessaria.
Inoltre, SQL stesso è uno strumento molto più potente per lavorare con un DBMS specifico. Permette di scrivere query complesse di grandi dimensioni con “join”, aggregazioni e funzioni di finestra, che possono essere estremamente difficili in Clojure.
Inoltre, SQL consente di utilizzare i vantaggi di un DBMS specifico (ad esempio, Postgres). È importante se sei sicuro che il database non verrà modificato.
HugSQL cons
- È difficile cambiare DBMS nel mezzo del progetto. Sarà necessario controllare molte richieste e testare attentamente il supporto della sintassi e l’output specifico.
- È possibile passare i parametri alle query SQL. Ma, in alcuni casi, le parti delle query devono dipendere da determinate condizioni. Sebbene i frammenti di HugSQL consentano di completare questa attività, più spesso è necessario farlo usando Clojure.
HoneySQL non fornisce tale separazione del codice SQL e Clojure. Vedrai le query come una mappa.
HoneySQL pro
- È indipendente da un’implementazione specifica del DBMS perché di solito evita query SQL dirette. Invece di loro, utilizza DSL specifico.
- Consente di mantenere la propria DSL basata su funzioni/macro Clojure. È inoltre possibile creare un generatore di query con il salvataggio delle richieste intermedie sul lato Clojure. Ad esempio, se è necessario definire un utente per ID o altra logica complessa, è possibile salvare parte della struttura HoneySQL. Mostrerà che abbiamo bisogno esattamente dell’utente, non delle merci o di altri dati. Questo “frammento” può essere sostituito nelle query necessarie. Di conseguenza, otterrai un codice più breve.
HoneySQL cons
- Può essere difficile utilizzare i vantaggi di un DBMS specifico, nonché scrivere query complesse (ad esempio, con funzioni Window)
- Il programmatore Clojure deve separare il codice per il recupero dei dati e il codice per l’elaborazione di questi dati. La separazione porta a ulteriori lavori sul refactoring.
danielsz / system
Scopo: supporto di architettura modulare
Codice: https://github.com/danielsz/system
Tecnologia utile per lo sviluppo di applicazioni altamente modulari in Clojure. Il framework supporta un’interazione efficace tra i moduli e ha una buona compatibilità con altre parti del variegato ecosistema Clojure.
Come funziona danielsz/system?
La libreria consente a un programmatore web di utilizzare un approccio basato su componenti. Quindi, è possibile creare un’applicazione utilizzando moduli/componenti e le connessioni tra di loro. Ogni componente è un oggetto speciale. Ha il suo ciclo di vita. Il programmatore descrive come inizia, cosa deve iniziare e come si ferma.
Ad esempio, la nostra applicazione è costituita da un server web e un database. Non ha senso avviare il server Web prima che il database sia attivato. Descriviamo il componente del database, descriviamo il componente server e la dipendenza del server dal database. Quando si avvia il progetto, indichiamo che è necessario avviare il server Web. La libreria tenterà automaticamente di attivare il database. Quindi, se possibile, avvierà il server e trasferirà il componente del database attivato finito al componente del server Web. Quindi, se necessario, il sistema verrà arrestato.
Motivi per l’utilizzo di danielsz/system
A differenza della descrizione dell’intera applicazione con una serie di normali funzioni Clojure, la descrizione del progetto come componenti semplifica la sostituzione di un componente con un altro. Ad esempio, durante il test di un’applicazione, la sostituzione di un database con un altro o la disattivazione completa, la sostituzione con i dati correnti.
Nel caso delle funzioni, cambierai le vecchie funzioni con quelle nuove. Avranno lo stesso nome, che spesso causa bug. danielsz / system è un insieme di soluzioni già pronte (per un server web, un database e molto altro), organizzate come un insieme di componenti.
Spero, ora capisci meglio come usare Clojure e quali soluzioni tecnologiche dovrebbero essere implementate nel tuo progetto. I miei ulteriori articoli includeranno i vantaggi di questo linguaggio potente e bello, così come alcuni suggerimenti sullo sviluppo di applicazioni web, servizi e API. Quindi, iscriviti al blog FreshCode, se vuoi saperne di più sul mondo della programmazione Clojure.