The [dynamic extensions](dynamic_extensions.md) are an easy way to extend the system. To enable fast lookup of route data, we can compile them into any shape (records, functions etc.), enabling fast access at request-time.
But, we can do much better. As we know the exact route that a middleware/interceptor is linked to, we can pass the (compiled) route information into the middleware at creation-time. It can do local reasoning: Extract and transform relevant data just for it and pass the optimized data into the actual request-handler via a closure - yielding much faster runtime processing. A middleware can also decide not to mount itself by returning `nil`. (E.g. 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](data_driven_middleware.md) `:compile` key instead of the normal `:wrap`. `:compile` expects a function of `route-data router-opts => ?IntoMiddleware`.
To demonstrate the two approaches, below is the response coercion middleware written as normal ring middleware function and as middleware record with `:compile`.
In the example above the `:spec` expresses that each route is required to provide the `:authorize` key. However, in this case the compile function returns `nil` when that key is missing, which means **the middleware will not be mounted, the spec will not be considered, and the compiler will not enforce this requirement as intended**.
If you just want to enforce the spec return a map without `:wrap` or `:compile` keys, e.g. an empty map, `{}`.