clojuredecoratorinterceptoryada

Prepend function to every route request in yada


currently i am playing with Yada as web lib. Now i want to execute some function before a route is hit.

Approaches I have tested: - wrap the current resource as sub-resource, but then the swagger-doc doesn't find the resource - using an prepend-interceptor, but the docu is not complete at this point at i got errors

My code:

(ns all-mighty.namespace
    (:require [yada.yada :refer [handler listener resource as-resource]]
              [yada.swagger :refer [swaggered]])

(defn resources []
[""
 (swaggered
     [""
      [
       (cool-route)
       ]]
     {:info     {:title       "Hello You!"
                 :version     "1.0"
                 :description "It's something"}
      :basePath ""}
     )])

(defn cool-route []
["/cool" (resource {
                   :description "Returns somethign cool"
                   :produces    "application/json"
                   :methods     {:get {:response cool-response}}}
                  )])

(defn cool-response [ctx]
(-> (:response ctx)
    (assoc :status 200)
    (assoc :body {:state :up}))

Yeah, I'll refactor the resources latter ;-)

Does someone has an idea?


Solution

  • The way I'm using append-interceptor:

    (ns all-mighty.namespace
      (:require
       [yada.handler :refer [append-interceptor]]
       [yada.interceptors :as i]
       [yada.swagger :refer [swaggered]]
       [yada.yada :refer [handler listener resource as-resource]]))
    
    (defn cool-response [ctx]
      {:state :up
       :my/value (get ctx :my/value)})
    
    (defn my-cool-interceptor [ctx]
      (assoc ctx :my/value 10))
    
    (defn my-cool-resource
      [model]
      (-> model
       ;; you have to provide an interception chain, here we use the default one
       (assoc :interceptor-chain yada.yada/default-interceptor-chain)
       resource
       ;; here we append our interceptor after the request body has been processed
       (append-interceptor i/process-request-body my-cool-interceptor)))
    
    (defn cool-route []
      ["/cool" (my-cool-resource {:description "Returns somethign cool"
                                  :produces    "application/json"
                                  :methods     {:get {:response cool-response}}})])
    
    (defn routes []
      [""
       (swaggered
        [""
         [
          (cool-route)
          ]]
        {:info     {:title       "Hello You!"
                    :version     "1.0"
                    :description "It's something"}
         :basePath ""}
        )])
    
    (comment
      (def l (listener (routes) {:port 1337}))
      ((:close l))
      )
    

    So for every resource under /cool you can use the my-cool-resource function to automatically add the desired interceptor.