diff --git a/examples/http-swagger/src/example/server.clj b/examples/http-swagger/src/example/server.clj index 078ca83b..eb84bd73 100644 --- a/examples/http-swagger/src/example/server.clj +++ b/examples/http-swagger/src/example/server.clj @@ -9,6 +9,7 @@ [reitit.http.interceptors.muuntaja :as muuntaja] [reitit.http.interceptors.exception :as exception] [reitit.http.interceptors.multipart :as multipart] + [reitit.http.interceptors.dev :as dev] [reitit.interceptor.sieppari :as sieppari] [ring.adapter.jetty :as jetty] [aleph.http :as client] @@ -108,7 +109,8 @@ {:status 200 :body {:total (- x y)}})}}]]] - {:data {:coercion spec-coercion/coercion + {;:reitit.interceptor/transform dev/print-request-diffs + :data {:coercion spec-coercion/coercion :muuntaja m/instance :interceptors [;; query-params & form-params (parameters/parameters-interceptor) diff --git a/examples/ring-swagger/src/example/server.clj b/examples/ring-swagger/src/example/server.clj index 5e997dbb..370970ef 100644 --- a/examples/ring-swagger/src/example/server.clj +++ b/examples/ring-swagger/src/example/server.clj @@ -8,6 +8,7 @@ [reitit.ring.middleware.exception :as exception] [reitit.ring.middleware.multipart :as multipart] [reitit.ring.middleware.parameters :as parameters] + [reitit.ring.middleware.dev :as dev] [ring.adapter.jetty :as jetty] [muuntaja.core :as m] [clojure.java.io :as io])) @@ -60,7 +61,8 @@ {:status 200 :body {:total (+ x y)}})}}]]] - {:data {:coercion reitit.coercion.spec/coercion + {;:reitit.middleware/transform dev/print-request-diffs + :data {:coercion reitit.coercion.spec/coercion :muuntaja m/instance :middleware [;; query-params & form-params parameters/parameters-middleware diff --git a/modules/reitit-interceptors/project.clj b/modules/reitit-interceptors/project.clj index d2dd97d4..cd760ef6 100644 --- a/modules/reitit-interceptors/project.clj +++ b/modules/reitit-interceptors/project.clj @@ -9,4 +9,5 @@ :parent-project {:path "../../project.clj" :inherit [:deploy-repositories :managed-dependencies]} :dependencies [[metosin/reitit-ring] + [lambdaisland/deep-diff] [metosin/muuntaja]]) diff --git a/modules/reitit-interceptors/src/reitit/http/interceptors/dev.clj b/modules/reitit-interceptors/src/reitit/http/interceptors/dev.clj new file mode 100644 index 00000000..5d6cf11d --- /dev/null +++ b/modules/reitit-interceptors/src/reitit/http/interceptors/dev.clj @@ -0,0 +1,50 @@ +(ns reitit.http.interceptors.dev + (:require [lambdaisland.deep-diff :as ddiff] + [lambdaisland.deep-diff.printer :as printer] + [puget.color :as color] + [reitit.core :as r])) + +(def printer + (-> (printer/puget-printer) + (assoc :width 70) + (update :color-scheme merge {:name [:blue]}))) + +(defn- empty-context? [ctx] + (-> ctx :request nil?)) + +(defn diff-doc [stage name previous current] + [:group + [:span "--- " (str stage) " " (if name (color/document printer :name (str name " "))) "---" :break :break] + [:nest (printer/format-doc (if (empty-context? previous) current (ddiff/diff previous current)) printer)] + :break]) + +(defn- polish [ctx] + (-> ctx + (dissoc ::original ::previous :stack :queue) + (update :request dissoc ::r/match ::r/router))) + +(defn- handle [name stage] + (fn [{:keys [::original ::previous] :as ctx}] + (let [current (polish ctx) + previous (polish previous)] + (printer/print-doc (diff-doc stage name previous current) printer) + (-> ctx + (update ::original (fnil identity ctx)) + (assoc ::previous ctx))))) + +(defn diff-interceptor + [stages {:keys [enter leave error name]}] + (cond-> {:name ::diff} + (and enter (stages :enter)) (assoc :enter (handle name :enter)) + (and leave (stages :leave)) (assoc :leave (handle name :leave)) + (and error (stages :error)) (assoc :error (handle name :error)))) + +(defn print-request-diffs + "A interceptor chain transformer that adds a context diff printer between all interceptors" + [chain] + (reduce + (fn [chain interceptor] + (into chain [(diff-interceptor #{:leave :error} interceptor) + interceptor + (diff-interceptor #{:enter} interceptor)])) + [(diff-interceptor #{:enter :leave :error} {:enter identity})] chain)) diff --git a/modules/reitit-middleware/project.clj b/modules/reitit-middleware/project.clj index 7f6291f1..2be4d3bf 100644 --- a/modules/reitit-middleware/project.clj +++ b/modules/reitit-middleware/project.clj @@ -9,4 +9,5 @@ :parent-project {:path "../../project.clj" :inherit [:deploy-repositories :managed-dependencies]} :dependencies [[metosin/reitit-ring] + [lambdaisland/deep-diff] [metosin/muuntaja]]) diff --git a/modules/reitit-middleware/src/reitit/ring/middleware/dev.clj b/modules/reitit-middleware/src/reitit/ring/middleware/dev.clj new file mode 100644 index 00000000..7f183752 --- /dev/null +++ b/modules/reitit-middleware/src/reitit/ring/middleware/dev.clj @@ -0,0 +1,39 @@ +(ns reitit.ring.middleware.dev + (:require [lambdaisland.deep-diff :as ddiff] + [lambdaisland.deep-diff.printer :as printer] + [puget.color :as color] + [reitit.core :as r])) + +(def printer + (-> (printer/puget-printer) + (assoc :width 70) + (update :color-scheme merge {:middleware [:blue]}))) + +(defn diff-doc [x y z] + [:group + [:span "--- Middleware " (if z (color/document printer :middleware (str z " "))) "---" :break :break] + [:nest (printer/format-doc (if x (ddiff/diff x y) y) printer)] + :break]) + +(defn polish [request] + (dissoc request ::r/match ::r/router ::original ::previous)) + +(defn print-diff-middleware + ([] + (print-diff-middleware nil)) + ([{:keys [name]}] + {:name ::debug + :wrap (fn [handler] + (fn [{:keys [::original ::previous] :as request}] + (printer/print-doc (diff-doc (polish previous) (polish request) name) printer) + (handler (-> request + (update ::original (fnil identity request)) + (assoc ::previous request)))))})) + +(defn print-request-diffs + "A middleware chain transformer that adds a request-diff printer between all middleware" + [chain] + (reduce + (fn [chain mw] + (into chain [mw (print-diff-middleware (select-keys mw [:name]))])) + [(print-diff-middleware)] chain)) diff --git a/project.clj b/project.clj index edbb0878..1f86a0d7 100644 --- a/project.clj +++ b/project.clj @@ -23,6 +23,7 @@ [metosin/reitit-frontend "0.2.7"] [metosin/reitit-sieppari "0.2.7"] [meta-merge "1.0.0"] + [lambdaisland/deep-diff "0.0-25"] [ring/ring-core "1.7.1"] [metosin/ring-swagger-ui "2.2.10"] [metosin/spec-tools "0.8.2"] @@ -80,7 +81,7 @@ [funcool/promesa "1.9.0"] ;; https://github.com/bensu/doo/issues/180 - [fipp "0.6.14"]]} + [fipp "0.6.14" :exclusions [org.clojure/core.rrb-vector]]]} :perf {:jvm-opts ^:replace ["-server" "-Xmx4096m" "-Dclojure.compiler.direct-linking=true"]