From b9ae9a8b560cf36c3ef8177df7186de5ec5ef5a8 Mon Sep 17 00:00:00 2001 From: Benjamin Sigonneau Date: Fri, 30 Jan 2026 18:25:31 +0100 Subject: [PATCH] Check 'POST /items' payload is application/json This commit adds a middleware function that checks any POST endpoint is called with Content-Type: application/json. Returns `HTTP 415 Unsupported Media Type` if this is not the case. TODO: this commit does not check that the payload is actually well-formed JSON. If the payload is *not* valid JSON, muutaja will fail, which will result in an `HTTP 500 Server error`. --- src/yohoho/core.clj | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/yohoho/core.clj b/src/yohoho/core.clj index 3e23923..c8741e6 100644 --- a/src/yohoho/core.clj +++ b/src/yohoho/core.clj @@ -6,6 +6,8 @@ (:gen-class)) + +;; Handlers ------------------------------------------------------- (defn ahoy-handler [_] {:status 200 @@ -29,6 +31,22 @@ :body {:id id, :name name, :email email}})) +;; Custom middleware ---------------------------------------------- +(defn wrap-content-type-json + "Middleware that checks is a POST request is bring sent data as JSON" + [handler] + (fn [request] + (let [http-verb (:request-method request) + is-post? (= :post http-verb) + content-type (get-in request [:headers "content-type"]) + is-json? (= "application/json" content-type)] + (cond (not is-post?) (handler request) + (and is-post? is-json?) (handler request) + :else {:status 415 + :body {:error "Unsupported Media Type" + :message "Content-Type must be application/json"}})))) + +;; Routing -------------------------------------------------------- (def app (ring/ring-handler (ring/router @@ -37,13 +55,15 @@ :post post-items-handler}]] ;; Use muuntaja middleware to automatically decode JSON {:data {:muuntaja m/instance - :middleware [muuntaja/format-middleware]}}) + :middleware [wrap-content-type-json + 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"}})}))) +;; Entry point ---------------------------------------------------- (defn -main "HolidayPirates take-home assignement. Goal: build a (very) small REST API that exposes to endpoints."