reitit/ring/middleware_registry.html

837 lines
24 KiB
HTML
Raw Normal View History

<!DOCTYPE HTML>
<html lang="" >
<head>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Middleware Registry · GitBook</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="description" content="">
<meta name="generator" content="GitBook 3.2.3">
<link rel="stylesheet" href="../gitbook/style.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-highlight/website.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-search/search.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-fontsettings/website.css">
<meta name="HandheldFriendly" content="true"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="../gitbook/images/apple-touch-icon-precomposed-152.png">
<link rel="shortcut icon" href="../gitbook/images/favicon.ico" type="image/x-icon">
<link rel="next" href="default_middleware.html" />
<link rel="prev" href="data_driven_middleware.html" />
</head>
<body>
<div class="book">
<div class="book-summary">
<div id="book-search-input" role="search">
<input type="text" placeholder="Type to search" />
</div>
<nav role="navigation">
<ul class="summary">
<li class="chapter " data-level="1.1" data-path="../">
<a href="../">
Introduction
</a>
</li>
<li class="chapter " data-level="1.2" data-path="../basics/">
<a href="../basics/">
Basics
</a>
<ul class="articles">
<li class="chapter " data-level="1.2.1" data-path="../basics/route_syntax.html">
<a href="../basics/route_syntax.html">
Route Syntax
</a>
</li>
<li class="chapter " data-level="1.2.2" data-path="../basics/router.html">
<a href="../basics/router.html">
Router
</a>
</li>
<li class="chapter " data-level="1.2.3" data-path="../basics/path_based_routing.html">
<a href="../basics/path_based_routing.html">
Path-based Routing
</a>
</li>
<li class="chapter " data-level="1.2.4" data-path="../basics/name_based_routing.html">
<a href="../basics/name_based_routing.html">
Name-based Routing
</a>
</li>
<li class="chapter " data-level="1.2.5" data-path="../basics/route_data.html">
<a href="../basics/route_data.html">
Route Data
</a>
</li>
<li class="chapter " data-level="1.2.6" data-path="../basics/route_data_validation.html">
<a href="../basics/route_data_validation.html">
Route Data Validation
</a>
</li>
<li class="chapter " data-level="1.2.7" data-path="../basics/route_conflicts.html">
<a href="../basics/route_conflicts.html">
Route Conflicts
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.3" data-path="../coercion/">
<a href="../coercion/">
Coercion
</a>
<ul class="articles">
<li class="chapter " data-level="1.3.1" data-path="../coercion/coercion.html">
<a href="../coercion/coercion.html">
Coercion Explained
</a>
</li>
<li class="chapter " data-level="1.3.2" data-path="../coercion/schema_coercion.html">
<a href="../coercion/schema_coercion.html">
Plumatic Schema
</a>
</li>
<li class="chapter " data-level="1.3.3" data-path="../coercion/clojure_spec_coercion.html">
<a href="../coercion/clojure_spec_coercion.html">
Clojure.spec
</a>
</li>
<li class="chapter " data-level="1.3.4" data-path="../coercion/data_spec_coercion.html">
<a href="../coercion/data_spec_coercion.html">
Data-specs
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.4" data-path="../advanced/">
<a href="../advanced/">
Advanced
</a>
<ul class="articles">
<li class="chapter " data-level="1.4.1" data-path="../advanced/configuring_routers.html">
<a href="../advanced/configuring_routers.html">
Configuring Routers
</a>
</li>
<li class="chapter " data-level="1.4.2" data-path="../advanced/composing_routers.html">
<a href="../advanced/composing_routers.html">
Composing Routers
</a>
</li>
<li class="chapter " data-level="1.4.3" data-path="../advanced/different_routers.html">
<a href="../advanced/different_routers.html">
Different Routers
</a>
</li>
<li class="chapter " data-level="1.4.4" data-path="../advanced/route_validation.html">
<a href="../advanced/route_validation.html">
Route Validation
</a>
</li>
<li class="chapter " data-level="1.4.5" data-path="../advanced/dev_workflow.html">
<a href="../advanced/dev_workflow.html">
Dev Workflow
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.5" data-path="./">
<a href="./">
Ring
</a>
<ul class="articles">
<li class="chapter " data-level="1.5.1" data-path="ring.html">
<a href="ring.html">
Ring-router
</a>
</li>
<li class="chapter " data-level="1.5.2" data-path="reverse_routing.html">
<a href="reverse_routing.html">
Reverse-routing
</a>
</li>
<li class="chapter " data-level="1.5.3" data-path="default_handler.html">
<a href="default_handler.html">
Default handler
</a>
</li>
<li class="chapter " data-level="1.5.4" data-path="static.html">
<a href="static.html">
Static Resources
</a>
</li>
<li class="chapter " data-level="1.5.5" data-path="dynamic_extensions.html">
<a href="dynamic_extensions.html">
Dynamic Extensions
</a>
</li>
<li class="chapter " data-level="1.5.6" data-path="data_driven_middleware.html">
<a href="data_driven_middleware.html">
Data-driven Middleware
</a>
</li>
<li class="chapter active" data-level="1.5.7" data-path="middleware_registry.html">
<a href="middleware_registry.html">
Middleware Registry
</a>
</li>
<li class="chapter " data-level="1.5.8" data-path="default_middleware.html">
<a href="default_middleware.html">
Default Middleware
</a>
</li>
<li class="chapter " data-level="1.5.9" data-path="coercion.html">
<a href="coercion.html">
Pluggable Coercion
</a>
</li>
<li class="chapter " data-level="1.5.10" data-path="route_data_validation.html">
<a href="route_data_validation.html">
Route Data Validation
</a>
</li>
<li class="chapter " data-level="1.5.11" data-path="compiling_middleware.html">
<a href="compiling_middleware.html">
Compiling Middleware
</a>
</li>
<li class="chapter " data-level="1.5.12" data-path="swagger.html">
<a href="swagger.html">
Swagger Support
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.6" data-path="../frontend/">
<a href="../frontend/">
Frontend
</a>
<ul class="articles">
<li class="chapter " data-level="1.6.1" data-path="../frontend/basics.html">
<a href="../frontend/basics.html">
Basics
</a>
</li>
<li class="chapter " data-level="1.6.2" data-path="../frontend/browser.html">
<a href="../frontend/browser.html">
Browser integration
</a>
</li>
<li class="chapter " data-level="1.6.3" data-path="../frontend/controllers.html">
<a href="../frontend/controllers.html">
Controllers
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.7" data-path="../performance.html">
<a href="../performance.html">
Performance
</a>
</li>
<li class="chapter " data-level="1.8" data-path="../interceptors.html">
<a href="../interceptors.html">
Interceptors (WIP)
</a>
</li>
<li class="chapter " data-level="1.9" data-path="../development.html">
<a href="../development.html">
Development Instructions
</a>
</li>
<li class="chapter " data-level="1.10" data-path="../faq.html">
<a href="../faq.html">
FAQ
</a>
</li>
<li class="divider"></li>
<li>
<a href="https://www.gitbook.com" target="blank" class="gitbook-link">
Published with GitBook
</a>
</li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<div class="book-header" role="navigation">
<!-- Title -->
<h1>
<i class="fa fa-circle-o-notch fa-spin"></i>
<a href=".." >Middleware Registry</a>
</h1>
</div>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<div id="book-search-results">
<div class="search-noresults">
<section class="normal markdown-section">
<h1 id="middleware-registry">Middleware Registry</h1>
<p>The <code>:middleware</code> syntax in <code>reitit-ring</code> supports also Keywords. Keywords are looked from Middleware Registry, which is a map of <code>keyword =&gt; IntoMiddleware</code>. Middleware registry should be stored under key <code>:reitit.middleware/registry</code> in the router options. If a middleware keyword isn&apos;t found in the registry, router creation fails fast with descriptive error message.</p>
<h2 id="examples">Examples</h2>
<p>Application using middleware defined in the Middleware Registry:</p>
<pre><code class="lang-clj">(<span class="hljs-name">require</span> &apos;[reitit.ring <span class="hljs-symbol">:as</span> ring])
(<span class="hljs-name">require</span> &apos;[reitit.middleware <span class="hljs-symbol">:as</span> middleware])
(<span class="hljs-name"><span class="hljs-builtin-name">defn</span></span> wrap-bonus [handler value]
(<span class="hljs-name"><span class="hljs-builtin-name">fn</span></span> [request]
(<span class="hljs-name">handler</span> (<span class="hljs-name">update</span> request <span class="hljs-symbol">:bonus</span> (<span class="hljs-name">fnil</span> + <span class="hljs-number">0</span>) value))))
(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> app
(<span class="hljs-name">ring/ring-handler</span>
(<span class="hljs-name">ring/router</span>
[<span class="hljs-string">&quot;/api&quot;</span> {<span class="hljs-symbol">:middleware</span> [[<span class="hljs-symbol">:bonus</span> <span class="hljs-number">20</span>]]}
[<span class="hljs-string">&quot;/bonus&quot;</span> {<span class="hljs-symbol">:middleware</span> [<span class="hljs-symbol">:bonus10</span>]
<span class="hljs-symbol">:get</span> (<span class="hljs-name"><span class="hljs-builtin-name">fn</span></span> [{<span class="hljs-symbol">:keys</span> [bonus]}]
{<span class="hljs-symbol">:status</span> <span class="hljs-number">200</span>, <span class="hljs-symbol">:body</span> {<span class="hljs-symbol">:bonus</span> bonus}})}]]
{<span class="hljs-symbol">::middleware/registry</span> {<span class="hljs-symbol">:bonus</span> wrap-bonus
<span class="hljs-symbol">:bonus10</span> [<span class="hljs-symbol">:bonus</span> <span class="hljs-number">10</span>]}})))
</code></pre>
<p>Works as expected:</p>
<pre><code class="lang-clj">(<span class="hljs-name">app</span> {<span class="hljs-symbol">:request-method</span> <span class="hljs-symbol">:get</span>, <span class="hljs-symbol">:uri</span> <span class="hljs-string">&quot;/api/bonus&quot;</span>})
<span class="hljs-comment">; {:status 200, :body {:bonus 30}}</span>
</code></pre>
<p>Router creation fails fast if registry doesn&apos;t contain the Middleware:</p>
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> app
(<span class="hljs-name">ring/ring-handler</span>
(<span class="hljs-name">ring/router</span>
[<span class="hljs-string">&quot;/api&quot;</span> {<span class="hljs-symbol">:middleware</span> [[<span class="hljs-symbol">:bonus</span> <span class="hljs-number">20</span>]]}
[<span class="hljs-string">&quot;/bonus&quot;</span> {<span class="hljs-symbol">:middleware</span> [<span class="hljs-symbol">:bonus10</span>]
<span class="hljs-symbol">:get</span> (<span class="hljs-name"><span class="hljs-builtin-name">fn</span></span> [{<span class="hljs-symbol">:keys</span> [bonus]}]
{<span class="hljs-symbol">:status</span> <span class="hljs-number">200</span>, <span class="hljs-symbol">:body</span> {<span class="hljs-symbol">:bonus</span> bonus}})}]]
{<span class="hljs-symbol">::middleware/registry</span> {<span class="hljs-symbol">:bonus</span> wrap-bonus}})))
<span class="hljs-comment">;CompilerException clojure.lang.ExceptionInfo: Middleware :bonus10 not found in registry.</span>
<span class="hljs-comment">;</span>
<span class="hljs-comment">;Available middleware in registry:</span>
<span class="hljs-comment">;</span>
<span class="hljs-comment">;| :id | :description |</span>
<span class="hljs-comment">;|--------+--------------------------------------|</span>
<span class="hljs-comment">;| :bonus | reitit.ring_test$wrap_bonus@59fddabb |</span>
</code></pre>
<h2 id="when-to-use-the-registry">When to use the registry?</h2>
<p>Middleware as Keywords helps to keep the routes (all but handlers) as literal data (e.g. data that evaluates to itself) enabling the routes to be persisted in external formats like EDN-files and databases. Duct is a good example where the <a href="https://github.com/duct-framework/duct/wiki/Configuration" target="_blank">middleware can be referenced from EDN-files</a>. It should be easy to make Duct configuration a Middleware Registry in <code>reitit-ring</code>.</p>
<p>The bad thing it&apos;s an extra indirection, making things more complex and removed the default IDE-support of &quot;goto definition&quot; or &quot;look source&quot;.</p>
<h2 id="todo">TODO</h2>
<ul>
<li>a prefilled registry of common middleware in the <code>reitit-middleware</code></li>
</ul>
</section>
</div>
<div class="search-results">
<div class="has-results">
<h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
<ul class="search-results-list"></ul>
</div>
<div class="no-results">
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
</div>
</div>
</div>
</div>
</div>
</div>
<a href="data_driven_middleware.html" class="navigation navigation-prev " aria-label="Previous page: Data-driven Middleware">
<i class="fa fa-angle-left"></i>
</a>
<a href="default_middleware.html" class="navigation navigation-next " aria-label="Next page: Default Middleware">
<i class="fa fa-angle-right"></i>
</a>
</div>
<script>
var gitbook = gitbook || [];
gitbook.push(function() {
gitbook.page.hasChanged({"page":{"title":"Middleware Registry","level":"1.5.7","depth":2,"next":{"title":"Default Middleware","level":"1.5.8","depth":2,"path":"ring/default_middleware.md","ref":"ring/default_middleware.md","articles":[]},"previous":{"title":"Data-driven Middleware","level":"1.5.6","depth":2,"path":"ring/data_driven_middleware.md","ref":"ring/data_driven_middleware.md","articles":[]},"dir":"ltr"},"config":{"plugins":["editlink","github","highlight"],"root":"doc","styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"pluginsConfig":{"editlink":{"label":"Edit This Page","multilingual":false,"base":"https://github.com/metosin/reitit/tree/master/doc"},"github":{"url":"https://github.com/metosin/reitit"},"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"theme":"default","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"gitbook":"*"},"file":{"path":"ring/middleware_registry.md","mtime":"2018-08-22T17:24:29.926Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-08-22T17:25:09.089Z"},"basePath":"..","book":{"language":""}});
});
</script>
</div>
<script src="../gitbook/gitbook.js"></script>
<script src="../gitbook/theme.js"></script>
<script src="../gitbook/gitbook-plugin-editlink/plugin.js"></script>
<script src="../gitbook/gitbook-plugin-github/plugin.js"></script>
<script src="../gitbook/gitbook-plugin-search/search-engine.js"></script>
<script src="../gitbook/gitbook-plugin-search/search.js"></script>
<script src="../gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
<script src="../gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
<script src="../gitbook/gitbook-plugin-sharing/buttons.js"></script>
<script src="../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
</body>
</html>