(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))
      (eval-expr body)
      (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)))
          (eval-expr let-form))))))
