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
This commit is contained in:
2026-01-30 17:25:35 +01:00
commit c278633c66
5 changed files with 122 additions and 0 deletions

13
.gitignore vendored Normal file
View File

@@ -0,0 +1,13 @@
/target
/classes
/checkouts
profiles.clj
pom.xml
pom.xml.asc
*.jar
*.class
/.clj-kondo
/.lein-*
/.lsp
/.nrepl-port
/.prepl-port

14
LICENSE Normal file
View File

@@ -0,0 +1,14 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
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.

29
README.md Normal file
View File

@@ -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:
* <https://practical.li/clojure-web-services/building-api/>
* <https://github.com/metosin/reitit/blob/master/doc/ring/content_negotiation.md>

14
project.clj Normal file
View File

@@ -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"]}})

52
src/yohoho/core.clj Normal file
View File

@@ -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"))