Compiling Middleware
-The meta-data extensions are a easy way to extend the system. Routes meta-data can be transformed into any shape (records, functions etc.) in route compilation, enabling fast access at request-time.
-Still, we can do better. As we know the exact route that interceptor/middleware is linked to, we can pass the (compiled) route information into the interceptor/middleware at creation-time. It can extract and transform relevant data just for it and pass it into the actual request-handler via a closure - yielding faster runtime processing.
-To do this we use middleware records :gen hook instead of the normal :wrap. :gen expects a function of route-meta router-opts => wrap. Middleware can also return nil, which effective unmounts the middleware. Why mount a wrap-enforce-roles middleware for a route if there are no roles required for it?
-To demonstrate the two approaches, below are response coercion middleware written as normal ring middleware function and as middleware record with :gen. These are the actual codes are from reitit.coercion:
+The dynamic extensions is a easy way to extend the system. To enable fast lookups into route data, we can compile them into any shape (records, functions etc.) we want, enabling fast access at request-time.
+Still, we can do better. As we know the exact route that middleware/interceptor is linked to, we can pass the (compiled) route information into the middleware/interceptor at creation-time. It can do local reasoning: extract and transform relevant data just for it and pass it into the actual request-handler via a closure - yielding much faster runtime processing. Middleware/interceptor can also decide not to mount itself. Why mount a wrap-enforce-roles middleware for a route if there are no roles required for it?
+To enable this we use middleware records :gen hook instead of the normal :wrap. :gen expects a function of route-meta router-opts => wrap. Middleware can also return nil, which effective unmounts the middleware.
+To demonstrate the two approaches, below are response coercion middleware written as normal ring middleware function and as middleware record with :gen. These are the actual codes are from reitit.ring.coercion:
Naive
- Extracts the compiled route information on every request.
@@ -409,7 +422,7 @@
(defn wrap-coerce-response
"Pluggable response coercion middleware.
Expects a :coercion of type `reitit.coercion.protocol/Coercion`
- and :responses from route meta, otherwise does not mount."
+ and :responses from route meta, otherwise will do nothing."
[handler]
(fn
([request]
@@ -420,20 +433,17 @@
coercion (-> match :meta :coercion)
opts (-> match :meta :opts)]
(if (and coercion responses)
- (let [coercers (response-coercers coercion responses opts)
- coerced (coerce-response coercers request response)]
- (coerce-response coercers request (handler request)))
- (handler request))))
+ (let [coercers (response-coercers coercion responses opts)]
+ (coerce-response coercers request response))
+ response)))
([request respond raise]
- (let [response (handler request)
- method (:request-method request)
+ (let [method (:request-method request)
match (ring/get-match request)
responses (-> match :result method :meta :responses)
coercion (-> match :meta :coercion)
opts (-> match :meta :opts)]
(if (and coercion responses)
- (let [coercers (response-coercers coercion responses opts)
- coerced (coerce-response coercers request response)]
+ (let [coercers (response-coercers coercion responses opts)]
(handler request #(respond (coerce-response coercers request %))))
(handler request respond raise))))))
@@ -459,7 +469,7 @@
([request respond raise]
(handler request #(respond (coerce-response coercers request %)) raise)))))))}))
-The :gen -version has 50% less code, is easier to reason about and is 2-4x faster on basic perf tests.
+The :gen -version has 50% less code, is easier to reason about and is twice as faster on basic perf tests.
@@ -499,7 +509,7 @@
diff --git a/ring/data_driven_middleware.html b/ring/data_driven_middleware.html
new file mode 100644
index 00000000..1a5d3e9c
--- /dev/null
+++ b/ring/data_driven_middleware.html
@@ -0,0 +1,546 @@
+
+
+
+
+