Skip to content

Commit 6bed94c

Browse files
draft: repl driven api service from scratch
1 parent dbe5953 commit 6bed94c

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
---
2+
title: Clojure REPL driven API project from scratch
3+
date:
4+
created: 2024-07-21
5+
updated: 2024-07-21
6+
authors:
7+
- practicalli
8+
categories:
9+
- clojure
10+
tags:
11+
- clojure
12+
- api
13+
draft: true
14+
---
15+
16+
Creating a comprehensive API project in Clojure.
17+
18+
??? HINT "Practicalli Project Templates"
19+
[Practicalli Project Templates](https://practical.li/clojure/clojure-cli/projects/templates/practicalli) provides several templates to build production level projects. Generated projects can include component management systems, e.g. donut-party/system or integrant.
20+
21+
Create a new project called gameboard managed by donut-party/system with an example API service and swagger documentation.
22+
```shell
23+
clojure -T:project/create :template practicalli/service :name practicalli/gameboard :component donut
24+
```
25+
26+
<!-- more -->
27+
28+
## Create a project
29+
30+
Create a Clojure CLI project using Practicalli Clojure CLI config. Clojure 1.12. supports hot loading of library dependencies.
31+
32+
```shell
33+
clojure -T:project/create :template practicalli/application :name practicalli/repl-driven-api
34+
```
35+
36+
## Start REPL
37+
38+
Start a REPL process along with nREPL server to enable your Clojure aware editor to connect to the REPL and give instant feedback.
39+
40+
!!! EXAMPLE "Start a REPL with nREPL server & a rich terminal UI"
41+
```shell
42+
clojure -M:repl/rebel
43+
```
44+
45+
> The REPL could also be started from a Clojure aware editor (jack-in)
46+
47+
48+
## Web server
49+
50+
The Web Server listens to HTTP requests and sends HTTP responses back to the calling client.
51+
52+
53+
Http kit and jetty are the most commonly used web servers. Http-kit is predominantly written in Clojure and will be used for these examples
54+
55+
56+
!!! EXAMPLE "Add http-kit library"
57+
```shell
58+
;; add-libs command
59+
```
60+
61+
62+
!!! EXAMPLE "Add function to start & stop http-kit server"
63+
```clojure
64+
65+
```
66+
67+
## Convert HTTP request to Clojure
68+
69+
Ring is the defacto library that bridges the world of HTTP requests & responses with Clojure. Ring acts as an adaptor on top of the web server.
70+
71+
Ring converts an HTTP request into a Clojure Hash Map, the request map.
72+
73+
Once a response has been created, Ring converts the response map into an HTTP response.
74+
75+
!!! EXAMPLE "Add Reitit libraries"
76+
```shell
77+
78+
```
79+
80+
## Routing http requests
81+
82+
Routing takes a request and sends it to a header function to create a response.
83+
84+
Reitit configuration is a hash-map with HTTP type (GET, POST, )
85+
Add a request router function to dispatch requests to specific handler functions
86+
87+
!!! EXAMPLE "Add a reitit-ring router"
88+
```clojure
89+
90+
```
91+
92+
> Reitit is a library that provides routing for both Clojure and ClojureScript. Reitit-ring provides the webserver adaptor for back-end Clojure applications. Reitit also includes libraries for middleware, coersion, etc.
93+
94+
95+
96+
97+
[Anatomy of a Clojure Web Service](https://practical.li/clojure-web-services/app-servers){target=_blank .md-button}
98+
99+
??? INFO:
100+
101+
102+
## Service REPL
103+
104+
105+
106+
## Integrant
107+
108+
109+
Integrant is a data centric approach although I would like simpler code design to work with.
110+
111+
112+
Integrant REPL is a separate library
113+
114+
115+
## Donut
116+
117+
118+
119+
A data as code approach, extended by simple functions
120+
121+
defmethod only used to create different system types, so only a minimal used (unless there is a very complex set of systems)
122+
123+
REPL tools are built into the System library.
124+
125+
126+
127+
## Reloadable Code
128+
129+
Minimise
130+
- macros
131+
- defmethod, deftype, defrecord
132+
133+
134+
## Exclude code from reload
135+
136+
Set refresh directories to include all paths except those that should be excluded from the reload, e.g `(set-refresh-dirs "src" "resources")` will exclude the `"test"` and `"dev"` directories from the refresh.
137+
138+
The `set-refresh-dirs` function returns the directory paths set, so including the function call within a printlin expression provides useful feedback on REPL startup.
139+
140+
!!! EXAMPLE "Set directories to reload"
141+
```clojure
142+
(require '[clojure.tools.namespace.repl :refer [set-refresh-dirs]])
143+
144+
;; ---------------------------------------------------------
145+
;; Avoid reloading `dev` code
146+
;; - code in `dev` directory should be evaluated if changed to reload into repl
147+
(println
148+
"Set REPL refresh directories to "
149+
(set-refresh-dirs "src" "resources"))
150+
;; ---------------------------------------------------------
151+
```
152+
153+
154+
---
155+
Thank you.
156+
157+
[:globe_with_meridians: Practical.li Website](https://practical.li){target=_blank .md-button}
158+
159+
[:fontawesome-brands-github: Practical.li GitHub Org](https://github.com/practicalli){target=_blank .md-button}
160+
[:fontawesome-brands-github: practicalli-johnny profile](https://github.com/practicalli-johnny){target=_blank .md-button}
161+
162+
[:fontawesome-brands-mastodon: @practicalli@clj.social](https://clj.social/@practicalli){target=_blank .md-button}
163+
[:fontawesome-brands-twitter: @practical_li](https://twitter.com/practcial_li){target=_blank .md-button}

0 commit comments

Comments
 (0)