Clojure webalkalmazások írása Ring segítségével

1. Bemutatkozás

A Ring egy könyvtár, amely webalkalmazásokat ír a Clojure-ban. Támogat mindent, ami a teljes funkcionalitású webalkalmazások megírásához szükséges, és virágzó ökoszisztémával rendelkezik, hogy még erőteljesebbé tegye.

Ebben az oktatóanyagban bemutatjuk a Ringet, és bemutatunk néhány dolgot, amit elérhetünk vele.

A Ring nem olyan keret, amelyet REST API-k létrehozására terveztek, mint annyi modern eszközkészlet. Alacsonyabb szintű keretrendszer a HTTP-kérelmek kezelésére általában, amelynek középpontjában a hagyományos webfejlesztés áll. Egyes könyvtárak azonban a tetejére építenek, hogy sok más kívánt alkalmazásstruktúrát támogassanak.

2. Függőségek

Mielőtt elkezdhetnénk a Ringet, hozzá kell adnunk a projektünkhöz. A minimális függőség, amire szükségünk van:

  • gyűrű / gyűrűmag
  • gyűrű / gyűrű-móló-adapter

Ezeket felvehetjük a leiningeni projektünkbe:

 : függőségek [[org.clojure / clojure "1.10.0"] [ring / ring-core "1.7.1"] [ring / ring-móló-adapter "1.7.1"]]

Ezután hozzáadhatjuk ezt egy minimális projekthez:

(ns ring.core (: Use ring.adapter.jetty)) (defn kezelő [kérés] {: status 200: fejlécek {"Content-Type" "text / plain"}: body "Hello World"}) (defn - main [& args] (run-mólókezelő {: port 3000}))

Itt meghatároztunk egy kezelő függvényt - amelyet hamarosan lefedünk - amely mindig a „Hello World” karakterláncot adja vissza. Ezenkívül hozzáadtuk a fő funkciónkat ennek a kezelőnek a használatához - figyelni fogja a 3000-es port kéréseit.

3. Alapfogalmak

Leiningen rendelkezik néhány alapvető fogalommal, amelyek köré minden épül: Kérések, Válaszok, Kezelők és Középprogramok.

3.1. Kérések

A kérések a bejövő HTTP-kérelmek reprezentációi. A Ring a kérést térképként ábrázolja, lehetővé téve a Clojure alkalmazásunk számára, hogy könnyen kölcsönhatásba léphessen az egyes mezőkkel. Ezen a térképen van egy szabványos kulcskészlet, beleértve, de nem kizárólag:

  • : uri - A teljes URI útvonal.
  • : query-string - A teljes lekérdezési karakterlánc.
  • : kérés-módszer - A kérési módszer, az egyik : get,: head,: post,: put,: delete vagy :opciók.
  • : fejlécek - A kérelemhez megadott összes HTTP fejléc térképe.
  • :test - Egy InputStream képviseli a megkereső szervet, ha jelen van.

A middleware ehhez a térképhez is adhat további kulcsokat szükség szerint.

3.2. Válaszok

Hasonlóképpen, a válaszok a kimenő HTTP válaszok reprezentációját jelentik. A Ring ezeket három szabványos kulccsal ellátott térképként is ábrázolja:

  • :állapot - A visszaküldendő állapotkód
  • :fejlécek - A visszaküldendő összes HTTP fejléc térképe
  • :test - Az opcionális törzs a visszaküldéshez

Mint azelőtt, A middleware megváltoztathatja ezt az előállító kezelőnk és a végeredmény között, amelyet elküldünk az ügyfélnek.

A Ring emellett néhány segítséget nyújt a válaszok felépítésének megkönnyítéséhez.

Ezek közül a legalapvetőbb a ring.util.reagálás / válasz függvény, amely egyszerű választ hoz létre állapotkóddal 200 OK:

ring.core => (ring.util.response / response "Hello") {: status 200,: headers {},: body "Hello"}

Van néhány más módszer, amely ezzel együtt jár a közös állapotkódok esetében - például, rossz kérés, nem található és átirányítás:

ring.core => (ring.util.response / bad-request "Hello") {: status 400,: headers {},: body "Hello"} ring.core => (ring.util.response / created "/ post / 123 ") {: status 201,: headers {" Location "" / post / 123 "},: body nil} ring.core => (ring.util.response / redirect" //ring-clojure.github. io / ring / ") {: állapot 302,: fejlécek {" Hely "" //ring-clojure.github.io/ring/ "},: törzs" "}

Nálunk is van állapot módszer, amely egy meglévő választ bármilyen tetszőleges állapotkódgá alakít át:

ring.core => (ring.util.response / status (ring.util.response / response "Hello") 409) {: status 409,: headers {},: body "Hello"}

Ezután van néhány módszerünk a válasz egyéb jellemzőinek hasonló beállítására - például, tartalomtípus, fejléc vagy készlet-süti:

ring.core => (ring.util.response / content-type (ring.util.response / response "Hello") "text / plain") {: status 200,: fejlécek "" Content-Type "" text / plain "},: body" Hello "} ring.core => (ring.util.response / header (ring.util.response / response" Hello ")" X-Tutorial-For "" Baeldung ") {: állapot 200, : fejlécek {"X-Tutorial-For" "Baeldung"},: body "Hello"} ring.core => (ring.util.response / set-cookie (ring.util.response / response "Hello") "Felhasználó "" 123 ") {: status 200,: fejlécek {},: body" Hello ",: cookie-k {" User "{: value" 123 "}}}

Vegye figyelembe, hogy a készlet-süti A módszer egy teljesen új bejegyzést ad a választérképhez. Ehhez kell a csomagolás-sütik köztes szoftver hogy helyesen dolgozza fel, hogy működjön.

3.3. Kezelők

Most, hogy megértettük a kéréseket és válaszokat, elkezdhetjük írni a kezelő funkciónkat, hogy összekapcsoljuk.

A kezelő egy egyszerű függvény, amely a bejövő kérést paraméterként veszi fel, és visszaadja a kimenő választ. Amit ebben a funkcióban csinálunk, az kizárólag az alkalmazásunkon múlik, amennyiben ez megfelel ennek a szerződésnek.

A legegyszerűbben írhatunk olyan függvényt, amely mindig ugyanazt a választ adja vissza:

(defn kezelő [kérés] (ring.util.response / válasz "Hello"))

Szükség szerint kölcsönhatásba léphetünk a kéréssel is.

Írhatunk például egy kezelőt a bejövő IP-cím visszaadására:

(defn check-ip-handler [kérés] (ring.util.response / content-type (ring.util.response / response (: remote-addr kérés) "text / plain"))

3.4. Középprogram

A middleware egy olyan név, amely néhány nyelvben elterjedt, de kevésbé a Java világban. Fogalmilag hasonlítanak a Servlet szűrőkhöz és a rugós interceptorokhoz.

A Ringben a middleware olyan egyszerű funkciókra utal, amelyek beburkolják a fő kezelőt, és annak bizonyos aspektusait valamilyen módon módosítják. Ez azt jelentheti, hogy a bejövő kérelmet feldolgozás előtt mutálják, a kimenő választ pedig generálják, vagy esetleg nem tesz mást, mint naplózza, hogy mennyi ideig tartott a feldolgozása.

Általánosságban, A köztes szoftver függvények a kezelő első paraméterét veszik fel, és új kezelő funkciót adnak vissza az új funkcióval.

A köztes szoftver annyi egyéb paramétert használhat, amennyi szükséges. Például a következőket használhatjuk a Tartalom típus fejléc a becsomagolt kezelő minden válaszára:

(defn wrap-content-type [kezelő content-type] (fn [request] (let [válasz (handler-kérelem)] (társított válasz [: headers "Content-Type"] tartalom-típus)))

Végigolvasva láthatjuk, hogy egy olyan függvényt adunk vissza, amely kérést fogad - ez az új kezelő. Ezután felhívja a megadott kezelőt, majd visszaadja a válasz mutált változatát.

Ezt felhasználhatjuk új kezelő gyártásához, egyszerűen összekapcsolva őket:

(def app-handler (wrap-content-type kezelő "text / html"))

A Clojure lehetőséget kínál arra is, hogy sokakat összekapcsoljon egy természetesebb módon - a Threading Macros segítségével. Ez lehetővé teszi a meghívandó funkciók felsorolását, mindegyik az előző kimenetével együtt.

Különösen a Thread First makrót akarjuk, ->. Ez lehetővé teszi számunkra, hogy az egyes köztes programokat első paraméterként a megadott értékkel hívjuk meg:

(def app-handler (-> handler (wrap-content-type "text / html") wrap-keyword-params wrap-params))

Ez egy olyan kezelőt hozott létre, amely az eredeti kezelő, három különböző köztes program funkcióba csomagolva.

4. Íráskezelők

Most, hogy megértettük a Ring alkalmazást alkotó összetevőket, tudnunk kell, mit tehetünk a tényleges kezelőkkel. Ezek jelentik a teljes alkalmazás szívét, és az üzleti logika nagy része itt fog menni.

Bármilyen kódot elhelyezhetünk ezekben a kezelőkben, beleértve az adatbázis-hozzáférést vagy más szolgáltatások hívását. A Ring további képességeket ad a bejövő kérések vagy kimenő válaszok közvetlen kezeléséhez, amelyek szintén nagyon hasznosak.

4.1. Statikus erőforrások kiszolgálása

Az egyik legegyszerűbb funkció, amelyet bármely webalkalmazás elvégezhet, az a statikus erőforrások kiszolgálása. A Ring két köztes programfunkcióval rendelkezik, hogy ezt megkönnyítse - wrap-file és wrap-erőforrás.

A wrap-file A middleware könyvtárat vesz fel a fájlrendszeren. Ha a bejövő kérés egyezik egy könyvtárban található fájllal, akkor a fájl visszatér a kezelő függvény meghívása helyett:

(használja a „ring.middleware.file” fájlt) 
(def app-handler (burkold be a handler-t "/ var / www / public"))

Nagyon hasonló módon, a wrap-erőforrás A middleware egy classpath előtagot vesz fel, amelyben a fájlokat keresi:

(használja a 'ring.middleware.resource' szót) 
(def app-handler (wrap-erőforrás a handler "public"))

Mindkét esetben, a becsomagolt kezelő függvény csak akkor hívódik meg, ha nem találunk egy fájlt, amely visszatérne az ügyfélhez.

A Ring további köztes szoftvert is biztosít, hogy ezek tisztábbak legyenek a HTTP API-n keresztül:

(használja a 'ring.middleware.resource' ring.middleware.content-type 'ring.middleware.not-modified' (def app-handler (-> your-handler (wrap-resource "public") wrap-content-type wrap -nem módosított)

A wrap-content-type a köztes szoftver automatikusan meghatározza a Tartalom típus a kért fájlnévkiterjesztés alapján beállítandó fejléc. A burkolat-nem módosított middleware összehasonlítja a Ha nem módosított fejléc a Utoljára módosítva érték a HTTP gyorsítótár használatához, csak akkor adja vissza a fájlt, ha arra szükség van.

4.2. Hozzáférés a kérési paraméterekhez

A kérelem feldolgozása során néhány fontos mód van arra, hogy az ügyfél információt nyújtson a kiszolgálónak. Ide tartoznak a lekérdezési karakterlánc-paraméterek - amelyek szerepelnek az URL-ben és az űrlapparaméterek -, amelyeket a POST és PUT kérések kérési hasznos terheként nyújtanak be.

A paraméterek használata előtt a burkolatok köztes szoftver a kezelő beburkolásához. Ez helyesen elemzi a paramétereket, támogatva az URL-kódolást, és elérhetővé teszi azokat a kérelem számára. Ez opcionálisan meghatározhatja a használni kívánt karakterkódolást, alapértelmezés szerint UTF-8, ha nincs megadva:

(def app-handler (-> your-handler (wrap-params {: kódolás: "UTF-8"})))

Egyszer kész, a kérés frissül a paraméterek elérhetővé tétele érdekében. Ezek a beérkező kérelem megfelelő kulcsaiba mennek:

  • : query-params - A lekérdezési karakterláncból kiolvasott paraméterek
  • : form-params - A paraméterek ki vannak elemezve az űrlap törzséből
  • : params - Mindkettő kombinációja : query-params és : form-params

Ezt pontosan a várakozásoknak megfelelően használhatjuk fel kéréskezelőnkben.

(defn echo-handler [{params: params}] (ring.util.response / content-type (ring.util.response / response (params "input" beolvasás)) "text / plain"))

Ez a kezelő a paraméter értékét tartalmazó választ ad vissza bemenet.

A paraméterek egyetlen karaktersorozathoz kapcsolódnak, ha csak egy érték van jelen, vagy egy listához, ha több érték van jelen.

Például a következő paramétertérképeket kapjuk:

// / echo? input = hello {"input" hello "} // / echo? input = hello & name = Fred {" input "hello" "name" "Fred"} // / echo? input = hello & input = world {" input ["hello" "world"]}

4.3. Fájlfeltöltések fogadása

Gyakran azt szeretnénk, hogy képesek legyünk olyan webalkalmazások írására, amelyekbe a felhasználók fájlokat tölthetnek fel. A HTTP protokollban ezt általában többrészes kérések segítségével kezelik. Ezek lehetővé teszik, hogy egyetlen kérelem tartalmazza mind az űrlapparamétereket, mind a fájlkészletet.

A Ringhez egy úgynevezett köztes szoftver tartozik burkolat-többrészes-paramok hogy kezelje ezt a fajta kérést. Ez hasonló ahhoz a módhoz burkolatok elemzi az egyszerű kéréseket.

burkolat-többrészes-paramok a feltöltött fájlokat automatikusan dekódolja és eltárolja a fájlrendszerben, és megmondja a kezelőnek, hogy hol kell dolgozniuk:

(def app-handler (-> a-handler wrap-params wrap-multipart-params))

Alapértelmezés szerint, a feltöltött fájlok az ideiglenes rendszerkönyvtárba kerülnek, és egy óra múlva automatikusan törlődnek. Ne feledje, hogy ehhez szükséges, hogy a JVM a következő órában még futjon a tisztítás elvégzéséhez.

Ha úgy tetszik, van még egy memória tároló isbár ez nyilvánvalóan veszélyezteti a memória hiányát, ha nagy fájlokat töltenek fel.

Szükség esetén megírhatjuk tároló motorjainkat is, amennyiben azok megfelelnek az API követelményeinek.

(def app-handler (-> your-handler wrap-params (wrap-multipart-params {: store ring.middleware.multipart-params.byte-array / byte-array-store})))

Miután ez a köztes szoftver be lett állítva, A feltöltött fájlok elérhetők a bejövő kérelem objektumon a params kulcs. Ez megegyezik a burkolatok köztes szoftver. Ez a bejegyzés egy térkép, amely tartalmazza a fájl használatához szükséges részleteket, a használt tárolótól függően.

Például az alapértelmezett ideiglenes fájltároló értékeket ad vissza:

 {"file" {: fájlnév "words.txt": tartalomtípus "text / plain": tempfile #object [java.io.File ...]: 51-es méret}}

Hol a : tempfile bejegyzés a java.io.Fájl objektum, amely közvetlenül képviseli a fájlt a fájlrendszeren.

4.4. Munka a sütikkel

A sütik egy olyan mechanizmus, amelyben a szerver kis mennyiségű adatot tud szolgáltatni, amelyeket az ügyfél a későbbi kérésekre továbbra is visszaküld. Ezt általában munkamenet-azonosítókhoz, hozzáférési tokenekhez vagy állandó felhasználói adatokhoz, például a konfigurált lokalizációs beállításokhoz használják.

A Ring rendelkezik köztes szoftverrel, amely lehetővé teszi számunkra, hogy a sütikkel könnyen dolgozzunk. Ez automatikusan elemzi a cookie-kat a beérkező kérések esetén, és lehetővé teszi számunkra, hogy új cookie-kat hozzunk létre a kimenő válaszokról.

A köztes szoftver konfigurálása ugyanazokat a mintákat követi, mint korábban:

(def app-handler (-> a-handler wrap-cookie-k))

Ezen a ponton, az összes beérkező kérelem elemzi a cookie-kat, és bekerül a : sütik írja be a kérést. Ez a sütik nevének és értékének térképét tartalmazza:

{"session_id" {: value "session-id-hash"}}

Ezután hozzáadhatjuk a kimenő válaszokhoz a sütiket a : sütik kulcs a kimenő válaszhoz. Ezt megtehetjük a válasz közvetlen létrehozásával:

{: status 200: headers {}: cookies {"session_id" {: value "session-id-hash"}}: body "Cookie beállítása."}

Van egy segítő funkció is, amellyel cookie-kat adhatunk a válaszokhoz, hasonlóan ahhoz, ahogyan korábban beállíthatunk állapotkódokat vagy fejléceket:

(ring.util.response / set-cookie (ring.util.response / response "Cookie-k beállítása.") "session_id" "session-id-hash")

A sütikben további opciók is beállíthatók, ha szükséges a HTTP specifikációhoz. Ha használjuk készlet-süti akkor ezeket a kulcs és az érték után térképi paraméterként adjuk meg. A térkép kulcsai a következők:

  • :tartomány - A cookie korlátozására szolgáló domain
  • :pálya - A cookie korlátozásának útja
  • : biztonságosigaz hogy a sütit csak HTTPS kapcsolatokon küldje el
  • : csak http-csakigaz hogy a cookie elérhetetlen legyen a JavaScript számára
  • : maximális életkor - Azon másodpercek száma, amelyek után a böngésző törli a sütit
  • : lejár - Egy meghatározott időbélyeg, amely után a böngésző törli a cookie-t
  • : ugyanazon a helyen - Ha értéke :szigorú, akkor a böngésző nem küldi vissza ezt a cookie-t webhelyek közötti kérésekkel.
(ring.util.response / set-cookie (ring.util.response / response "Cookie-k beállítása.") "session_id" "session-id-hash" {: biztonságos true: csak http-true igaz: max-3600 életkor} )

4.5. Munkamenetek

A cookie-k lehetővé teszik számunkra, hogy tároljunk olyan információkat, amelyeket az ügyfél minden kérésre visszaküld a szervernek. Ennek elérésének hatékonyabb módja a munkamenetek használata. Ezeket a szerver teljesen tárolja, de az ügyfél fenntartja az azonosítót, amely meghatározza, hogy melyik munkamenetet használja.

Mint minden más itt, a munkamenetek egy middleware függvény segítségével valósulnak meg:

(def app-handler (-> a-handler wrap-session))

Alapértelmezés szerint, ez tárolja a munkamenet adatait a memóriában. Szükség esetén ezen változtathatunk, és a Ringhez tartozik egy alternatív áruház is, amely cookie-kat használ a munkamenet összes adatának tárolására.

Mint a fájlok feltöltésekor, szükség esetén biztosíthatjuk tárolási funkciónkat.

(def app-handler (-> your-handler wrap-cookies (wrap-session {: store (cookie-store {: kulcs "16 bájtos titok"}}}})))

A munkamenetkulcs tárolásához használt cookie részleteit is módosíthatjuk.

Például annak érdekében, hogy a munkamenet süti egy órán át fennmaradjon, megtehetjük:

(def app-handler (-> a kezelője wrap-cookie-k (wrap-session {: cookie-attrs {: max-age 3600}})))

A cookie attribútumok itt megegyeznek a csomagolás-sütik köztes szoftver.

A munkamenetek gyakran működhetnek adattárolóként. Ez nem mindig működik olyan jól egy funkcionális programozási modellben, ezért a Ring ezeket kissé másképp hajtja végre.

Helyette, hozzáférünk a munkamenet adataihoz a kérésből, és a válasz részeként visszaküldjük az adatok térképét, hogy azokat tároljuk. Ez a teljes munkamenet-állapot, nem csak a megváltozott értékek.

Például az alábbiak folyamatosan számolják, hogy a kezelőt hányszor kérték:

(defn kezelő [{session: session}] (let [count (: munkamenet 0 számlálása) session (társított munkamenet: count (inc count))] (-> (válasz (str "Ezt az oldalt" alkalommal "számoltad." )) (társ: munkamenet))))

Így dolgozva megtehetjük távolítsa el az adatokat a munkamenetből egyszerűen a kulcs beiktatásával. Visszatéréssel törölhetjük a teljes munkamenetet is nulla az új térképhez.

(defn kezelő [kérés] (-> (válasz "A munkamenet törölve.") (társítva: munkamenet nulla)))

5. Leiningen bővítmény

A Ring egy bővítményt biztosít a Leiningen build eszközhöz, amely segíti mind a fejlesztést, mind a gyártást.

A bővítményt úgy állítottuk be, hogy a megfelelő bővítmény adatait hozzáadtuk a project.clj fájl:

 : plugins [[lein-ring "0.12.5"]]: ring {: kezelő ring.core / kezelő}

Fontos, hogy a lein-gyűrű helyes a Ring verziójához. Itt az 1.7.1 gyűrűt használtuk, ami azt jelenti, hogy szükségünk van rá lein-gyűrű 0.12.5. Általánosságban elmondható, hogy a legbiztonságosabb mindkettő legújabb verzióját használni, ahogyan azt a Maven központjában vagy a lein keresés parancs:

$ lein search ring-core Keresés clojarsban ... [ring / ring-core "1.7.1"] Ring core könyvtárak. $ lein keresés lein-ring Keresés klojrokban ... [lein-ring "0.12.5"] Leiningen Ring plugin

A : kezelő paraméter a :gyűrű A call a használni kívánt kezelő teljesen minősített neve. Ez magában foglalhat minden általunk definiált köztes szoftvert.

A bővítmény használata azt jelenti, hogy már nincs szükségünk fő funkcióra. Használhatjuk a Leiningen-t fejlesztési módban történő futtatásra, vagy pedig gyártási műtárgyat készíthetünk telepítési célokra. A kódunk most pontosan a logikánknak felel meg, és semmi más.

5.1. Termelési műtárgy építése

Ha ez be van állítva, most létrehozhatunk egy WAR fájlt, amelyet bármelyik standard szervlet-tárolóba telepíthetünk:

$ lein ring uberwar 2019-04-12 07: 10: 08.033: INFO :: main: A naplózás inicializálva @ 1054ms az org.eclipse.jetty.util.log.StdErrLog létrehozva ./clojure/ring/target/uberjar/ring-0.1 .0-SNAPSHOT-önálló.háború

Készíthetünk egy önálló JAR fájlt is, amely pontosan az elvárásoknak megfelelően fogja futtatni a kezelőnket:

$ lein ring uberjar A ring.core összeállítása 2019-04-12 07: 11: 27.669: INFO :: main: A naplózás inicializálva lett @ 3016ms az org.eclipse.jetty.util.log.StdErrLog létrehozva ./clojure/ring/target/uberjar /ring-0.1.0-SNAPSHOT.jar Created ./clojure/ring/target/uberjar/ring-0.1.0-SNAPSHOT-standalone.jar

Ez a JAR fájl tartalmazni fog egy fő osztályt, amely elindítja a kezelőt a beágyazott tárolóban, amelyet belefoglaltunk. Ez a környezeti változót is tiszteletben tartja KIKÖTŐ lehetővé téve számunkra, hogy egyszerűen futtassuk termelési környezetben:

PORT = 2000 java -jar ./clojure/ring/target/uberjar/ring-0.1.0-SNAPSHOT-standalone.jar 2019-04-12 07: 14: 08.954: INFO :: main: A naplózás inicializálva @ 1009ms az org számára. eclipse.jetty.util.log.StdErrLog VIGYÁZAT! már utal: # 'clojure.core / seqable? a névtérben: clojure.core.inkubator, helyébe a következő lép: # 'clojure.core.inkubátor / seqable? 2019-04-12 07: 14: 10.795: INFO: oejs. Szerver: main: móló-9.4.z-SNAPSHOT; épült: 2018-08-30T13: 59: 14.071Z; git: 27208684755d94a92186989f695db2d7b21ebc51; jvm 1.8.0_77-b03 2019-04-12 07: 14: 10.863: INFO: oejs.AbstractConnector: main: Elkezdve [e-mail védett] {HTTP / 1.1, [http / 1.1]} {0.0.0.0:2000} 2019- 04-12 07: 14: 10.863: INFO: oejs. Szerver: main: Indult @ 2918ms Indítva a kiszolgálót a 2000-es porton

5.2. Fejlesztési módban fut

Fejlesztési célokra, futtathatjuk a kezelőt közvetlenül Leiningenből anélkül, hogy manuálisan kellene építenünk és futtatnunk. Ez megkönnyíti az alkalmazásunk valódi böngészőben történő tesztelését:

$ lein ring szerver 2019-04-12 07: 16: 28.908: INFO :: main: A naplózás inicializálva van @ 1403ms az org.eclipse.jetty.util.log.StdErrLog 2019-04-12 07: 16: 29.026: INFO: oejs .Szerver: main: móló-9.4.12.v20180830; épült: 2018-08-30T13: 59: 14.071Z; git: 27208684755d94a92186989f695db2d7b21ebc51; jvm 1.8.0_77-b03 2019-04-12 07: 16: 29.092: INFO: oejs.AbstractConnector: main: Elkezdve [e-mail védett] {HTTP / 1.1, [http / 1.1]} {0.0.0.0:3000} 2019- 04-12 07: 16: 29.092: INFO: oejs. Szerver: main: Indult @ 1587ms

Ez is tiszteletben tartja a KIKÖTŐ környezeti változó, ha ezt beállítottuk.

Ezenkívül van egy Ring Development könyvtár, amelyet hozzáadhatunk a projektünkhöz. Ha ez elérhető, akkor a fejlesztőkiszolgáló megpróbálja automatikusan feltölteni az észlelt forrásváltozásokat. Ez hatékony munkafolyamatot nyújthat számunkra a kód megváltoztatásával és a böngészőnk élőben való megtekintésével. Ehhez szükség van a gyűrű-devel függőség hozzáadása:

[ring / ring-devel "1.7.1"]

6. Következtetés

Ebben a cikkben röviden bemutattuk a Ring könyvtárat, amely a Clojure webalkalmazások írásának eszköze. Miért nem próbálja ki a következő projekten?

Az itt bemutatott fogalmakra példákat láthatunk a GitHub-ban.


$config[zx-auto] not found$config[zx-overlay] not found