Improve README (finally)
This commit is contained in:
87
README.md
87
README.md
@@ -9,6 +9,9 @@ endpoints :
|
||||
* `POST /items`: creates an item
|
||||
* `GET /items`: returns the list of items
|
||||
|
||||
This was a great opportunity for me to learn more about Clojure. Whatever the
|
||||
result of the recruitment process, it was really fun working on this assignment!
|
||||
|
||||
## Running and testing
|
||||
|
||||
This project uses Leiningen. Assuming you already have Leiningen installed,
|
||||
@@ -31,13 +34,85 @@ The source code lies in `/src/yohoho` and is structured as follows:
|
||||
* `routes.clj`: API routes
|
||||
* `schemas.cls`: Malli schemas used for validation
|
||||
|
||||
## Library choices
|
||||
## Library/tools choices
|
||||
|
||||
* `reitit`: for handling routes
|
||||
* `jetty`: web server
|
||||
* `muuntaja`: JSON handling
|
||||
* `next.jdbc`: database interface (SQLite)
|
||||
* `malli`: validation
|
||||
Since this is just a small assignment, I sticked to simple and proven tools:
|
||||
|
||||
* SQLite for the database (easy to setup, easy to use with `next.jdbc`)
|
||||
* Leiningen for managing the project (it seems to be getting outdated in favor
|
||||
of Clojure CLI Tools, but is still widely used and I could find more
|
||||
documentation)
|
||||
* Libraries : `reitit` for route handling + `malli` for validation + `muuntaja`
|
||||
for handling json content. Thanks for the suggestions in the assignment! I
|
||||
chose `reitit` because it seemed more complete/integrated than Compojure.
|
||||
However, in the context of this simple assignment, Compojure may have been a
|
||||
better choice (would have probably been easier to learn)
|
||||
* Web server: `jetty` (seems to be pretty standard)
|
||||
|
||||
## Comments
|
||||
|
||||
Respect of the assignment:
|
||||
|
||||
* The API features the `POST /items` and `GET /items` endpoints
|
||||
* `POST /items` accepts a JSON payload, validates it and returns HTTP 400 is
|
||||
validation fails
|
||||
* `POST /items` persists data in SQLite
|
||||
* `GET /items` returns the list of all items as JSON.
|
||||
* The structure of the items is respected, although it just includes the bare
|
||||
minimum (id, name, email).
|
||||
* A data validation library is used (`malli`)
|
||||
* Unit tests were written (although generated with the help of Claude Code)
|
||||
* Integration tests were written (although generated with the help of Claude
|
||||
Code too)
|
||||
* The API is documented (OpenAPI `/openapi.json` + Swagger UI at `/doc`)
|
||||
|
||||
Divergences from the assignment:
|
||||
|
||||
* The `POST /items` do not take the id in the input. Instead, I prefer to let
|
||||
the database generate a new id on its own.
|
||||
* As a consequence, the `id` of an item is an integer, not a string. SQLite can
|
||||
autogenerate/autoincrement only on a integer id.
|
||||
|
||||
What was not part of the assignment:
|
||||
|
||||
* `GET /ahoy` health check endpoint. As you may guess, this was my very first
|
||||
endpoint as I was learning how to use `reitit`. I decided to keep it, because
|
||||
a health check endpoint cannot hurt.
|
||||
* `GET /item/:id` was included. This was quite easy to add, and also makes sense
|
||||
since the `POST /items` endpoint follows standard practice of returning a
|
||||
`Location` header for the newly created item.
|
||||
|
||||
Security:
|
||||
|
||||
* SQL injections: we should be ok since we are not using raw SQL statements in
|
||||
`db.clj` (`next.jdbc` will use parametrized statements under the hood)
|
||||
* `POST /items` input has validation
|
||||
* See the "Desirable improvement" section for some missing security features
|
||||
|
||||
## Desirable improvements
|
||||
|
||||
This project is voluntarily kept simple. If it were to get deployed in
|
||||
production, the following should be dealt with, in no particular order:
|
||||
|
||||
* `GET /items`: add pagination
|
||||
* Security: Add rate limiting
|
||||
* Security: Add authentication/authorization
|
||||
* Security: Add and configure CORS middleware
|
||||
* Add logging
|
||||
* TLS: it's fine that the API is accessible only through http, but it should be
|
||||
deployed behind a reverse proxy to add TLS/https support. This is quite easy
|
||||
to do with Apache, Nginx or Caddy.
|
||||
* Database: use a migration system. This was definitely unnecessary for this
|
||||
assignment, but should be used for a more serious project. Migratus seems to
|
||||
be the de-facto library for this.
|
||||
* Database: switch to a more serious database (PostgreSQL comes to mind), add
|
||||
connection pooling, use transactions.
|
||||
* Add metrics (request rate, response time, database connection
|
||||
pool stats, etc.) and monitoring (eg. using Datadog).
|
||||
* Configuration: add the ability to override deffault configuration using a
|
||||
dotenv file and/or environment variables.
|
||||
* Add a supervisor to ensure the API keeps running (could be as easy as using
|
||||
systemd, or as complex as deploying with kubernetes)
|
||||
|
||||
## Documentation links
|
||||
|
||||
|
||||
Reference in New Issue
Block a user