Handler bodies contain HTML elements (div, p, span) which need the render pipeline. eval-expr treats them as function calls. aser evaluates and serializes HTML to wire format. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
50 lines
1.6 KiB
Plaintext
50 lines
1.6 KiB
Plaintext
(define
|
|
api
|
|
(fn
|
|
(slug)
|
|
(let
|
|
((handler-key (str "handler:ex-" slug)))
|
|
(let
|
|
((hdef (cek-try (fn () (eval-expr (make-symbol handler-key))) (fn (err) nil))))
|
|
(if
|
|
(nil? hdef)
|
|
(error (str "Handler not found: " handler-key))
|
|
(call-handler hdef))))))
|
|
|
|
(define
|
|
call-handler
|
|
(fn
|
|
(hdef)
|
|
(let
|
|
((method (get hdef "method"))
|
|
(params (get hdef "params"))
|
|
(body (get hdef "body"))
|
|
(closure (get hdef "closure")))
|
|
(let
|
|
((req-method (request-method))
|
|
(handler-method (upper (or method "get"))))
|
|
(if
|
|
(and
|
|
(not (= handler-method "GET"))
|
|
(not (= req-method handler-method)))
|
|
(error
|
|
(str
|
|
"Method not allowed: expected "
|
|
handler-method
|
|
" got "
|
|
req-method))
|
|
(eval-handler-body params body closure))))))
|
|
|
|
(define
|
|
eval-handler-body
|
|
(fn
|
|
(params body closure)
|
|
(if
|
|
(or (nil? params) (empty? params))
|
|
(aser body closure)
|
|
(let
|
|
((bindings (map (fn (p) (let ((name (if (symbol? p) (symbol-name p) (str p)))) (if (= name "&key") nil (if (= name "&rest") nil (let ((val (or (request-arg name) (request-form name)))) (list (make-symbol name) (or val nil))))))) (filter (fn (p) (let ((name (if (symbol? p) (symbol-name p) (str p)))) (and (not (= name "&key")) (not (= name "&rest"))))) params))))
|
|
(let
|
|
((let-form (list (quote let) (filter (fn (b) (not (nil? b))) bindings) body)))
|
|
(aser let-form closure))))))
|