Skip to content

Instantly share code, notes, and snippets.

@xonev
Created February 26, 2025 05:48
Show Gist options
  • Save xonev/0aa0078f9e5d19ac63c8fd0adb8b4a4b to your computer and use it in GitHub Desktop.
Save xonev/0aa0078f9e5d19ac63c8fd0adb8b4a4b to your computer and use it in GitHub Desktop.
AWS Lambda function URL emulating dev server
(ns nudgsicle.server
(:require [goog.object]
[clojure.string :as s]
[nudgsicle.api :as api]
[nudgsicle.logging :refer [log]]
["http" :as http]))
(defn- parse-query-string
[raw-query-string]
(->> raw-query-string
(reduce (fn [params [k v]]
(let [values (get params k [])]
(assoc params k (conj values v))))
{})
(reduce (fn [params [k v]]
(let [value (if (= (count v) 1)
(first v)
(s/join "," v))]
(assoc params k value)))
{})))
(defn lambda-emulator [^js req ^js res]
(let [url (js/URL. (str "http://localhost:3000" (.-url req)))
function-url-event {:rawPath (.-pathname url)
:rawQueryString (.-search url)
:queryStringParameters (clj->js (parse-query-string (.entries (.-searchParams url))))
:requestContext {:http {:method (.-method req)
:path (.-pathname url)}}}]
(api/handler (clj->js function-url-event)
nil
(fn [err result]
(let [clj-result (js->clj result :keywordize-keys true)]
(if err
(throw err)
(do
(log "info" {:path (.-pathname url)})
(goog.object/set res "statusCode" (:statusCode clj-result))
(.setHeaders res (js/Headers. (clj->js (:headers clj-result))))
(.end res (.stringify js/JSON (clj->js (:body clj-result)))))))))))
(defonce server-ref
(volatile! nil))
(defn main [& _]
(log {:message "Starting development server"})
(let [port 3000
server (http/createServer #(lambda-emulator %1 %2))]
(.listen server port
(fn [err]
(if err
(log "error" {:error err})
(log {:message "Development server started"
:port port}))))
(vreset! server-ref server)))
(defn start []
(main))
(defn stop [done]
(log {:message "Stopping development server"})
(when-some [server @server-ref]
(.close server
(fn [err]
(log {:message "Development server stopped"
:error err})
(done)))
(vreset! server-ref nil)))
(comment
(->> (.entries (.-searchParams (js/URL. "http://localhost:3000/status?test=1&test=2&foo=bar")))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment