Compojure использует "middleware" для обработки HTTP-запросов, вы можете посмотреть на его реализацию.«Обработчик» в Compojure - это функция, которая принимает запрос и возвращает ответ.(Запрос и ответ - оба хеш-карты Clojure.) «Промежуточное программное обеспечение» - это функция, которая принимает функцию-обработчик и возвращает другую функцию-обработчик.Промежуточное программное обеспечение может изменять запрос, ответ или оба;он может вызвать обработчик, которому он был передан (повторно, если он хочет), или замкнуть накоротко и игнорировать обработчик и т. д. Вы можете обернуть обработчики в другие обработчики таким образом в любой комбинации.
Благодаря функциям, являющимся первокласснымиобъекты, это очень легкий и простой в реализации и использовании.Однако во время компиляции он ничего не применяет, как вы могли бы получить из интерфейса Java;все дело в следующих соглашениях и наборе утки. Протоколы могут в конечном итоге пригодиться для этой задачи, но они некоторое время не будут доступны (вероятно, в Clojure 2.0?)
Не уверен, что это то, что вы хотите, но здесьочень элементарная версия:
;; Handler
(defn default [msg]
{:from "Server"
:to (:from msg)
:response "Hi there."})
;; Middleware
(defn logger [handler]
(fn [msg]
(println "LOGGING MESSAGE:" (pr-str msg))
(handler msg)))
(defn datestamper [handler]
(fn [msg]
(assoc (handler msg)
:datestamp (.getTime (java.util.Calendar/getInstance)))))
(defn short-circuit [handler]
(fn [msg]
{:from "Ninja"
:to (:from msg)
:response "I intercepted your message."}))
;; This would do something with a response (send it to a remote server etc.)
(defn do-something [response]
(println ">>>> Response:" (pr-str response)))
;; Given a message and maybe a handler, handle the message
(defn process-message
([msg] (process-message msg identity))
([msg handler]
(do-something ((-> default handler) msg))))
Тогда:
user> (def msg {:from "Chester" :to "Server" :message "Hello?"})
#'user/msg
user> (process-message msg)
>>>> Response: {:from "Server", :to "Chester", :response "Hi there."}
nil
user> (process-message msg logger)
LOGGING MESSAGE: {:from "Chester", :to "Server", :message "Hello?"}
>>>> Response: {:from "Server", :to "Chester", :response "Hi there."}
nil
user> (process-message msg (comp logger datestamper))
LOGGING MESSAGE: {:from "Chester", :to "Server", :message "Hello?"}
>>>> Response: {:datestamp #<Date Fri Nov 27 17:50:29 PST 2009>, :from "Server", :to "Chester", :response "Hi there."}
nil
user> (process-message msg (comp short-circuit logger datestamper))
>>>> Response: {:from "Ninja", :to "Chester", :response "I intercepted your message."}
nil