Created
February 26, 2025 05:48
-
-
Save xonev/0aa0078f9e5d19ac63c8fd0adb8b4a4b to your computer and use it in GitHub Desktop.
AWS Lambda function URL emulating dev server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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