From c278633c6654acdfabb4fcd3ca1432887004e300 Mon Sep 17 00:00:00 2001 From: Benjamin Sigonneau Date: Fri, 30 Jan 2026 17:25:35 +0100 Subject: [PATCH] Initial commit This initial version is purposely extremily limited: * `GET /ahoy` endpoint, just to check the server is alive * `GET /items` endpoint, always returns the same item * `POST items` endpoint, checks and print request payload, no persistance * calling any other route defaults to a 404 --- .gitignore | 13 ++++++++++++ LICENSE | 14 ++++++++++++ README.md | 29 +++++++++++++++++++++++++ project.clj | 14 ++++++++++++ src/yohoho/core.clj | 52 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 122 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 project.clj create mode 100644 src/yohoho/core.clj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de3bf7f --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +/target +/classes +/checkouts +profiles.clj +pom.xml +pom.xml.asc +*.jar +*.class +/.clj-kondo +/.lein-* +/.lsp +/.nrepl-port +/.prepl-port diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ee7d6a5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..3fcc257 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# Yohoho - A take-home assignment for HolidayPirates + +This is my take on the take-home assignment I was given for the Backend Engineer +position at HolidayPirates. + +The goal is to implement a very small REST API in Clojure. That API provides two +endpoints : + +* `POST /items`: creates an item +* `GET /items`: returns the list of items + +## Usage + +This project uses Leiningen. Assuming you already have Leiningen installed, +running the API should be as easy as cloning the repo and issuing `lein run`. By +default, the server listens on port 3000. + +## Library choices + +* `reitit`: for handling routes +* `jetty`: web server +* `muuntaja`: JSON handling + +## Documentation links + +The following links proved more than useful when working on this assignment: + +* +* diff --git a/project.clj b/project.clj new file mode 100644 index 0000000..e713531 --- /dev/null +++ b/project.clj @@ -0,0 +1,14 @@ +(defproject yohoho "0.1.0-SNAPSHOT" + :description "Yo-Ho-Ho, a take home assignment for the brave" + :url "https://git.dromaludaire.info/yohoho" + :license {:name "WTFPL – Do What the Fuck You Want to Public License" + :url "https://www.wtfpl.net/about/"} + :dependencies [[org.clojure/clojure "1.12.4"] + [ring/ring-core "1.15.3"] + [ring/ring-jetty-adapter "1.15.3"] + [metosin/reitit "0.10.0"] + [metosin/muuntaja "0.6.11"]] + :main ^:skip-aot yohoho.core + :target-path "target/%s" + :profiles {:uberjar {:aot :all + :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}}) diff --git a/src/yohoho/core.clj b/src/yohoho/core.clj new file mode 100644 index 0000000..3e23923 --- /dev/null +++ b/src/yohoho/core.clj @@ -0,0 +1,52 @@ +(ns yohoho.core + (:require [reitit.ring :as ring] + [ring.adapter.jetty :as http-server] + [reitit.ring.middleware.muuntaja :as muuntaja] + [muuntaja.core :as m]) + (:gen-class)) + + +(defn ahoy-handler + [_] + {:status 200 + :body "Ahoy mate, the ship be sailin' alright"}) + +(defn get-items-handler + [_] + {:status 200 + :body {:id 1 + :name "Jack Sparrow" + :email "jack.sparrow@triangle.bm"}}) + +(defn post-items-handler + [request] + (let [item (:body-params request) + id 1 + name (:name item) + email (:email item)] + {:status 201 + :headers {"Location" (str "/item/" id)} + :body {:id id, :name name, :email email}})) + + +(def app + (ring/ring-handler + (ring/router + [["/ahoy" {:get ahoy-handler}] + ["/items" {:get get-items-handler + :post post-items-handler}]] + ;; Use muuntaja middleware to automatically decode JSON + {:data {:muuntaja m/instance + :middleware [muuntaja/format-middleware]}}) + ;; Default route: anything not explicitely handled should give a 404 + (ring/create-default-handler + {:not-found (constantly {:status 404 + :body {:error "Not Found"}})}))) + + +(defn -main + "HolidayPirates take-home assignement. + Goal: build a (very) small REST API that exposes to endpoints." + [& args] + (http-server/run-jetty app {:port 3000 :join? false}) + (println "Ahoy! Yo-ho-ho API running on port 3000"))