This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-10-10
Channels
- # babashka (37)
- # babashka-sci-dev (22)
- # beginners (16)
- # biff (12)
- # calva (40)
- # cider (6)
- # clj-kondo (7)
- # clojure (183)
- # clojure-austin (20)
- # clojure-doc (22)
- # clojure-europe (16)
- # clojure-nl (2)
- # clojure-norway (39)
- # clojure-romania (1)
- # clojure-uk (9)
- # clojuredesign-podcast (9)
- # clojurescript (29)
- # core-typed (66)
- # cursive (19)
- # data-science (14)
- # docker (5)
- # fulcro (6)
- # hyperfiddle (46)
- # java (5)
- # malli (19)
- # missionary (3)
- # off-topic (84)
- # pedestal (5)
- # portal (36)
- # reitit (35)
- # releases (2)
- # shadow-cljs (30)
- # web-security (2)
- # yamlscript (1)
I går så jeg @slipset sin talk fra ClojureD OG hørte på defn-episoden hans. Vet ikke hvordan jeg har gått glipp av dem før, men jeg satte god pris på begge to 🙂 👍
Mange interessante betraktninger, og den podcasten var veldig trivelig. Du undervurderer seg selv 😅
Takk, alt for mye ros! Jeg har bodd to år i Junaiten tilsammen, et år da jeg var 7 (og så Star Wars) og et år da jeg var 16(?)
Det at jeg så Star Wars da den kom ut var en sjelsettende opplevelse for meg. Den og The Cat from Outer Space. Men det er liksom ikke like kult å ha sett den.
https://ericnormand.me/guide/clojure-web-tutorial var ganske fin egentlig! Utrolig nok har jeg aldri hatt en "web 101" selv om jeg har laget web apps i PHP, Ruby, Python, C# og Elixir med web frameworks tidligere. Jeg har ikke hatt behov for å forstå hvordan HTTP requests fungerer fra first principles. Men det er jo svært interessant og nyttig å vite!
én endring jeg ville gjort fra det artikkelen forklarer er å alltid kjøre stop-server før man kjører start-server. Da funker alltid start (idempotent), og du slipper å huske på å kjøre stop før du kjører start. feks sånn:
(defonce server (atom nil))
(defn stop-server []
(when-some [s @server] ;; check if there is an object in the atom
(.stop s) ;; call the .stop method
(reset! server nil)));; overwrite the atom with nil
(defn start-server []
(stop-server)
(reset! server
(jetty/run-jetty (fn [req] {:status 200 :body "Hello" :headers {}}) ;; a really basic handler
{:port 3001 ;; listen on port 3001
:join? false}))) ;; don't block the main thread
Når man bruker when-some
på den måten kan man teknisk sett få en race condition hvis to tråder prøver å stoppe serveren samtidig. Men det er superduperpirk! swap!
er laget for å kunne den situasjonen bedre, men da blir koden litt vanskeligere.Bare noe så essensielt som dette var en øyeåpner for meg: > "Each server uses a different Java class to represent the request. The adapter's purpose is to convert the server's custom Java request class into a standardized Ring request. Once it has transformed the custom class into a standard Ring request, we are in the realm of Ring apps." Da tenkte jeg, "Aha! Så Ring er på en måte et abstraksjonslag for web servere," så kunne jeg koble det til abstraksjonslaget vi lagde for DirectX og OpenGL for grafikkmotoren vår i Funcom. Det var ikke før nå i dag at det falt på plass for meg hva Ring egentlig gjør.
Hvis man bruker Ring betyr vel det at det er relativt enkelt å bytte til en annen web server også vil jeg tro.
jeg husker også at jeg likte den artikkelen fra Eric Normand skikkelig godt da jeg leste den! Jeg tror det er utrolig viktig å få kommet i gang med en http-server, en liten router, og handlers som funksjoner fra request-som-data til repons-som-data.
Jeg har i dag laget et tomt repo for appen jeg nevnte for leden dag: https://clojurians.slack.com/archives/C061XGG1W/p1696496057253029 Min plan er nå å få opp en veldig basic "Hello World" i Clojure + ClojureScript med så få dependencies som mulig lokalt på min maskin. Da fant jeg guiden til Eric Normand. Så vil jeg få deployet denne appen via CI/CD før jeg begynner å legge til features. Jeg følger rådet til Roy Osherove om å ha build- og deployment på plass fra dag én.
P.t. tenker jeg å kun introdusere biblioteker ved behov for å se hvor få jeg faktisk trenger. Ring ser nærmest uungåelig ut.
Ring tror jeg du ønsker å ha, ja! Tror det er vanskelig å komme utenom følgende: 1. Modellere HTTP requests / response som ring-maps 2. Ring-kompatibel HTTP-server (Feks http-kit eller ring-jetty-adapter) 3. Ring-kompatibel router (feks compojure eller reitit)
For øvrig har jeg ikke funnet noen god guide på Clojure deployment via CI/CD enda. I mitt tilfelle må jeg gjøre deploy via GitHub Actions (eller til nøds Azure DevOps) med ressurser i Microsoft Azure. Vi har alt kjørende i Kubernetes. Så det blir spennende å se hvor vanskelig det blir å finne ut av de tingene.
I og med at appen min kun skal hente og spleise sammen data fra andre kilder (K8s, Splunk, GitHub, Jira, etc.) håper jeg på å slippe en database så lenge som mulig, typ "in-memory/cache only."
Autentisering via Azure Active Directory føler jeg meg også ganske usikker på. Jeg må ha det på plass sånn at ansatte kan be om tilgang til appen min og logge seg inn via Single Sign-On med OTP. Det er kanskje aspektet jeg gruer meg mest til å finne ut av p.t. Men jeg tar ikke den sorgen på forskudd 😅
Jeg føler ikke jeg har god kontroll på CI/CD jeg heller. Får til å kjøre tester på commits med Github actions og cognitect sin test runner; mer komplisert oppsett har jeg ikke laget før.
En ruter er ihvertfall veldig mye mindre essensielt enn de to andre tingene på den lista.
Og for meg i allefall var en ruter litt magisk, men det er jo egentlig bare akkurat det @christian767 sier. Mener til og med å huske at det finnes et eget lib for url-matching som compojure bruker.
Mang en ruter-forfatter har falt for fristelsen til å både lage ting for magisk og lesse på med mer features enn hva 95% trenger 😅
Mang en bibliotek-forfatter har falt for fristelsen til å både lage ting for magisk og lesse på med mer features enn hva 95% trenger 😅
Absolutt 😄 Men jeg har inntrykk av at det er spesielt lett å gå i den fella når man lager rutere. Jeg har prøvd, og gjort akkurat samme feil sjøl. Flere ganger!
Hvordan er det vanlig å strukturere et prosjekt som inneholder både server-side Clojure stuff og client-side ClojureScript stuff? Jeg tenker mest på noe så praktisk som mappestruktur og navnerom. Og er det vanlig å blande og dele kode mellom Clojure og ClojureScript? :thinking_face:
Det går fint ann å dele kode, men der er noen pitfalls med tanke på underliggende datatyper som f.eks tidsbaserte enheter. For min del er den største fordelen med Clojure(Script) på frontend og backend at du kan dele samme tankesett og datastrukturer, mer enn at du får gjenbrukt kode.
Takk for tipset, @U0PS4MS80! Er dette en god idé for organiseringen av kode?:
.
├── clj-backend
│ ├── deps.edn
│ ├── resources
│ │ └── picture.png
│ ├── src
│ │ └── main.clj
│ └── test
│ └── test_main.clj
├── cljs-frontend
│ ├── deps.edn
│ ├── resources
│ │ └── picture.png
│ ├── src
│ │ └── main.cljs
│ └── test
│ └── test_main.cljs
└── common
├── src
│ └── common.clj
└── test
└── test_common.clj