mirror of
https://github.com/metosin/reitit.git
synced 2025-12-22 18:41:10 +00:00
Build book from commit ae75021aac [skip ci]
This commit is contained in:
parent
02a4636fd8
commit
f718171106
30 changed files with 1129 additions and 979 deletions
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -630,7 +630,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Configuring Routers","level":"1.4.1","depth":2,"next":{"title":"Different Routers","level":"1.4.2","depth":2,"path":"advanced/different_routers.md","ref":"advanced/different_routers.md","articles":[]},"previous":{"title":"Advanced","level":"1.4","depth":1,"path":"advanced/README.md","ref":"advanced/README.md","articles":[{"title":"Configuring Routers","level":"1.4.1","depth":2,"path":"advanced/configuring_routers.md","ref":"advanced/configuring_routers.md","articles":[]},{"title":"Different Routers","level":"1.4.2","depth":2,"path":"advanced/different_routers.md","ref":"advanced/different_routers.md","articles":[]},{"title":"Route Validation","level":"1.4.3","depth":2,"path":"advanced/route_validation.md","ref":"advanced/route_validation.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":"advanced/configuring_routers.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Configuring Routers","level":"1.4.1","depth":2,"next":{"title":"Different Routers","level":"1.4.2","depth":2,"path":"advanced/different_routers.md","ref":"advanced/different_routers.md","articles":[]},"previous":{"title":"Advanced","level":"1.4","depth":1,"path":"advanced/README.md","ref":"advanced/README.md","articles":[{"title":"Configuring Routers","level":"1.4.1","depth":2,"path":"advanced/configuring_routers.md","ref":"advanced/configuring_routers.md","articles":[]},{"title":"Different Routers","level":"1.4.2","depth":2,"path":"advanced/different_routers.md","ref":"advanced/different_routers.md","articles":[]},{"title":"Route Validation","level":"1.4.3","depth":2,"path":"advanced/route_validation.md","ref":"advanced/route_validation.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":"advanced/configuring_routers.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -547,23 +547,23 @@
|
|||
<tbody>
|
||||
<tr>
|
||||
<td><code>:linear-router</code></td>
|
||||
<td>Matches the routes one-by-one starting from the top until a match is found. Works with any kind of routes. Slow, but works with all route trees.</td>
|
||||
<td>Matches the routes one-by-one starting from the top until a match is found. Slow, but works with all route trees.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>:segment-router</code></td>
|
||||
<td>Router that creates a optimized <a href="https://en.wikipedia.org/wiki/Trie" target="_blank">search trie</a> out of an route table. Much faster than <code>:linear-router</code> for wildcard routes. Valid only if there are no <a href="../basics/route_conflicts.html">Route conflicts</a>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>:lookup-router</code></td>
|
||||
<td>Fast router, uses hash-lookup to resolve the route. Valid if no paths have path or catch-all parameters and there are no <a href="../basics/route_conflicts.html">Route conflicts</a>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>:mixed-router</code></td>
|
||||
<td>Creates internally a <code>:segment-router</code> for wildcard routes and a <code>:lookup-router</code> or <code>:single-static-path-router</code> for static routes. Valid only if there are no <a href="../basics/route_conflicts.html">Route conflicts</a>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>:single-static-path-router</code></td>
|
||||
<td>Super fast router: sting-matches the route. Valid only if there is one static route.</td>
|
||||
<td>Super fast router: string-matches a route. Valid only if there is one static route.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>:segment-router</code></td>
|
||||
<td>Router that creates a optimized <a href="https://en.wikipedia.org/wiki/Trie" target="_blank">search trie</a> out of an route table. Much faster than <code>:linear-router</code> for wildcard routes. Valid only if there are no <a href="../basics/route_conflicts.html">Route conflicts</a>.</td>
|
||||
<td><code>:mixed-router</code></td>
|
||||
<td>Contains two routers: <code>:segment-router</code> for wildcard routes and a <code>:lookup-router</code> or <code>:single-static-path-router</code> for static routes. Valid only if there are no <a href="../basics/route_conflicts.html">Route conflicts</a>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -577,6 +577,18 @@
|
|||
|
||||
(<span class="hljs-name">r/router-name</span> router)
|
||||
<span class="hljs-comment">; :mixed-router</span>
|
||||
</code></pre>
|
||||
<p>Overriding the router implementation:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.core <span class="hljs-symbol">:as</span> r])
|
||||
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> router
|
||||
(<span class="hljs-name">r/router</span>
|
||||
[[<span class="hljs-string">"/ping"</span> <span class="hljs-symbol">::ping</span>]
|
||||
[<span class="hljs-string">"/api/:users"</span> <span class="hljs-symbol">::users</span>]]
|
||||
{<span class="hljs-symbol">:router</span> r/linear-router}))
|
||||
|
||||
(<span class="hljs-name">r/router-name</span> router)
|
||||
<span class="hljs-comment">; :linear-router</span>
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
|
@ -621,7 +633,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Different Routers","level":"1.4.2","depth":2,"next":{"title":"Route Validation","level":"1.4.3","depth":2,"path":"advanced/route_validation.md","ref":"advanced/route_validation.md","articles":[]},"previous":{"title":"Configuring Routers","level":"1.4.1","depth":2,"path":"advanced/configuring_routers.md","ref":"advanced/configuring_routers.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":"advanced/different_routers.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Different Routers","level":"1.4.2","depth":2,"next":{"title":"Route Validation","level":"1.4.3","depth":2,"path":"advanced/route_validation.md","ref":"advanced/route_validation.md","articles":[]},"previous":{"title":"Configuring Routers","level":"1.4.1","depth":2,"path":"advanced/configuring_routers.md","ref":"advanced/configuring_routers.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":"advanced/different_routers.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -584,7 +584,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Advanced","level":"1.4","depth":1,"next":{"title":"Configuring Routers","level":"1.4.1","depth":2,"path":"advanced/configuring_routers.md","ref":"advanced/configuring_routers.md","articles":[]},"previous":{"title":"Data-specs","level":"1.3.4","depth":2,"path":"coercion/data_spec_coercion.md","ref":"coercion/data_spec_coercion.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":"advanced/README.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Advanced","level":"1.4","depth":1,"next":{"title":"Configuring Routers","level":"1.4.1","depth":2,"path":"advanced/configuring_routers.md","ref":"advanced/configuring_routers.md","articles":[]},"previous":{"title":"Data-specs","level":"1.3.4","depth":2,"path":"coercion/data_spec_coercion.md","ref":"coercion/data_spec_coercion.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":"advanced/README.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -725,7 +725,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Validation","level":"1.4.3","depth":2,"next":{"title":"Ring","level":"1.5","depth":1,"path":"ring/README.md","ref":"ring/README.md","articles":[{"title":"Ring-router","level":"1.5.1","depth":2,"path":"ring/ring.md","ref":"ring/ring.md","articles":[]},{"title":"Dynamic Extensions","level":"1.5.2","depth":2,"path":"ring/dynamic_extensions.md","ref":"ring/dynamic_extensions.md","articles":[]},{"title":"Data-driven Middleware","level":"1.5.3","depth":2,"path":"ring/data_driven_middleware.md","ref":"ring/data_driven_middleware.md","articles":[]},{"title":"Pluggable Coercion","level":"1.5.4","depth":2,"path":"ring/coercion.md","ref":"ring/coercion.md","articles":[]},{"title":"Route Data Validation","level":"1.5.5","depth":2,"path":"ring/route_data_validation.md","ref":"ring/route_data_validation.md","articles":[]},{"title":"Compiling Middleware","level":"1.5.6","depth":2,"path":"ring/compiling_middleware.md","ref":"ring/compiling_middleware.md","articles":[]}]},"previous":{"title":"Different Routers","level":"1.4.2","depth":2,"path":"advanced/different_routers.md","ref":"advanced/different_routers.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":"advanced/route_validation.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Validation","level":"1.4.3","depth":2,"next":{"title":"Ring","level":"1.5","depth":1,"path":"ring/README.md","ref":"ring/README.md","articles":[{"title":"Ring-router","level":"1.5.1","depth":2,"path":"ring/ring.md","ref":"ring/ring.md","articles":[]},{"title":"Dynamic Extensions","level":"1.5.2","depth":2,"path":"ring/dynamic_extensions.md","ref":"ring/dynamic_extensions.md","articles":[]},{"title":"Data-driven Middleware","level":"1.5.3","depth":2,"path":"ring/data_driven_middleware.md","ref":"ring/data_driven_middleware.md","articles":[]},{"title":"Pluggable Coercion","level":"1.5.4","depth":2,"path":"ring/coercion.md","ref":"ring/coercion.md","articles":[]},{"title":"Route Data Validation","level":"1.5.5","depth":2,"path":"ring/route_data_validation.md","ref":"ring/route_data_validation.md","articles":[]},{"title":"Compiling Middleware","level":"1.5.6","depth":2,"path":"ring/compiling_middleware.md","ref":"ring/compiling_middleware.md","articles":[]}]},"previous":{"title":"Different Routers","level":"1.4.2","depth":2,"path":"advanced/different_routers.md","ref":"advanced/different_routers.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":"advanced/route_validation.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -588,7 +588,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Basics","level":"1.2","depth":1,"next":{"title":"Route Syntax","level":"1.2.1","depth":2,"path":"basics/route_syntax.md","ref":"basics/route_syntax.md","articles":[]},"previous":{"title":"Introduction","level":"1.1","depth":1,"path":"README.md","ref":"README.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":"basics/README.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Basics","level":"1.2","depth":1,"next":{"title":"Route Syntax","level":"1.2.1","depth":2,"path":"basics/route_syntax.md","ref":"basics/route_syntax.md","articles":[]},"previous":{"title":"Introduction","level":"1.1","depth":1,"path":"README.md","ref":"README.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":"basics/README.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -542,9 +542,9 @@
|
|||
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> router
|
||||
(<span class="hljs-name">r/router</span>
|
||||
[[<span class="hljs-string">"/api"</span>
|
||||
[<span class="hljs-string">"/ping"</span> <span class="hljs-symbol">::ping</span>]
|
||||
[<span class="hljs-string">"/user/:id"</span> <span class="hljs-symbol">::user</span>]]]))
|
||||
[<span class="hljs-string">"/api"</span>
|
||||
[<span class="hljs-string">"/ping"</span> <span class="hljs-symbol">::ping</span>]
|
||||
[<span class="hljs-string">"/user/:id"</span> <span class="hljs-symbol">::user</span>]]))
|
||||
</code></pre>
|
||||
<p>Listing all route names:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">r/route-names</span> router)
|
||||
|
|
@ -628,7 +628,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Name-based Routing","level":"1.2.4","depth":2,"next":{"title":"Route Data","level":"1.2.5","depth":2,"path":"basics/route_data.md","ref":"basics/route_data.md","articles":[]},"previous":{"title":"Path-based Routing","level":"1.2.3","depth":2,"path":"basics/path_based_routing.md","ref":"basics/path_based_routing.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":"basics/name_based_routing.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Name-based Routing","level":"1.2.4","depth":2,"next":{"title":"Route Data","level":"1.2.5","depth":2,"path":"basics/route_data.md","ref":"basics/route_data.md","articles":[]},"previous":{"title":"Path-based Routing","level":"1.2.3","depth":2,"path":"basics/path_based_routing.md","ref":"basics/path_based_routing.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":"basics/name_based_routing.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -540,16 +540,16 @@
|
|||
<ul>
|
||||
<li><code>nil</code>, no match</li>
|
||||
<li><code>PartialMatch</code>, path matched, missing path-parameters (only in reverse-routing)</li>
|
||||
<li><code>Match</code>, exact match</li>
|
||||
<li><code>Match</code>, an exact match</li>
|
||||
</ul>
|
||||
<p>Given a router:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.core <span class="hljs-symbol">:as</span> r])
|
||||
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> router
|
||||
(<span class="hljs-name">r/router</span>
|
||||
[[<span class="hljs-string">"/api"</span>
|
||||
[<span class="hljs-string">"/ping"</span> <span class="hljs-symbol">::ping</span>]
|
||||
[<span class="hljs-string">"/user/:id"</span> <span class="hljs-symbol">::user</span>]]]))
|
||||
[<span class="hljs-string">"/api"</span>
|
||||
[<span class="hljs-string">"/ping"</span> <span class="hljs-symbol">::ping</span>]
|
||||
[<span class="hljs-string">"/user/:id"</span> <span class="hljs-symbol">::user</span>]]))
|
||||
</code></pre>
|
||||
<p>No match returns <code>nil</code>:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">r/match-by-path</span> router <span class="hljs-string">"/hello"</span>)
|
||||
|
|
@ -606,7 +606,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Path-based Routing","level":"1.2.3","depth":2,"next":{"title":"Name-based Routing","level":"1.2.4","depth":2,"path":"basics/name_based_routing.md","ref":"basics/name_based_routing.md","articles":[]},"previous":{"title":"Router","level":"1.2.2","depth":2,"path":"basics/router.md","ref":"basics/router.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":"basics/path_based_routing.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Path-based Routing","level":"1.2.3","depth":2,"next":{"title":"Name-based Routing","level":"1.2.4","depth":2,"path":"basics/name_based_routing.md","ref":"basics/name_based_routing.md","articles":[]},"previous":{"title":"Router","level":"1.2.2","depth":2,"path":"basics/router.md","ref":"basics/router.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":"basics/path_based_routing.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -623,7 +623,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Conflicts","level":"1.2.7","depth":2,"next":{"title":"Coercion","level":"1.3","depth":1,"path":"coercion/README.md","ref":"coercion/README.md","articles":[{"title":"Coercion Explained","level":"1.3.1","depth":2,"path":"coercion/coercion.md","ref":"coercion/coercion.md","articles":[]},{"title":"Plumatic Schema","level":"1.3.2","depth":2,"path":"coercion/schema_coercion.md","ref":"coercion/schema_coercion.md","articles":[]},{"title":"Clojure.spec","level":"1.3.3","depth":2,"path":"coercion/clojure_spec_coercion.md","ref":"coercion/clojure_spec_coercion.md","articles":[]},{"title":"Data-specs","level":"1.3.4","depth":2,"path":"coercion/data_spec_coercion.md","ref":"coercion/data_spec_coercion.md","articles":[]}]},"previous":{"title":"Route Data Validation","level":"1.2.6","depth":2,"path":"basics/route_data_validation.md","ref":"basics/route_data_validation.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":"basics/route_conflicts.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Conflicts","level":"1.2.7","depth":2,"next":{"title":"Coercion","level":"1.3","depth":1,"path":"coercion/README.md","ref":"coercion/README.md","articles":[{"title":"Coercion Explained","level":"1.3.1","depth":2,"path":"coercion/coercion.md","ref":"coercion/coercion.md","articles":[]},{"title":"Plumatic Schema","level":"1.3.2","depth":2,"path":"coercion/schema_coercion.md","ref":"coercion/schema_coercion.md","articles":[]},{"title":"Clojure.spec","level":"1.3.3","depth":2,"path":"coercion/clojure_spec_coercion.md","ref":"coercion/clojure_spec_coercion.md","articles":[]},{"title":"Data-specs","level":"1.3.4","depth":2,"path":"coercion/data_spec_coercion.md","ref":"coercion/data_spec_coercion.md","articles":[]}]},"previous":{"title":"Route Data Validation","level":"1.2.6","depth":2,"path":"basics/route_data_validation.md","ref":"basics/route_data_validation.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":"basics/route_conflicts.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -536,8 +536,8 @@
|
|||
<section class="normal markdown-section">
|
||||
|
||||
<h1 id="route-data">Route Data</h1>
|
||||
<p>Route data is the heart of this library. Routes can have any data attachted to them. Data is interpeted either by the client application or the <code>Router</code> via it's <code>:coerce</code> and <code>:compile</code> hooks. Together with <code>clojure.spec</code> -validation this enables co-existence of both <a href="https://youtu.be/x9pxbnFC4aQ?t=1907" target="_blank">adaptive and principled</a> components.</p>
|
||||
<p>Routes can have a non-sequential route argument that is expanded into route data map when a router is created.</p>
|
||||
<p>Route data is the core feature of reitit. Routes can have any map-like data attachted to them. This data is interpeted either by the client application or the <code>Router</code> via it's <code>:coerce</code> and <code>:compile</code> hooks. Route data format can be defined and validated with <code>clojure.spec</code> enabling a architecture of both <a href="https://youtu.be/x9pxbnFC4aQ?t=1907" target="_blank">adaptive and principled</a> components.</p>
|
||||
<p>Raw routes can have a non-sequential route argument that is expanded (via router <code>:expand</code> hook) into route data at router creation time. By default, Keywords are expanded into <code>:name</code> and functions into <code>:handler</code> keys.</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.core <span class="hljs-symbol">:as</span> r])
|
||||
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> router
|
||||
|
|
@ -553,15 +553,15 @@
|
|||
<span class="hljs-comment">; ["/pong" {:handler identity]}</span>
|
||||
<span class="hljs-comment">; ["/users" {:get {:roles #{:admin}</span>
|
||||
<span class="hljs-comment">; :handler identity}}]]</span>
|
||||
|
||||
(<span class="hljs-name">r/match-by-path</span> router <span class="hljs-string">"/ping"</span>)
|
||||
</code></pre>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">r/match-by-path</span> router <span class="hljs-string">"/ping"</span>)
|
||||
<span class="hljs-comment">; #Match{:template "/ping"</span>
|
||||
<span class="hljs-comment">; :data {:name :user/ping}</span>
|
||||
<span class="hljs-comment">; :result nil</span>
|
||||
<span class="hljs-comment">; :path-params {}</span>
|
||||
<span class="hljs-comment">; :path "/ping"}</span>
|
||||
|
||||
(<span class="hljs-name">r/match-by-name</span> router <span class="hljs-symbol">::ping</span>)
|
||||
</code></pre>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">r/match-by-name</span> router <span class="hljs-symbol">::ping</span>)
|
||||
<span class="hljs-comment">; #Match{:template "/ping"</span>
|
||||
<span class="hljs-comment">; :data {:name :user/ping}</span>
|
||||
<span class="hljs-comment">; :result nil</span>
|
||||
|
|
@ -591,27 +591,19 @@
|
|||
<span class="hljs-comment">; :roles #{:db-admin}}]]</span>
|
||||
</code></pre>
|
||||
<h2 id="expansion">Expansion</h2>
|
||||
<p>By default, <code>reitit/Expand</code> protocol is used to expand the route arguments. It expands keywords into <code>:name</code> and functions into <code>:handler</code> key in the route data map. It's easy to add custom expanders and one can chenge the whole expand implementation via <a href="../advanced/configuring_routers.html">router options</a>.</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> router
|
||||
(<span class="hljs-name">r/router</span>
|
||||
[[<span class="hljs-string">"/ping"</span> <span class="hljs-symbol">::ping</span>]
|
||||
[<span class="hljs-string">"/pong"</span> identity]
|
||||
[<span class="hljs-string">"/users"</span> {<span class="hljs-symbol">:get</span> {<span class="hljs-symbol">:roles</span> #{<span class="hljs-symbol">:admin</span>}
|
||||
<span class="hljs-symbol">:handler</span> identity}}]]))
|
||||
<p>By default, router <code>:expand</code> hook maps to <code>reitit.core/expand</code> function, backed by a <code>reitit.core/Expand</code> protocol. One can provide either a totally different function or add new implementations to that protocol. Expand implementations can be recursive.</p>
|
||||
<p>Naive example to add direct support for <code>java.io.File</code> route argument:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">extend-type</span></span> java.io.File
|
||||
r/Expand
|
||||
(<span class="hljs-name">expand</span> [file options]
|
||||
(<span class="hljs-name">r/expand</span>
|
||||
#(<span class="hljs-name"><span class="hljs-builtin-name">slurp</span></span> file)
|
||||
options)))
|
||||
|
||||
(<span class="hljs-name">r/routes</span> router)
|
||||
<span class="hljs-comment">; [["/ping" {:name :user/ping}]</span>
|
||||
<span class="hljs-comment">; ["/pong" {:handler identity]}</span>
|
||||
<span class="hljs-comment">; ["/users" {:get {:roles #{:admin}</span>
|
||||
<span class="hljs-comment">; :handler identity}}]]</span>
|
||||
|
||||
(<span class="hljs-name">r/match-by-path</span> router <span class="hljs-string">"/ping"</span>)
|
||||
<span class="hljs-comment">; #Match{:template "/ping"</span>
|
||||
<span class="hljs-comment">; :data {:name :user/ping}</span>
|
||||
<span class="hljs-comment">; :result nil</span>
|
||||
<span class="hljs-comment">; :path-params {}</span>
|
||||
<span class="hljs-comment">; :path "/ping"}</span>
|
||||
(<span class="hljs-name">r/router</span>
|
||||
[<span class="hljs-string">"/"</span> (<span class="hljs-name">java.io.File.</span> <span class="hljs-string">"index.html"</span>)])
|
||||
</code></pre>
|
||||
<p>See <a href="../advanced/configuring_routers.html">router options</a> for all available options.</p>
|
||||
|
||||
|
||||
</section>
|
||||
|
|
@ -655,7 +647,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Data","level":"1.2.5","depth":2,"next":{"title":"Route Data Validation","level":"1.2.6","depth":2,"path":"basics/route_data_validation.md","ref":"basics/route_data_validation.md","articles":[]},"previous":{"title":"Name-based Routing","level":"1.2.4","depth":2,"path":"basics/name_based_routing.md","ref":"basics/name_based_routing.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":"basics/route_data.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Data","level":"1.2.5","depth":2,"next":{"title":"Route Data Validation","level":"1.2.6","depth":2,"path":"basics/route_data_validation.md","ref":"basics/route_data_validation.md","articles":[]},"previous":{"title":"Name-based Routing","level":"1.2.4","depth":2,"path":"basics/name_based_routing.md","ref":"basics/name_based_routing.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":"basics/route_data.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -536,9 +536,9 @@
|
|||
<section class="normal markdown-section">
|
||||
|
||||
<h1 id="route-data-validation">Route Data Validation</h1>
|
||||
<p>Route data can be anything, so it's easy to do mistakes. Accidentally using a <code>:role</code> key instead of <code>:roles</code> might render the whole routing app without any authorization in place.</p>
|
||||
<p>Route data can be anything, so it's easy to do go wrong. Accidentally adding a <code>:role</code> key instead of <code>:roles</code> might hinder the whole routing app without any authorization in place.</p>
|
||||
<p>To fail fast, we could use the custom <code>:coerce</code> and <code>:compile</code> hooks to apply data validation and throw exceptions on first sighted problem.</p>
|
||||
<p>But there is a better way. Router also has a <code>:validation</code> hook to validate the whole route tree after it's successfuly compiled. It expects a 2-arity function <code>routes opts => ()</code> that can side-effect in case of validation errors.</p>
|
||||
<p>But there is a better way. Router has a <code>:validation</code> hook to validate the whole route tree after it's successfuly compiled. It expects a 2-arity function <code>routes opts => ()</code> that can side-effect in case of validation errors.</p>
|
||||
<h2 id="clojurespec">clojure.spec</h2>
|
||||
<p>Namespace <code>reitit.spec</code> contains specs for main parts of <code>reitit.core</code> and a helper function <code>validate-spec!</code> that runs spec validation for all route data and throws an exception if any errors are found.</p>
|
||||
<p>A Router with invalid route data:</p>
|
||||
|
|
@ -633,27 +633,27 @@
|
|||
<span class="hljs-symbol">::rs/explain</span> e/expound-str
|
||||
<span class="hljs-symbol">:validate</span> rs/validate-spec!})
|
||||
<span class="hljs-comment">; CompilerException clojure.lang.ExceptionInfo: Invalid route data:</span>
|
||||
<span class="hljs-comment">; </span>
|
||||
<span class="hljs-comment">;</span>
|
||||
<span class="hljs-comment">; -- On route -----------------------</span>
|
||||
<span class="hljs-comment">; </span>
|
||||
<span class="hljs-comment">;</span>
|
||||
<span class="hljs-comment">; "/api"</span>
|
||||
<span class="hljs-comment">; </span>
|
||||
<span class="hljs-comment">;</span>
|
||||
<span class="hljs-comment">; -- Spec failed --------------------</span>
|
||||
<span class="hljs-comment">; </span>
|
||||
<span class="hljs-comment">;</span>
|
||||
<span class="hljs-comment">; {:handler</span>
|
||||
<span class="hljs-comment">; #object[clojure.core$identity 0x15b59b0e "clojure.core$identity@15b59b0e"]}</span>
|
||||
<span class="hljs-comment">; </span>
|
||||
<span class="hljs-comment">;</span>
|
||||
<span class="hljs-comment">; should contain key: `:user/roles`</span>
|
||||
<span class="hljs-comment">; </span>
|
||||
<span class="hljs-comment">;</span>
|
||||
<span class="hljs-comment">; | key | spec |</span>
|
||||
<span class="hljs-comment">; |-------------+----------------------------------------|</span>
|
||||
<span class="hljs-comment">; | :user/roles | (coll-of #{:admin :manager} :into #{}) |</span>
|
||||
<span class="hljs-comment">; </span>
|
||||
<span class="hljs-comment">; </span>
|
||||
<span class="hljs-comment">; </span>
|
||||
<span class="hljs-comment">;</span>
|
||||
<span class="hljs-comment">;</span>
|
||||
<span class="hljs-comment">;</span>
|
||||
<span class="hljs-comment">; -------------------------</span>
|
||||
<span class="hljs-comment">; Detected 1 error</span>
|
||||
<span class="hljs-comment">; </span>
|
||||
<span class="hljs-comment">;</span>
|
||||
<span class="hljs-comment">; {:problems (#reitit.spec.Problem{:path "/api", :scope nil, :data {:handler #object[clojure.core$identity 0x15b59b0e "clojure.core$identity@15b59b0e"]}, :spec #object[clojure.spec.alpha$merge_spec_impl$reify__2124 0x7461744b "clojure.spec.alpha$merge_spec_impl$reify__2124@7461744b"], :problems #:clojure.spec.alpha{:problems ({:path [], :pred (clojure.core/fn [%] (clojure.core/contains? % :user/roles)), :val {:handler #object[clojure.core$identity 0x15b59b0e "clojure.core$identity@15b59b0e"]}, :via [], :in []}), :spec #object[clojure.spec.alpha$merge_spec_impl$reify__2124 0x7461744b "clojure.spec.alpha$merge_spec_impl$reify__2124@7461744b"], :value {:handler #object[clojure.core$identity 0x15b59b0e "clojure.core$identity@15b59b0e"]}}})}, compiling:(/Users/tommi/projects/metosin/reitit/test/cljc/reitit/spec_test.cljc:151:1)</span>
|
||||
</code></pre>
|
||||
|
||||
|
|
@ -699,7 +699,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Data Validation","level":"1.2.6","depth":2,"next":{"title":"Route Conflicts","level":"1.2.7","depth":2,"path":"basics/route_conflicts.md","ref":"basics/route_conflicts.md","articles":[]},"previous":{"title":"Route Data","level":"1.2.5","depth":2,"path":"basics/route_data.md","ref":"basics/route_data.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":"basics/route_data_validation.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Data Validation","level":"1.2.6","depth":2,"next":{"title":"Route Conflicts","level":"1.2.7","depth":2,"path":"basics/route_conflicts.md","ref":"basics/route_conflicts.md","articles":[]},"previous":{"title":"Route Data","level":"1.2.5","depth":2,"path":"basics/route_data.md","ref":"basics/route_data.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":"basics/route_data_validation.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -571,27 +571,24 @@
|
|||
[<span class="hljs-string">"/api/ping"</span> {<span class="hljs-symbol">:name</span> <span class="hljs-symbol">::ping</span>}]]
|
||||
</code></pre>
|
||||
<h3 id="generating-routes">Generating routes</h3>
|
||||
<p>As routes are just data, it's easy to create them programmatically:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">defn</span></span> cqrs-routes [actions dev-mode?]
|
||||
<p>Routes are just data, so it's easy to create them programmatically:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">defn</span></span> cqrs-routes [actions]
|
||||
[<span class="hljs-string">"/api"</span> {<span class="hljs-symbol">:interceptors</span> [<span class="hljs-symbol">::api</span> <span class="hljs-symbol">::db</span>]}
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">for</span></span> [[type interceptor] actions
|
||||
<span class="hljs-symbol">:let</span> [path (<span class="hljs-name"><span class="hljs-builtin-name">str</span></span> <span class="hljs-string">"/"</span> (<span class="hljs-name"><span class="hljs-builtin-name">name</span></span> interceptor))
|
||||
method (<span class="hljs-name"><span class="hljs-builtin-name">condp</span></span> = type
|
||||
<span class="hljs-symbol">:query</span> <span class="hljs-symbol">:get</span>
|
||||
<span class="hljs-symbol">:command</span> <span class="hljs-symbol">:post</span>)]]
|
||||
[path {method {<span class="hljs-symbol">:interceptors</span> [interceptor]}}])
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">if</span></span> dev-mode? [<span class="hljs-string">"/dev-tools"</span> <span class="hljs-symbol">::dev-tools</span>])])
|
||||
[path {method {<span class="hljs-symbol">:interceptors</span> [interceptor]}}])])
|
||||
</code></pre>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">cqrs-routes</span>
|
||||
[[<span class="hljs-symbol">:query</span> 'get-user]
|
||||
[<span class="hljs-symbol">:command</span> 'add-user]
|
||||
[<span class="hljs-symbol">:command</span> 'add-order]]
|
||||
<span class="hljs-literal">false</span>)
|
||||
[<span class="hljs-symbol">:command</span> 'add-order]])
|
||||
<span class="hljs-comment">; ["/api" {:interceptors [::api ::db]}</span>
|
||||
<span class="hljs-comment">; (["/get-user" {:get {:interceptors [get-user]}}]</span>
|
||||
<span class="hljs-comment">; ["/add-user" {:post {:interceptors [add-user]}}]</span>
|
||||
<span class="hljs-comment">; ["/add-order" {:post {:interceptors [add-order]}}])</span>
|
||||
<span class="hljs-comment">; nil]</span>
|
||||
<span class="hljs-comment">; ["/add-order" {:post {:interceptors [add-order]}}])]</span>
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
|
@ -636,7 +633,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Syntax","level":"1.2.1","depth":2,"next":{"title":"Router","level":"1.2.2","depth":2,"path":"basics/router.md","ref":"basics/router.md","articles":[]},"previous":{"title":"Basics","level":"1.2","depth":1,"path":"basics/README.md","ref":"basics/README.md","articles":[{"title":"Route Syntax","level":"1.2.1","depth":2,"path":"basics/route_syntax.md","ref":"basics/route_syntax.md","articles":[]},{"title":"Router","level":"1.2.2","depth":2,"path":"basics/router.md","ref":"basics/router.md","articles":[]},{"title":"Path-based Routing","level":"1.2.3","depth":2,"path":"basics/path_based_routing.md","ref":"basics/path_based_routing.md","articles":[]},{"title":"Name-based Routing","level":"1.2.4","depth":2,"path":"basics/name_based_routing.md","ref":"basics/name_based_routing.md","articles":[]},{"title":"Route Data","level":"1.2.5","depth":2,"path":"basics/route_data.md","ref":"basics/route_data.md","articles":[]},{"title":"Route Data Validation","level":"1.2.6","depth":2,"path":"basics/route_data_validation.md","ref":"basics/route_data_validation.md","articles":[]},{"title":"Route Conflicts","level":"1.2.7","depth":2,"path":"basics/route_conflicts.md","ref":"basics/route_conflicts.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":"basics/route_syntax.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Syntax","level":"1.2.1","depth":2,"next":{"title":"Router","level":"1.2.2","depth":2,"path":"basics/router.md","ref":"basics/router.md","articles":[]},"previous":{"title":"Basics","level":"1.2","depth":1,"path":"basics/README.md","ref":"basics/README.md","articles":[{"title":"Route Syntax","level":"1.2.1","depth":2,"path":"basics/route_syntax.md","ref":"basics/route_syntax.md","articles":[]},{"title":"Router","level":"1.2.2","depth":2,"path":"basics/router.md","ref":"basics/router.md","articles":[]},{"title":"Path-based Routing","level":"1.2.3","depth":2,"path":"basics/path_based_routing.md","ref":"basics/path_based_routing.md","articles":[]},{"title":"Name-based Routing","level":"1.2.4","depth":2,"path":"basics/name_based_routing.md","ref":"basics/name_based_routing.md","articles":[]},{"title":"Route Data","level":"1.2.5","depth":2,"path":"basics/route_data.md","ref":"basics/route_data.md","articles":[]},{"title":"Route Data Validation","level":"1.2.6","depth":2,"path":"basics/route_data_validation.md","ref":"basics/route_data_validation.md","articles":[]},{"title":"Route Conflicts","level":"1.2.7","depth":2,"path":"basics/route_conflicts.md","ref":"basics/route_conflicts.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":"basics/route_syntax.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -536,7 +536,7 @@
|
|||
<section class="normal markdown-section">
|
||||
|
||||
<h1 id="router">Router</h1>
|
||||
<p>Routes are just data and for routing, we need a router instance satisfying the <code>reitit.core/Router</code> protocol. Routers are created with <code>reitit.core/router</code> function, taking the raw routes and optionally an options map.</p>
|
||||
<p>Routes are just data and to do routing, we need a router instance satisfying the <code>reitit.core/Router</code> protocol. Routers are created with <code>reitit.core/router</code> function, taking the raw routes and optionally an options map.</p>
|
||||
<p>The <code>Router</code> protocol:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">defprotocol</span></span> Router
|
||||
(<span class="hljs-name">router-name</span> [this])
|
||||
|
|
@ -551,9 +551,9 @@
|
|||
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> router
|
||||
(<span class="hljs-name">r/router</span>
|
||||
[[<span class="hljs-string">"/api"</span>
|
||||
[<span class="hljs-string">"/ping"</span> <span class="hljs-symbol">::ping</span>]
|
||||
[<span class="hljs-string">"/user/:id"</span> <span class="hljs-symbol">::user</span>]]]))
|
||||
[<span class="hljs-string">"/api"</span>
|
||||
[<span class="hljs-string">"/ping"</span> <span class="hljs-symbol">::ping</span>]
|
||||
[<span class="hljs-string">"/user/:id"</span> <span class="hljs-symbol">::user</span>]]))
|
||||
</code></pre>
|
||||
<p>Name of the created router:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">r/router-name</span> router)
|
||||
|
|
@ -570,8 +570,8 @@
|
|||
<li>route tree is flattened</li>
|
||||
<li>route arguments are expanded (via <code>reitit.core/Expand</code> protocol) and optionally coerced</li>
|
||||
<li><a href="advanced/route_conflicts.md">route conflicts</a> are resolved</li>
|
||||
<li>route tree is compiled</li>
|
||||
<li>actual <a href="../advanced/different_routers.html">router implementation</a> is selected and created</li>
|
||||
<li>optionally route data gets compiled</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
|
@ -616,7 +616,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Router","level":"1.2.2","depth":2,"next":{"title":"Path-based Routing","level":"1.2.3","depth":2,"path":"basics/path_based_routing.md","ref":"basics/path_based_routing.md","articles":[]},"previous":{"title":"Route Syntax","level":"1.2.1","depth":2,"path":"basics/route_syntax.md","ref":"basics/route_syntax.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":"basics/router.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Router","level":"1.2.2","depth":2,"next":{"title":"Path-based Routing","level":"1.2.3","depth":2,"path":"basics/path_based_routing.md","ref":"basics/path_based_routing.md","articles":[]},"previous":{"title":"Route Syntax","level":"1.2.1","depth":2,"path":"basics/route_syntax.md","ref":"basics/route_syntax.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":"basics/router.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -618,7 +618,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Clojure.spec","level":"1.3.3","depth":2,"next":{"title":"Data-specs","level":"1.3.4","depth":2,"path":"coercion/data_spec_coercion.md","ref":"coercion/data_spec_coercion.md","articles":[]},"previous":{"title":"Plumatic Schema","level":"1.3.2","depth":2,"path":"coercion/schema_coercion.md","ref":"coercion/schema_coercion.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":"coercion/clojure_spec_coercion.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Clojure.spec","level":"1.3.3","depth":2,"next":{"title":"Data-specs","level":"1.3.4","depth":2,"path":"coercion/data_spec_coercion.md","ref":"coercion/data_spec_coercion.md","articles":[]},"previous":{"title":"Plumatic Schema","level":"1.3.2","depth":2,"path":"coercion/schema_coercion.md","ref":"coercion/schema_coercion.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":"coercion/clojure_spec_coercion.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -537,14 +537,14 @@
|
|||
|
||||
<h1 id="coercion-explained">Coercion Explained</h1>
|
||||
<p>Coercion is a process of transforming parameters (and responses) from one format into another. Reitit separates routing and coercion into two separate steps.</p>
|
||||
<p>By default, all wildcard and catch-all parameters are parsed as Strings:</p>
|
||||
<p>By default, all wildcard and catch-all parameters are parsed into strings:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.core <span class="hljs-symbol">:as</span> r])
|
||||
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> router
|
||||
(<span class="hljs-name">r/router</span>
|
||||
[<span class="hljs-string">"/:company/users/:user-id"</span> <span class="hljs-symbol">::user-view</span>]))
|
||||
</code></pre>
|
||||
<p>Match with the parsed <code>:params</code> as Strings:</p>
|
||||
<p>Match with the parsed <code>:path-params</code> as strings:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">r/match-by-path</span> r <span class="hljs-string">"/metosin/users/123"</span>)
|
||||
<span class="hljs-comment">; #Match{:template "/:company/users/:user-id",</span>
|
||||
<span class="hljs-comment">; :data {:name :user/user-view},</span>
|
||||
|
|
@ -591,10 +591,10 @@
|
|||
<span class="hljs-comment">; :path-params {:company "metosin", :user-id "123"},</span>
|
||||
<span class="hljs-comment">; :path "/metosin/users/123"}</span>
|
||||
</code></pre>
|
||||
<p>Coercion was not applied. Why? In Reitit, routing and coercion are separate processes and we haven't applied the coercion yet. We need to apply it ourselves after the successfull routing.</p>
|
||||
<p>Coercion was not applied. Why? In Reitit, routing and coercion are separate processes and we have done just the routing part. We need to apply coercion after the successful routing.</p>
|
||||
<p>But now we should have enough data on the match to apply the coercion.</p>
|
||||
<h2 id="compiling-coercers">Compiling coercers</h2>
|
||||
<p>Before the actual coercion, we need to compile the coercers against the route data. Compiled coercers yield much better performance and the manual step of adding a coercion compiler makes things explicit and non-magical.</p>
|
||||
<p>Before the actual coercion, we <del>should</del> need to compile the coercers against the route data. Compiled coercers yield much better performance and the manual step of adding a coercion compiler makes things explicit and non-magical.</p>
|
||||
<p>Compiling can be done via a Middleware, Interceptor or a Router. We apply it now at router-level, effecting all routes (with <code>:parameters</code> and <code>:coercion</code> defined).</p>
|
||||
<p>There is a helper function <code>reitit.coercion/compile-request-coercers</code> just for this:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.coercion <span class="hljs-symbol">:as</span> coercion])
|
||||
|
|
@ -670,12 +670,6 @@
|
|||
</code></pre>
|
||||
<h2 id="ring-coercion">Ring Coercion</h2>
|
||||
<p>For a full-blown http-coercion, see the <a href="../ring/coercion.html">ring coercion</a>.</p>
|
||||
<h2 id="thanks-to">Thanks to</h2>
|
||||
<ul>
|
||||
<li><a href="https://clojars.org/metosin/compojure-api" target="_blank">compojure-api</a> for the initial <code>Coercion</code> protocol</li>
|
||||
<li><a href="https://github.com/plumatic/schema" target="_blank">schema</a> and <a href="https://github.com/metosin/schema-tools" target="_blank">schema-tools</a> for Schema Coercion</li>
|
||||
<li><a href="https://github.com/metosin/spec-tools" target="_blank">spec-tools</a> for Spec Coercion</li>
|
||||
</ul>
|
||||
|
||||
|
||||
</section>
|
||||
|
|
@ -719,7 +713,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Coercion Explained","level":"1.3.1","depth":2,"next":{"title":"Plumatic Schema","level":"1.3.2","depth":2,"path":"coercion/schema_coercion.md","ref":"coercion/schema_coercion.md","articles":[]},"previous":{"title":"Coercion","level":"1.3","depth":1,"path":"coercion/README.md","ref":"coercion/README.md","articles":[{"title":"Coercion Explained","level":"1.3.1","depth":2,"path":"coercion/coercion.md","ref":"coercion/coercion.md","articles":[]},{"title":"Plumatic Schema","level":"1.3.2","depth":2,"path":"coercion/schema_coercion.md","ref":"coercion/schema_coercion.md","articles":[]},{"title":"Clojure.spec","level":"1.3.3","depth":2,"path":"coercion/clojure_spec_coercion.md","ref":"coercion/clojure_spec_coercion.md","articles":[]},{"title":"Data-specs","level":"1.3.4","depth":2,"path":"coercion/data_spec_coercion.md","ref":"coercion/data_spec_coercion.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":"coercion/coercion.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Coercion Explained","level":"1.3.1","depth":2,"next":{"title":"Plumatic Schema","level":"1.3.2","depth":2,"path":"coercion/schema_coercion.md","ref":"coercion/schema_coercion.md","articles":[]},"previous":{"title":"Coercion","level":"1.3","depth":1,"path":"coercion/README.md","ref":"coercion/README.md","articles":[{"title":"Coercion Explained","level":"1.3.1","depth":2,"path":"coercion/coercion.md","ref":"coercion/coercion.md","articles":[]},{"title":"Plumatic Schema","level":"1.3.2","depth":2,"path":"coercion/schema_coercion.md","ref":"coercion/schema_coercion.md","articles":[]},{"title":"Clojure.spec","level":"1.3.3","depth":2,"path":"coercion/clojure_spec_coercion.md","ref":"coercion/clojure_spec_coercion.md","articles":[]},{"title":"Data-specs","level":"1.3.4","depth":2,"path":"coercion/data_spec_coercion.md","ref":"coercion/data_spec_coercion.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":"coercion/coercion.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -612,7 +612,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Data-specs","level":"1.3.4","depth":2,"next":{"title":"Advanced","level":"1.4","depth":1,"path":"advanced/README.md","ref":"advanced/README.md","articles":[{"title":"Configuring Routers","level":"1.4.1","depth":2,"path":"advanced/configuring_routers.md","ref":"advanced/configuring_routers.md","articles":[]},{"title":"Different Routers","level":"1.4.2","depth":2,"path":"advanced/different_routers.md","ref":"advanced/different_routers.md","articles":[]},{"title":"Route Validation","level":"1.4.3","depth":2,"path":"advanced/route_validation.md","ref":"advanced/route_validation.md","articles":[]}]},"previous":{"title":"Clojure.spec","level":"1.3.3","depth":2,"path":"coercion/clojure_spec_coercion.md","ref":"coercion/clojure_spec_coercion.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":"coercion/data_spec_coercion.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Data-specs","level":"1.3.4","depth":2,"next":{"title":"Advanced","level":"1.4","depth":1,"path":"advanced/README.md","ref":"advanced/README.md","articles":[{"title":"Configuring Routers","level":"1.4.1","depth":2,"path":"advanced/configuring_routers.md","ref":"advanced/configuring_routers.md","articles":[]},{"title":"Different Routers","level":"1.4.2","depth":2,"path":"advanced/different_routers.md","ref":"advanced/different_routers.md","articles":[]},{"title":"Route Validation","level":"1.4.3","depth":2,"path":"advanced/route_validation.md","ref":"advanced/route_validation.md","articles":[]}]},"previous":{"title":"Clojure.spec","level":"1.3.3","depth":2,"path":"coercion/clojure_spec_coercion.md","ref":"coercion/clojure_spec_coercion.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":"coercion/data_spec_coercion.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -585,7 +585,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Coercion","level":"1.3","depth":1,"next":{"title":"Coercion Explained","level":"1.3.1","depth":2,"path":"coercion/coercion.md","ref":"coercion/coercion.md","articles":[]},"previous":{"title":"Route Conflicts","level":"1.2.7","depth":2,"path":"basics/route_conflicts.md","ref":"basics/route_conflicts.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":"coercion/README.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Coercion","level":"1.3","depth":1,"next":{"title":"Coercion Explained","level":"1.3.1","depth":2,"path":"coercion/coercion.md","ref":"coercion/coercion.md","articles":[]},"previous":{"title":"Route Conflicts","level":"1.2.7","depth":2,"path":"basics/route_conflicts.md","ref":"basics/route_conflicts.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":"coercion/README.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -613,7 +613,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Plumatic Schema","level":"1.3.2","depth":2,"next":{"title":"Clojure.spec","level":"1.3.3","depth":2,"path":"coercion/clojure_spec_coercion.md","ref":"coercion/clojure_spec_coercion.md","articles":[]},"previous":{"title":"Coercion Explained","level":"1.3.1","depth":2,"path":"coercion/coercion.md","ref":"coercion/coercion.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":"coercion/schema_coercion.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Plumatic Schema","level":"1.3.2","depth":2,"next":{"title":"Clojure.spec","level":"1.3.3","depth":2,"path":"coercion/clojure_spec_coercion.md","ref":"coercion/clojure_spec_coercion.md","articles":[]},"previous":{"title":"Coercion Explained","level":"1.3.1","depth":2,"path":"coercion/coercion.md","ref":"coercion/coercion.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":"coercion/schema_coercion.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
169
faq.html
169
faq.html
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
|
||||
|
||||
<link rel="prev" href="performance.html" />
|
||||
<link rel="prev" href="openapi.html" />
|
||||
|
||||
|
||||
</head>
|
||||
|
|
@ -436,33 +436,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="interceptors.html">
|
||||
|
||||
<a href="interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="openapi.html">
|
||||
|
||||
<a href="openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="performance.html">
|
||||
|
||||
<a href="performance.html">
|
||||
|
||||
|
|
@ -473,6 +447,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="interceptors.html">
|
||||
|
||||
<a href="interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="openapi.html">
|
||||
|
||||
<a href="openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter active" data-level="1.9" data-path="faq.html">
|
||||
|
|
@ -534,9 +534,114 @@
|
|||
<section class="normal markdown-section">
|
||||
|
||||
<h1 id="frequently-asked-questions">Frequently Asked Questions</h1>
|
||||
<ul>
|
||||
<li><a href="#why-yet-another-routing-library">Why yet another routing library?</a></li>
|
||||
<li><a href="#how-can-i-contribute">How can I contribute?</a></li>
|
||||
<li><a href="#how-does-reitit-differ-from-bidi">How does Reitit differ from Bidi?</a></li>
|
||||
<li><a href="#how-does-reitit-differ-from-pedestal">How does Reitit differ from Pedestal?</a></li>
|
||||
<li><a href="#how-does-reitit-differ-from-compojure">How does Reitit differ from Compojure?</a></li>
|
||||
</ul>
|
||||
<h3 id="why-yet-another-routing-library">Why yet another routing library?</h3>
|
||||
<p>There are many great routing libs for Clojure, but we felt that none was perfect. We picked
|
||||
best parts of existing libs, added things that were missing (like first-class route data, spec-coercion and full route conflict resolution) trying to make a library it both both fun to use and really, really fast.</p>
|
||||
<p>Routing and dispatching is in the core of most business apps, so we should have a great library to for it. There are already many good routing libs for Clojure, but we felt none was perfect. So, we took best parts of existing libs and added features that were missing: first-class composable route data, full route conflict resolution and pluggable coercion. Goal was to make a data-driven library that works, is fun to use and is really, really fast.</p>
|
||||
<h3 id="how-can-i-contribute">How can I contribute?</h3>
|
||||
<p>You can join <a href="https://clojurians.slack.com/messages/reitit/" target="_blank">#reitit</a> channel in <a href="http://clojurians.net/" target="_blank">Clojurians slack</a> to discuss things. Known roadmap is mostly written in <a href="https://github.com/metosin/reitit/issues" target="_blank">issues</a>, and many issues are marked already with "Help wanted".</p>
|
||||
<h3 id="how-does-reitit-differ-from-bidi">How does Reitit differ from Bidi?</h3>
|
||||
<p><a href="https://github.com/juxt/bidi" target="_blank">Bidi</a> is an great and proven library for ClojureScript and we have been using it in many of our frontend projects. Both Reitit and Bidi are data-driven, bi-directional and work with both Clojure & ClojureScript. Here are the main differences:</p>
|
||||
<h4 id="route-syntax">Route syntax</h4>
|
||||
<ul>
|
||||
<li>Bidi supports multiple representations for route syntax, Reitit supports just one (simple) syntax.</li>
|
||||
<li>Bidi uses special (Clojure) syntax for route patterns while Reitit separates (human-readable) paths strings from route data - still exposing the machine-readable syntax for extensions.</li>
|
||||
</ul>
|
||||
<p>Bidi:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> routes
|
||||
[<span class="hljs-string">"/"</span> [[<span class="hljs-string">"auth/login"</span> <span class="hljs-symbol">:auth/login</span>]
|
||||
[[<span class="hljs-string">"auth/recovery/token/"</span> <span class="hljs-symbol">:token</span>] <span class="hljs-symbol">:auth/recovery</span>]
|
||||
[<span class="hljs-string">"workspace/"</span> [[[<span class="hljs-symbol">:project-uuid</span> <span class="hljs-string">"/"</span> <span class="hljs-symbol">:page-uuid</span>] <span class="hljs-symbol">:workspace/page</span>]]]]])
|
||||
</code></pre>
|
||||
<p>Reitit:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> routes
|
||||
[[<span class="hljs-string">"/auth/login"</span> <span class="hljs-symbol">:auth/login</span>]
|
||||
[<span class="hljs-string">"/auth/recovery/token/:token"</span> <span class="hljs-symbol">:auth/recovery</span>]
|
||||
[<span class="hljs-string">"/workspace/:project-uuid/:page-uuid"</span> <span class="hljs-symbol">:workspace/page</span>]])
|
||||
</code></pre>
|
||||
<h4 id="features">Features</h4>
|
||||
<ul>
|
||||
<li>Bidi has extra features like route guards</li>
|
||||
<li>Reitit ships with composable route data, specs, full route conflict resolution and pluggable coercion.</li>
|
||||
</ul>
|
||||
<h4 id="performance">Performance</h4>
|
||||
<ul>
|
||||
<li>Bidi is not optimized for speed and thus, Reitit is <a href="performance.html">orders of magnitude faster</a> than Bidi. From Bidi source:</li>
|
||||
</ul>
|
||||
<pre><code class="lang-clj"><span class="hljs-comment">;; Route compilation was only marginally effective and hard to</span>
|
||||
<span class="hljs-comment">;; debug. When bidi matching takes in the order of 30 micro-seconds,</span>
|
||||
<span class="hljs-comment">;; this is good enough in relation to the time taken to process the</span>
|
||||
<span class="hljs-comment">;; overall request.</span>
|
||||
</code></pre>
|
||||
<h3 id="how-does-reitit-differ-from-pedestal">How does Reitit differ from Pedestal?</h3>
|
||||
<p><a href="http://pedestal.io/" target="_blank">Pedestal</a> is an great and proven library and has had great influence in Reitit. Both Reitit and Pedestal are data-driven and provide bi-directional routing and fast. Here are the main differences:</p>
|
||||
<h4 id="clojurescript">ClojureScript</h4>
|
||||
<ul>
|
||||
<li>Pedestal targets only Clojure, while Reitit works also with ClojureScript.</li>
|
||||
</ul>
|
||||
<h4 id="route-syntax">Route syntax</h4>
|
||||
<ul>
|
||||
<li>Pedestal supports multiple representations for route syntax: terse, table and verbose. Reitit provides only one representation.</li>
|
||||
<li>Pedestal supports both maps or keyword-arguments in route data, in Reitit, it's all maps.</li>
|
||||
</ul>
|
||||
<p>Pedestal:</p>
|
||||
<pre><code class="lang-clj">[<span class="hljs-string">"/api/ping"</span> <span class="hljs-symbol">:get</span> identity <span class="hljs-symbol">:route-name</span> <span class="hljs-symbol">::ping</span>]
|
||||
</code></pre>
|
||||
<p>Reitit:</p>
|
||||
<pre><code class="lang-clj">[<span class="hljs-string">"/api/ping"</span> {<span class="hljs-symbol">:get</span> identity, <span class="hljs-symbol">:name</span> <span class="hljs-symbol">::ping</span>}]
|
||||
</code></pre>
|
||||
<h4 id="features">Features</h4>
|
||||
<ul>
|
||||
<li>Pedestal supports route guards</li>
|
||||
<li>Pedestal supports interceptors (<code>reitit-http</code> module will support them too).</li>
|
||||
<li>Reitit ships with composable route data, specs, full route conflict resolution and pluggable coercion.</li>
|
||||
<li>In Pedestal, different routers <a href="https://github.com/pedestal/pedestal/issues/532" target="_blank">behave differently</a>, in Reitit, all work the same.</li>
|
||||
</ul>
|
||||
<h4 id="performance">Performance</h4>
|
||||
<p>Reitit routing was originally based on Pedestal Routing an thus they same similar performance. For routing trees with both static and wildcard routes, Reitit is much faster thanks to it's <code>mixed-router</code> algorithm.</p>
|
||||
<h3 id="how-does-reitit-differ-from-compojure">How does Reitit differ from Compojure?</h3>
|
||||
<p><a href="https://github.com/weavejester/compojure" target="_blank">Compojure</a> is the most used routing library in Clojure. It's proven and awesome.</p>
|
||||
<h4 id="clojurescript">ClojureScript</h4>
|
||||
<ul>
|
||||
<li>Compojure targets only Clojure, while Reitit works also with ClojureScript.</li>
|
||||
</ul>
|
||||
<h4 id="route-syntax">Route syntax</h4>
|
||||
<ul>
|
||||
<li>Compojure uses routing functions and macros while reitit is all data</li>
|
||||
<li>Compojure allows easy destructuring of route params on mid-path</li>
|
||||
<li>Applying middleware for sub-paths is hacky on Compojure, <code>reitit-ring</code> resolves this with data-driven middleware</li>
|
||||
</ul>
|
||||
<p>Compojure:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">defroutes</span> routes
|
||||
(<span class="hljs-name">wrap-routes</span>
|
||||
(<span class="hljs-name">context</span> <span class="hljs-string">"/api"</span> []
|
||||
(<span class="hljs-name">GET</span> <span class="hljs-string">"/users/:id"</span> [id <span class="hljs-symbol">:<<</span> as-int]
|
||||
(<span class="hljs-name">ok</span> (<span class="hljs-name">get-user</span> id)))
|
||||
(<span class="hljs-name">POST</span> <span class="hljs-string">"/pizza"</span> []
|
||||
(<span class="hljs-name">wrap-log</span> post-pizza-handler)))
|
||||
wrap-api <span class="hljs-symbol">:secure</span>))
|
||||
</code></pre>
|
||||
<p><code>reitit-ring</code> with <code>reitit-spec</code> module:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> routes
|
||||
[<span class="hljs-string">"/api"</span> {<span class="hljs-symbol">:middleware</span> [[wrap-api <span class="hljs-symbol">:secure</span>]]}
|
||||
[<span class="hljs-string">"/users/:id"</span> {<span class="hljs-symbol">:get</span> {<span class="hljs-symbol">:parameters</span> {<span class="hljs-symbol">:path</span> {<span class="hljs-symbol">:id</span> int?}}}
|
||||
<span class="hljs-symbol">:handler</span> (<span class="hljs-name"><span class="hljs-builtin-name">fn</span></span> [{<span class="hljs-symbol">:keys</span> [parameters]}]
|
||||
(<span class="hljs-name">ok</span> (<span class="hljs-name">get-user</span> (<span class="hljs-name"><span class="hljs-builtin-name">-></span></span> parameters <span class="hljs-symbol">:body</span> <span class="hljs-symbol">:id</span>))))}
|
||||
[<span class="hljs-string">"/pizza"</span> {<span class="hljs-symbol">:post</span> {<span class="hljs-symbol">:middleware</span> [wrap-log]
|
||||
<span class="hljs-symbol">:handler</span> post-pizza-handler}]]])
|
||||
</code></pre>
|
||||
<h4 id="features">Features</h4>
|
||||
<ul>
|
||||
<li>Dynamic routing is trivial in Compojure, with reitit, some trickery is needed</li>
|
||||
<li>Reitit ships with composable route data, specs, full route conflict resolution and pluggable coercion.</li>
|
||||
</ul>
|
||||
<h4 id="performance">Performance</h4>
|
||||
<p>Reitit is <a href="performance.html">orders of magnitude faster</a> than Compojure.</p>
|
||||
|
||||
|
||||
</section>
|
||||
|
|
@ -564,7 +669,7 @@ best parts of existing libs, added things that were missing (like first-class ro
|
|||
|
||||
|
||||
|
||||
<a href="performance.html" class="navigation navigation-prev navigation-unique" aria-label="Previous page: Performance">
|
||||
<a href="openapi.html" class="navigation navigation-prev navigation-unique" aria-label="Previous page: Swagger & Openapi (WIP)">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
|
|
@ -576,7 +681,7 @@ best parts of existing libs, added things that were missing (like first-class ro
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"FAQ","level":"1.9","depth":1,"previous":{"title":"Performance","level":"1.8","depth":1,"path":"performance.md","ref":"performance.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":"faq.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":".","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"FAQ","level":"1.9","depth":1,"previous":{"title":"Swagger & Openapi (WIP)","level":"1.8","depth":1,"path":"openapi.md","ref":"openapi.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":"faq.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":".","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
66
index.html
66
index.html
|
|
@ -436,33 +436,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="interceptors.html">
|
||||
|
||||
<a href="interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="openapi.html">
|
||||
|
||||
<a href="openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="performance.html">
|
||||
|
||||
<a href="performance.html">
|
||||
|
||||
|
|
@ -473,6 +447,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="interceptors.html">
|
||||
|
||||
<a href="interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="openapi.html">
|
||||
|
||||
<a href="openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="faq.html">
|
||||
|
|
@ -534,7 +534,7 @@
|
|||
<section class="normal markdown-section">
|
||||
|
||||
<h1 id="introduction">Introduction</h1>
|
||||
<p><a href="https://github.com/metosin/reitit" target="_blank">Reitit</a> is a small Clojure(Script) library for data-driven routing.</p>
|
||||
<p><a href="https://github.com/metosin/reitit" target="_blank">Reitit</a> is a fast data-driven router for Clojure(Script).</p>
|
||||
<ul>
|
||||
<li>Simple data-driven <a href="basics/route_syntax.html">route syntax</a></li>
|
||||
<li><a href="basics/route_conflicts.html">Route conflict resolution</a></li>
|
||||
|
|
@ -547,15 +547,15 @@
|
|||
</ul>
|
||||
<p>The following higher-level routers are also available as separate modules:</p>
|
||||
<ul>
|
||||
<li><a href="ring/ring.html">ring-router</a> with <a href="ring/data_driven_middleware.html">data-driven middleware</a></li>
|
||||
<li>http-router with Pedestal-style Interceptors (WIP)</li>
|
||||
<li>cljs-router with Keechma-style Controllers (WIP)</li>
|
||||
<li><a href="ring/ring.html"><code>ring-router</code></a> with <a href="ring/data_driven_middleware.html">data-driven middleware</a></li>
|
||||
<li><code>http-router</code> with enchanced Pedestal-style Interceptors (WIP)</li>
|
||||
<li><code>frontend-router</code> with Keechma-style Controllers (WIP)</li>
|
||||
</ul>
|
||||
<p>To use Reitit, add the following dependecy to your project:</p>
|
||||
<pre><code class="lang-clj">[metosin/reitit <span class="hljs-string">"0.1.0-SNAPSHOT"</span>]
|
||||
</code></pre>
|
||||
<p>Optionally, the parts can be required separately:</p>
|
||||
<pre><code class="lang-clj">[metosin/reitit-core <span class="hljs-string">"0.1.0-SNAPSHOT"</span>] <span class="hljs-comment">; just the router</span>
|
||||
<pre><code class="lang-clj">[metosin/reitit-core <span class="hljs-string">"0.1.0-SNAPSHOT"</span>] <span class="hljs-comment">; routing core</span>
|
||||
[metosin/reitit-ring <span class="hljs-string">"0.1.0-SNAPSHOT"</span>] <span class="hljs-comment">; ring-router</span>
|
||||
[metosin/reitit-spec <span class="hljs-string">"0.1.0-SNAPSHOT"</span>] <span class="hljs-comment">; spec coercion</span>
|
||||
[metosin/reitit-schema <span class="hljs-string">"0.1.0-SNAPSHOT"</span>] <span class="hljs-comment">; schema coercion</span>
|
||||
|
|
@ -695,7 +695,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Introduction","level":"1.1","depth":1,"next":{"title":"Basics","level":"1.2","depth":1,"path":"basics/README.md","ref":"basics/README.md","articles":[{"title":"Route Syntax","level":"1.2.1","depth":2,"path":"basics/route_syntax.md","ref":"basics/route_syntax.md","articles":[]},{"title":"Router","level":"1.2.2","depth":2,"path":"basics/router.md","ref":"basics/router.md","articles":[]},{"title":"Path-based Routing","level":"1.2.3","depth":2,"path":"basics/path_based_routing.md","ref":"basics/path_based_routing.md","articles":[]},{"title":"Name-based Routing","level":"1.2.4","depth":2,"path":"basics/name_based_routing.md","ref":"basics/name_based_routing.md","articles":[]},{"title":"Route Data","level":"1.2.5","depth":2,"path":"basics/route_data.md","ref":"basics/route_data.md","articles":[]},{"title":"Route Data Validation","level":"1.2.6","depth":2,"path":"basics/route_data_validation.md","ref":"basics/route_data_validation.md","articles":[]},{"title":"Route Conflicts","level":"1.2.7","depth":2,"path":"basics/route_conflicts.md","ref":"basics/route_conflicts.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":"README.md","mtime":"2018-02-02T12:48:38.750Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":".","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Introduction","level":"1.1","depth":1,"next":{"title":"Basics","level":"1.2","depth":1,"path":"basics/README.md","ref":"basics/README.md","articles":[{"title":"Route Syntax","level":"1.2.1","depth":2,"path":"basics/route_syntax.md","ref":"basics/route_syntax.md","articles":[]},{"title":"Router","level":"1.2.2","depth":2,"path":"basics/router.md","ref":"basics/router.md","articles":[]},{"title":"Path-based Routing","level":"1.2.3","depth":2,"path":"basics/path_based_routing.md","ref":"basics/path_based_routing.md","articles":[]},{"title":"Name-based Routing","level":"1.2.4","depth":2,"path":"basics/name_based_routing.md","ref":"basics/name_based_routing.md","articles":[]},{"title":"Route Data","level":"1.2.5","depth":2,"path":"basics/route_data.md","ref":"basics/route_data.md","articles":[]},{"title":"Route Data Validation","level":"1.2.6","depth":2,"path":"basics/route_data_validation.md","ref":"basics/route_data_validation.md","articles":[]},{"title":"Route Conflicts","level":"1.2.7","depth":2,"path":"basics/route_conflicts.md","ref":"basics/route_conflicts.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":"README.md","mtime":"2018-02-11T19:35:28.394Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":".","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<title>Interceptors · GitBook</title>
|
||||
<title>Interceptors (WIP) · GitBook</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="description" content="">
|
||||
<meta name="generator" content="GitBook 3.2.3">
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
<link rel="next" href="openapi.html" />
|
||||
|
||||
|
||||
<link rel="prev" href="ring/compiling_middleware.html" />
|
||||
<link rel="prev" href="performance.html" />
|
||||
|
||||
|
||||
</head>
|
||||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter active" data-level="1.6" data-path="interceptors.html">
|
||||
|
||||
<a href="interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="openapi.html">
|
||||
|
||||
<a href="openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="performance.html">
|
||||
|
||||
<a href="performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter active" data-level="1.7" data-path="interceptors.html">
|
||||
|
||||
<a href="interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="openapi.html">
|
||||
|
||||
<a href="openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="faq.html">
|
||||
|
|
@ -520,7 +520,7 @@
|
|||
<!-- Title -->
|
||||
<h1>
|
||||
<i class="fa fa-circle-o-notch fa-spin"></i>
|
||||
<a href="." >Interceptors</a>
|
||||
<a href="." >Interceptors (WIP)</a>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
|
|
@ -535,14 +535,16 @@
|
|||
|
||||
<section class="normal markdown-section">
|
||||
|
||||
<h1 id="interceptors">Interceptors</h1>
|
||||
<p>Reitit also supports <a href="pedestal.io">Pedestal</a>-style <a href="http://pedestal.io/reference/interceptors" target="_blank">interceptors</a> via <code>reitit.interceptor</code> package.</p>
|
||||
<p>Full support is WIP at the moment:</p>
|
||||
<h1 id="interceptors-wip">Interceptors (WIP)</h1>
|
||||
<p>Reitit has also support for <a href="pedestal.io">Pedestal</a>-style <a href="http://pedestal.io/reference/interceptors" target="_blank">interceptors</a> via <code>reitit.interceptor</code> package. Currently, there is no interceptor interpreter shipped, just a way to compose and manage the interceptor chains.</p>
|
||||
<p>Plan is to have a full-featured <code>reitit-http</code> module with same features as the <code>reitit-ring</code> - enchanced interceptor maps & interceptor compilations. Stay tuned.</p>
|
||||
<h3 id="todo">TODO</h3>
|
||||
<ul>
|
||||
<li>separate module (or library?) for interceptor interpreters</li>
|
||||
<li>figure out how to make a truly portable Interceptor definitions, e.g. Pedestal has namespaced keys for context errors, queues etc.</li>
|
||||
<li>finalize <code>reitit-http</code> module as an alternative to <code>reitit-ring</code></li>
|
||||
<li>Figure out how to make a truly portable Interceptor definitions, e.g. Pedestal has namespaced keys for context errors, queues etc.</li>
|
||||
<li>Separate modules for interceptor interpreters (including cljs)</li>
|
||||
<li>Finalize <code>reitit-http</code> module as an alternative to <code>reitit-ring</code></li>
|
||||
</ul>
|
||||
<h3 id="example">Example</h3>
|
||||
<p>Current <code>reitit-http</code> draft (with data-specs):</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.http.coercion <span class="hljs-symbol">:as</span> rhc])
|
||||
(<span class="hljs-name">require</span> '[reitit.http <span class="hljs-symbol">:as</span> http])
|
||||
|
|
@ -616,12 +618,12 @@
|
|||
|
||||
|
||||
|
||||
<a href="ring/compiling_middleware.html" class="navigation navigation-prev " aria-label="Previous page: Compiling Middleware">
|
||||
<a href="performance.html" class="navigation navigation-prev " aria-label="Previous page: Performance">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="openapi.html" class="navigation navigation-next " aria-label="Next page: Swagger & Openapi">
|
||||
<a href="openapi.html" class="navigation navigation-next " aria-label="Next page: Swagger & Openapi (WIP)">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
|
|
@ -632,7 +634,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Interceptors","level":"1.6","depth":1,"next":{"title":"Swagger & Openapi","level":"1.7","depth":1,"path":"openapi.md","ref":"openapi.md","articles":[]},"previous":{"title":"Compiling Middleware","level":"1.5.6","depth":2,"path":"ring/compiling_middleware.md","ref":"ring/compiling_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":"interceptors.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":".","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Interceptors (WIP)","level":"1.7","depth":1,"next":{"title":"Swagger & Openapi (WIP)","level":"1.8","depth":1,"path":"openapi.md","ref":"openapi.md","articles":[]},"previous":{"title":"Performance","level":"1.6","depth":1,"path":"performance.md","ref":"performance.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":"interceptors.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":".","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
119
openapi.html
119
openapi.html
|
|
@ -4,7 +4,7 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<title>Swagger & Openapi · GitBook</title>
|
||||
<title>Swagger & Openapi (WIP) · GitBook</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="description" content="">
|
||||
<meta name="generator" content="GitBook 3.2.3">
|
||||
|
|
@ -57,7 +57,7 @@
|
|||
<link rel="shortcut icon" href="gitbook/images/favicon.ico" type="image/x-icon">
|
||||
|
||||
|
||||
<link rel="next" href="performance.html" />
|
||||
<link rel="next" href="faq.html" />
|
||||
|
||||
|
||||
<link rel="prev" href="interceptors.html" />
|
||||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="interceptors.html">
|
||||
|
||||
<a href="interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter active" data-level="1.7" data-path="openapi.html">
|
||||
|
||||
<a href="openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="performance.html">
|
||||
|
||||
<a href="performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="interceptors.html">
|
||||
|
||||
<a href="interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter active" data-level="1.8" data-path="openapi.html">
|
||||
|
||||
<a href="openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="faq.html">
|
||||
|
|
@ -520,7 +520,7 @@
|
|||
<!-- Title -->
|
||||
<h1>
|
||||
<i class="fa fa-circle-o-notch fa-spin"></i>
|
||||
<a href="." >Swagger & Openapi</a>
|
||||
<a href="." >Swagger & Openapi (WIP)</a>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
|
|
@ -535,15 +535,58 @@
|
|||
|
||||
<section class="normal markdown-section">
|
||||
|
||||
<h1 id="swagger--openapi">Swagger & OpenAPI</h1>
|
||||
<p>Goal is to support both <a href="https://swagger.io/" target="_blank">Swagger</a> & <a href="https://www.openapis.org/" target="_blank">OpenAPI</a> specifications for route documentation.</p>
|
||||
<p>Swagge-support draft works, but only for Clojure.</p>
|
||||
<p>TODO:</p>
|
||||
<h1 id="swagger--openapi-wip">Swagger & OpenAPI (WIP)</h1>
|
||||
<p>Goal is to support both <a href="https://swagger.io/" target="_blank">Swagger</a> & <a href="https://www.openapis.org/" target="_blank">OpenAPI</a> for route documentation. Documentation is extracted from existing coercion definitions <code>:parameters</code>, <code>:responses</code> and from a set of new doumentation keys.</p>
|
||||
<p>Swagger-support draft works, but only for Clojure.</p>
|
||||
<h3 id="todo">TODO</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/metosin/schema-tools/issues/38" target="_blank">metosin/schema-tools#38</a>: extract Schema-swagger from <a href="https://github.com/metosin/ring-swagger" target="_blank">ring-swagger</a> into <a href="https://github.com/metosin/schema-tools" target="_blank">schema-tools</a> to support both Clojure & ClojureScript</li>
|
||||
<li>separate modules for the swagger2 & openapi</li>
|
||||
<li><a href="https://github.com/metosin/spec-tools/issues/105" target="_blank">metosin/spec-tools#105</a>: support OpenApi</li>
|
||||
<li><a href="https://github.com/metosin/spec-tools/issues/105" target="_blank">metosin/spec-tools#105</a>: support Openapi</li>
|
||||
</ul>
|
||||
<h3 id="example">Example</h3>
|
||||
<p>Current <code>reitit-swagger</code> draft (with <code>reitit-ring</code> & data-specs):</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.ring <span class="hljs-symbol">:as</span> ring])
|
||||
(<span class="hljs-name">require</span> '[reitit.ring.swagger <span class="hljs-symbol">:as</span> swagger])
|
||||
(<span class="hljs-name">require</span> '[reitit.ring.coercion <span class="hljs-symbol">:as</span> rrc])
|
||||
(<span class="hljs-name">require</span> '[reitit.coercion.spec <span class="hljs-symbol">:as</span> spec])
|
||||
|
||||
(<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">"/api"</span>
|
||||
<span class="hljs-comment">;; identify a swagger api</span>
|
||||
<span class="hljs-comment">;; there can be several in a routing tree</span>
|
||||
{<span class="hljs-symbol">:swagger</span> {<span class="hljs-symbol">:id</span> <span class="hljs-symbol">:math</span>}}
|
||||
|
||||
<span class="hljs-comment">;; the (undocumented) swagger spec endpoint</span>
|
||||
[<span class="hljs-string">"/swagger.json"</span>
|
||||
{<span class="hljs-symbol">:get</span> {<span class="hljs-symbol">:no-doc</span> <span class="hljs-literal">true</span>
|
||||
<span class="hljs-symbol">:swagger</span> {<span class="hljs-symbol">:info</span> {<span class="hljs-symbol">:title</span> <span class="hljs-string">"my-api"</span>}}
|
||||
<span class="hljs-symbol">:handler</span> swagger/swagger-spec-handler}}]
|
||||
|
||||
[<span class="hljs-string">"/minus"</span>
|
||||
{<span class="hljs-symbol">:get</span> {<span class="hljs-symbol">:summary</span> <span class="hljs-string">"minus"</span>
|
||||
<span class="hljs-symbol">:parameters</span> {<span class="hljs-symbol">:query</span> {<span class="hljs-symbol">:x</span> int?, <span class="hljs-symbol">:y</span> int?}}
|
||||
<span class="hljs-symbol">:responses</span> {<span class="hljs-number">200</span> {<span class="hljs-symbol">:body</span> {<span class="hljs-symbol">:total</span> int?}}}
|
||||
<span class="hljs-symbol">:handler</span> (<span class="hljs-name"><span class="hljs-builtin-name">fn</span></span> [{{{<span class="hljs-symbol">:keys</span> [x y]} <span class="hljs-symbol">:query</span>} <span class="hljs-symbol">:parameters</span>}]
|
||||
{<span class="hljs-symbol">:status</span> <span class="hljs-number">200</span>, <span class="hljs-symbol">:body</span> {<span class="hljs-symbol">:total</span> (<span class="hljs-name"><span class="hljs-builtin-name">-</span></span> x y)}})}}]
|
||||
|
||||
[<span class="hljs-string">"/plus"</span>
|
||||
{<span class="hljs-symbol">:get</span> {<span class="hljs-symbol">:summary</span> <span class="hljs-string">"plus"</span>
|
||||
<span class="hljs-symbol">:parameters</span> {<span class="hljs-symbol">:query</span> {<span class="hljs-symbol">:x</span> int?, <span class="hljs-symbol">:y</span> int?}}
|
||||
<span class="hljs-symbol">:responses</span> {<span class="hljs-number">200</span> {<span class="hljs-symbol">:body</span> {<span class="hljs-symbol">:total</span> int?}}}
|
||||
<span class="hljs-symbol">:handler</span> (<span class="hljs-name"><span class="hljs-builtin-name">fn</span></span> [{{{<span class="hljs-symbol">:keys</span> [x y]} <span class="hljs-symbol">:query</span>} <span class="hljs-symbol">:parameters</span>}]
|
||||
{<span class="hljs-symbol">:status</span> <span class="hljs-number">200</span>, <span class="hljs-symbol">:body</span> {<span class="hljs-symbol">:total</span> (<span class="hljs-name"><span class="hljs-builtin-name">+</span></span> x y)}})}}]]
|
||||
|
||||
{<span class="hljs-symbol">:data</span> {<span class="hljs-symbol">:middleware</span> [<span class="hljs-comment">;; does not particiate in request processing</span>
|
||||
<span class="hljs-comment">;; just defines specs for the extra keys</span>
|
||||
swagger/swagger-middleware
|
||||
rrc/coerce-exceptions-middleware
|
||||
rrc/coerce-request-middleware
|
||||
rrc/coerce-response-middleware]
|
||||
<span class="hljs-symbol">:coercion</span> spec/coercion}})))
|
||||
</code></pre>
|
||||
|
||||
|
||||
</section>
|
||||
|
|
@ -571,12 +614,12 @@
|
|||
|
||||
|
||||
|
||||
<a href="interceptors.html" class="navigation navigation-prev " aria-label="Previous page: Interceptors">
|
||||
<a href="interceptors.html" class="navigation navigation-prev " aria-label="Previous page: Interceptors (WIP)">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="performance.html" class="navigation navigation-next " aria-label="Next page: Performance">
|
||||
<a href="faq.html" class="navigation navigation-next " aria-label="Next page: FAQ">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
|
|
@ -587,7 +630,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Swagger & Openapi","level":"1.7","depth":1,"next":{"title":"Performance","level":"1.8","depth":1,"path":"performance.md","ref":"performance.md","articles":[]},"previous":{"title":"Interceptors","level":"1.6","depth":1,"path":"interceptors.md","ref":"interceptors.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":"openapi.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":".","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Swagger & Openapi (WIP)","level":"1.8","depth":1,"next":{"title":"FAQ","level":"1.9","depth":1,"path":"faq.md","ref":"faq.md","articles":[]},"previous":{"title":"Interceptors (WIP)","level":"1.7","depth":1,"path":"interceptors.md","ref":"interceptors.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":"openapi.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":".","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -57,10 +57,10 @@
|
|||
<link rel="shortcut icon" href="gitbook/images/favicon.ico" type="image/x-icon">
|
||||
|
||||
|
||||
<link rel="next" href="faq.html" />
|
||||
<link rel="next" href="interceptors.html" />
|
||||
|
||||
|
||||
<link rel="prev" href="openapi.html" />
|
||||
<link rel="prev" href="ring/compiling_middleware.html" />
|
||||
|
||||
|
||||
</head>
|
||||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="interceptors.html">
|
||||
|
||||
<a href="interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="openapi.html">
|
||||
|
||||
<a href="openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter active" data-level="1.8" data-path="performance.html">
|
||||
<li class="chapter active" data-level="1.6" data-path="performance.html">
|
||||
|
||||
<a href="performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="interceptors.html">
|
||||
|
||||
<a href="interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="openapi.html">
|
||||
|
||||
<a href="openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="faq.html">
|
||||
|
|
@ -536,16 +536,16 @@
|
|||
<section class="normal markdown-section">
|
||||
|
||||
<h1 id="performance">Performance</h1>
|
||||
<p>There are many great routing libraries for Clojure(Script), but not many are optimized for perf. Reitit tries to be both great in features and be really fast. Originally the routing was adopted from <a href="http://pedestal.io/" target="_blank">Pedestal</a> (which is known to be fast), but has been partially rewritten performance in mind. Hopefully some optimizations can be back-ported to Pedestal.</p>
|
||||
<p>Reitit tries to be both great in features and be really, really fast. Originally the routing was ported from <a href="http://pedestal.io/" target="_blank">Pedestal</a>, but has been mostly rewritten to get even better performance.</p>
|
||||
<h3 id="rationale">Rationale</h3>
|
||||
<ul>
|
||||
<li>Multiple routing algorithms, choose based on the route tree</li>
|
||||
<li>Multiple routing algorithms, chosen based on the route tree</li>
|
||||
<li>Route flattening and re-ordering</li>
|
||||
<li>Managed mutability over Immutability</li>
|
||||
<li>Precompute/compile as much as possible (matches, middleware, routes)</li>
|
||||
<li>Managed mutability over immutability</li>
|
||||
<li>Precompute/compile as much as possible (matches, middleware, interceptors, routes)</li>
|
||||
<li>Use abstractions that enable JVM optimizations</li>
|
||||
<li>Use small functions to enable JVM Inlining</li>
|
||||
<li>Protocols over Multimethods (or Maps)</li>
|
||||
<li>Protocols over Multimethods</li>
|
||||
<li>Records over Maps</li>
|
||||
<li>Always be measuring</li>
|
||||
<li>Don't trust the (micro-)benchmarks</li>
|
||||
|
|
@ -595,17 +595,17 @@
|
|||
<p>So, we need to test something more realistic.</p>
|
||||
<h3 id="restful-apis">RESTful apis</h3>
|
||||
<p>To get better view on the real life routing performance, there is <a href="https://github.com/metosin/reitit/blob/master/perf-test/clj/reitit/opensensors_perf_test.clj" target="_blank">test</a> of a mid-size rest(ish) http api with 50+ routes, having a lot of path parameters. The route definitions are pulled off from the <a href="https://opensensors.io/" target="_blank">OpenSensors</a> swagger definitions.</p>
|
||||
<p>Thanks to the snappy <a href="https://github.com/metosin/reitit/blob/master/modules/reitit-core/src/reitit/segment.cljc" target="_blank">segment-tree</a> algorithm, <code>reitit-ring</code> is fastest here. Pedestal is also fast with it's <a href="https://en.wikipedia.org/wiki/Radix_tree" target="_blank">prefix-tree</a> implementation.</p>
|
||||
<p>Thanks to the snappy new <a href="https://github.com/metosin/reitit/blob/master/modules/reitit-core/src/reitit/segment.cljc" target="_blank">segment-tree</a> algorithm, <code>reitit-ring</code> is fastest here. Pedestal is also fast with it's <a href="https://en.wikipedia.org/wiki/Radix_tree" target="_blank">prefix-tree</a> implementation.</p>
|
||||
<p><img src="images/opensensors.png" alt="Opensensors perf test"></p>
|
||||
<h3 id="cqrs-apis">CQRS apis</h3>
|
||||
<p>Another real-life <a href="https://github.com/metosin/reitit/blob/master/perf-test/clj/reitit/lupapiste_perf_test.clj" target="_blank">test scenario</a> is a <a href="https://martinfowler.com/bliki/CQRS.html" target="_blank">CQRS</a>-style route tree, where all the paths are static, e.g. <code>/api/command/add-order</code>. The route definitions are pulled out from <a href="https://github.com/lupapiste/lupapiste" target="_blank">Lupapiste</a>. The test consists of ~300 static routes (just the commands here, there would be ~200 queries too).</p>
|
||||
<p>Again, both <code>reitit-ring</code> and Pedestal shine here, thanks to the fast lookup-routers. On average, they are <strong>two</strong> and on best case, <strong>three orders of magnitude faster</strong> than the other tested libs. Ataraxy failed this test on <code>Method code too large!</code> error.</p>
|
||||
<p>Another real-life <a href="https://github.com/metosin/reitit/blob/master/perf-test/clj/reitit/lupapiste_perf_test.clj" target="_blank">test scenario</a> is a <a href="https://martinfowler.com/bliki/CQRS.html" target="_blank">CQRS</a>-style route tree, where all the paths are static, e.g. <code>/api/command/add-order</code>. The 300 route definitions are pulled out from <a href="https://github.com/lupapiste/lupapiste" target="_blank">Lupapiste</a>.</p>
|
||||
<p>Both <code>reitit-ring</code> and Pedestal shine in this test, thanks to the fast lookup-routers. On average, they are <strong>two</strong> and on best case, <strong>three orders of magnitude faster</strong> than the other tested libs. Ataraxy failed this test on <code>Method code too large!</code> error.</p>
|
||||
<p><img src="images/lupapiste.png" alt="Opensensors perf test"></p>
|
||||
<p><strong>NOTE</strong>: If there would be even one wildcard route in the route-tree, Pedestal would fallback from lookup-router to the prefix-tree router, yielding nearly constant, but an order of magnitude slower perf. Reitit instead fallbacks to <code>:mixed-router</code>, serving all the static routes with <code>:lookup-router</code>, just the wildcard route(s) with <code>:segment-tree</code>. So, the performance would not notably degrade.</p>
|
||||
<p><strong>NOTE</strong>: in real life, there are usually always also wild-card routes present. In this case, Pedestal would fallback from lookup-router to the prefix-tree router, which is order of magnitude slower (30x in this test). Reitit would handle this nicely thanks to it's <code>:mixed-router</code>: all static routes would still be served with <code>:lookup-router</code>, just the wildcard routes with <code>:segment-tree</code>. The performance would not notably degrade.</p>
|
||||
<h3 id="why-measure">Why measure?</h3>
|
||||
<p>The routing perf needs to be measured to get an internal baseline to optimize against. We also want to ensure that new features don't regress the performance. Perf tests should be run in a stable CI environment. Help welcome.</p>
|
||||
<p>The reitit routing perf is measured to get an internal baseline to optimize against. We also want to ensure that new features don't regress the performance. Perf tests should be run in a stable CI environment. Help welcome!</p>
|
||||
<h3 id="looking-out-of-the-box">Looking out of the box</h3>
|
||||
<p>It might be interesting to compare reitit with the routers in other languages, like the <a href="https://github.com/julienschmidt/go-http-routing-benchmark" target="_blank">routers in Go</a>.</p>
|
||||
<p>A quick poke to <a href="https://github.com/julienschmidt/go-http-routing-benchmark" target="_blank">routers in Go</a> indicates that the reitit is only few times slower than the fastest routers in Go. Which is really awesome (if true).</p>
|
||||
<h3 id="performance-tips">Performance tips</h3>
|
||||
<p>Few things that have an effect on performance:</p>
|
||||
<ul>
|
||||
|
|
@ -643,12 +643,12 @@
|
|||
|
||||
|
||||
|
||||
<a href="openapi.html" class="navigation navigation-prev " aria-label="Previous page: Swagger & Openapi">
|
||||
<a href="ring/compiling_middleware.html" class="navigation navigation-prev " aria-label="Previous page: Compiling Middleware">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="faq.html" class="navigation navigation-next " aria-label="Next page: FAQ">
|
||||
<a href="interceptors.html" class="navigation navigation-next " aria-label="Next page: Interceptors (WIP)">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
|
|
@ -659,7 +659,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Performance","level":"1.8","depth":1,"next":{"title":"FAQ","level":"1.9","depth":1,"path":"faq.md","ref":"faq.md","articles":[]},"previous":{"title":"Swagger & Openapi","level":"1.7","depth":1,"path":"openapi.md","ref":"openapi.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":"performance.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":".","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Performance","level":"1.6","depth":1,"next":{"title":"Interceptors (WIP)","level":"1.7","depth":1,"path":"interceptors.md","ref":"interceptors.md","articles":[]},"previous":{"title":"Compiling Middleware","level":"1.5.6","depth":2,"path":"ring/compiling_middleware.md","ref":"ring/compiling_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":"performance.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":".","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -552,12 +552,15 @@
|
|||
<li><code>reitit.coercion.spec/coercion</code> for both <a href="https://clojure.org/about/spec" target="_blank">clojure.spec</a> and <a href="https://github.com/metosin/spec-tools#data-specs" target="_blank">data-specs</a></li>
|
||||
</ul>
|
||||
<p>Coercion can be attached to route data under <code>:coercion</code> key. There can be multiple <code>Coercion</code> implementations within a single router, normal <a href="../basics/route_data.html#nested-route-data">scoping rules</a> apply.</p>
|
||||
<h1 id="defining-parameters-and-responses">Defining parameters and responses</h1>
|
||||
<p>Below is a ring route data defining <a href="https://github.com/plumatic/schema" target="_blank">Plumatic Schema</a> coercion. It defines schemas for <code>:query</code>, <code>:body</code> and <code>:path</code> parameters and for a successful response <code>:body</code>.</p>
|
||||
<p>The coerced parameters can be read under <code>:parameters</code> key in the request.</p>
|
||||
<h2 id="defining-parameters-and-responses">Defining parameters and responses</h2>
|
||||
<p>Parameters are defined in <code>:parameters</code> key and responses in <code>:responses</code>.</p>
|
||||
<p>Below is an example with <a href="https://github.com/plumatic/schema" target="_blank">Plumatic Schema</a>. It defines input schemas for <code>:query</code>, <code>:body</code> and <code>:path</code> parameters and a schema for a successful response <code>:body</code>.</p>
|
||||
<p>Handler can access the coerced parameters can be read under <code>:parameters</code> key in the request.</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.coercion.schema])
|
||||
(<span class="hljs-name">require</span> '[schema.core <span class="hljs-symbol">:as</span> s])
|
||||
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> PositiveInt (<span class="hljs-name">s/constrained</span> s/Int pos? 'PositiveInt))
|
||||
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> plus-endpoint
|
||||
{<span class="hljs-symbol">:coercion</span> reitit.coercion.schema/coercion
|
||||
<span class="hljs-symbol">:parameters</span> {<span class="hljs-symbol">:query</span> {<span class="hljs-symbol">:x</span> s/Int}
|
||||
|
|
@ -574,9 +577,9 @@
|
|||
<h2 id="coercion-middleware">Coercion Middleware</h2>
|
||||
<p>Defining a coercion for a route data doesn't do anything, as it's just data. We have to attach some code to apply the actual coercion. We can use the middleware from <code>reitit.ring.coercion</code>:</p>
|
||||
<ul>
|
||||
<li><code>coerce-request-middleware</code> for the parameter coercion</li>
|
||||
<li><code>coerce-response-middleware</code> for the response coercion</li>
|
||||
<li><code>coerce-exceptions-middleware</code> to turn coercion exceptions into pretty responses</li>
|
||||
<li><code>coerce-request-middleware</code> to apply the parameter coercion</li>
|
||||
<li><code>coerce-response-middleware</code> to apply the response coercion</li>
|
||||
<li><code>coerce-exceptions-middleware</code> to transform coercion exceptions into pretty responses</li>
|
||||
</ul>
|
||||
<h3 id="full-example">Full example</h3>
|
||||
<p>Here's an full example for applying coercion with Reitit, Ring and Schema:</p>
|
||||
|
|
@ -645,7 +648,7 @@
|
|||
<span class="hljs-comment">; :in [:response :body]}}</span>
|
||||
</code></pre>
|
||||
<h3 id="optimizations">Optimizations</h3>
|
||||
<p>The coercion middleware are <a href="compiling_middleware,md">compiled againts a route</a>. In the compile step the actual coercer implementations are compiled for the defined models. Also, the mw doesn't mount itself if a route doesn't have <code>:coercion</code> and <code>:parameters</code> or <code>:responses</code> defined.</p>
|
||||
<p>The coercion middleware are <a href="compiling_middleware,md">compiled againts a route</a>. In the middleware compilation step the actual coercer implementations are constructed for the defined models. Also, the middleware doesn't mount itself if a route doesn't have <code>:coercion</code> and <code>:parameters</code> or <code>:responses</code> defined.</p>
|
||||
<p>We can query the compiled middleware chain for the routes:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.core <span class="hljs-symbol">:as</span> r])
|
||||
|
||||
|
|
@ -668,13 +671,6 @@
|
|||
(<span class="hljs-name"><span class="hljs-builtin-name">->></span></span> (<span class="hljs-name"><span class="hljs-builtin-name">mapv</span></span> <span class="hljs-symbol">:name</span>)))
|
||||
<span class="hljs-comment">; []</span>
|
||||
</code></pre>
|
||||
<h2 id="thanks-to">Thanks to</h2>
|
||||
<ul>
|
||||
<li><a href="https://clojars.org/metosin/compojure-api" target="_blank">compojure-api</a> for the initial <code>Coercion</code> protocol</li>
|
||||
<li><a href="https://github.com/metosin/ring-swagger#more-complete-example" target="_blank">ring-swagger</a> for the <code>:parameters</code> and <code>:responses</code> syntax.</li>
|
||||
<li><a href="https://github.com/plumatic/schema" target="_blank">schema</a> and <a href="https://github.com/metosin/schema-tools" target="_blank">schema-tools</a> for Schema Coercion</li>
|
||||
<li><a href="https://github.com/metosin/spec-tools" target="_blank">spec-tools</a> for Spec Coercion</li>
|
||||
</ul>
|
||||
|
||||
|
||||
</section>
|
||||
|
|
@ -718,7 +714,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Pluggable Coercion","level":"1.5.4","depth":2,"next":{"title":"Route Data Validation","level":"1.5.5","depth":2,"path":"ring/route_data_validation.md","ref":"ring/route_data_validation.md","articles":[]},"previous":{"title":"Data-driven Middleware","level":"1.5.3","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/coercion.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Pluggable Coercion","level":"1.5.4","depth":2,"next":{"title":"Route Data Validation","level":"1.5.5","depth":2,"path":"ring/route_data_validation.md","ref":"ring/route_data_validation.md","articles":[]},"previous":{"title":"Data-driven Middleware","level":"1.5.3","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/coercion.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
<link rel="shortcut icon" href="../gitbook/images/favicon.ico" type="image/x-icon">
|
||||
|
||||
|
||||
<link rel="next" href="../interceptors.html" />
|
||||
<link rel="next" href="../performance.html" />
|
||||
|
||||
|
||||
<link rel="prev" href="route_data_validation.html" />
|
||||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -537,12 +537,12 @@
|
|||
|
||||
<h1 id="compiling-middleware">Compiling Middleware</h1>
|
||||
<p>The <a href="dynamic_extensions.html">dynamic extensions</a> 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.</p>
|
||||
<p>But, we can do much 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. It can also decide not to mount itself by returning <code>nil</code>. Why mount a <code>wrap-enforce-roles</code> middleware for a route if there are no roles required for it?</p>
|
||||
<p>To enable this we use <a href="data_driven_middleware.html">middleware records</a> <code>:compile</code> key instead of the normal <code>:wrap</code>. <code>:compile</code> expects a function of <code>route-data router-opts => ?wrap</code>.</p>
|
||||
<p>But, we can do much better. As we know the exact route that 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. Middleware can also decide not to mount itself by returning <code>nil</code>. Why mount a <code>wrap-enforce-roles</code> middleware for a route if there are no roles required for it?</p>
|
||||
<p>To enable this we use <a href="data_driven_middleware.html">middleware records</a> <code>:compile</code> key instead of the normal <code>:wrap</code>. <code>:compile</code> expects a function of <code>route-data router-opts => ?IntoMiddleware</code>.</p>
|
||||
<p>To demonstrate the two approaches, below are response coercion middleware written as normal ring middleware function and as middleware record with <code>:compile</code>.</p>
|
||||
<h2 id="normal-middleware">Normal Middleware</h2>
|
||||
<ul>
|
||||
<li>Reads the compiled route information on every request.</li>
|
||||
<li>Reads the compiled route information on every request. Everything is done at request-time.</li>
|
||||
</ul>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">defn</span></span> wrap-coerce-response
|
||||
<span class="hljs-string">"Middleware for pluggable response coercion.
|
||||
|
|
@ -574,9 +574,9 @@
|
|||
</code></pre>
|
||||
<h2 id="compiled-middleware">Compiled Middleware</h2>
|
||||
<ul>
|
||||
<li>Route information is provided via a closure</li>
|
||||
<li>Pre-compiled coercers</li>
|
||||
<li>Mounts only if <code>:coercion</code> and <code>:responses</code> are defined for the route</li>
|
||||
<li>Route information is provided at creation-time</li>
|
||||
<li>Coercers are compiled at creation-time</li>
|
||||
<li>Middleware mounts only if <code>:coercion</code> and <code>:responses</code> are defined for the route</li>
|
||||
<li>Also defines spec for the route data <code>:responses</code> for the <a href="route_data_validation.html">route data validation</a>.</li>
|
||||
</ul>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.spec <span class="hljs-symbol">:as</span> rs])
|
||||
|
|
@ -597,7 +597,7 @@
|
|||
([request respond raise]
|
||||
(<span class="hljs-name">handler</span> request #(<span class="hljs-name">respond</span> (<span class="hljs-name">coercion/coerce-response</span> coercers request %)) raise)))))))})
|
||||
</code></pre>
|
||||
<p>The latter has 50% less code, is easier to reason about and is much faster.</p>
|
||||
<p>It has 50% less code, it's much easier to reason about and is much faster.</p>
|
||||
|
||||
|
||||
</section>
|
||||
|
|
@ -630,7 +630,7 @@
|
|||
</a>
|
||||
|
||||
|
||||
<a href="../interceptors.html" class="navigation navigation-next " aria-label="Next page: Interceptors">
|
||||
<a href="../performance.html" class="navigation navigation-next " aria-label="Next page: Performance">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
|
|
@ -641,7 +641,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Compiling Middleware","level":"1.5.6","depth":2,"next":{"title":"Interceptors","level":"1.6","depth":1,"path":"interceptors.md","ref":"interceptors.md","articles":[]},"previous":{"title":"Route Data Validation","level":"1.5.5","depth":2,"path":"ring/route_data_validation.md","ref":"ring/route_data_validation.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/compiling_middleware.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Compiling Middleware","level":"1.5.6","depth":2,"next":{"title":"Performance","level":"1.6","depth":1,"path":"performance.md","ref":"performance.md","articles":[]},"previous":{"title":"Route Data Validation","level":"1.5.5","depth":2,"path":"ring/route_data_validation.md","ref":"ring/route_data_validation.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/compiling_middleware.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -540,12 +540,12 @@
|
|||
<p>Reitit defines middleware as data:</p>
|
||||
<ol>
|
||||
<li>Middleware can be defined as first-class data entries</li>
|
||||
<li>Middleware can be defined as a <a href="https://github.com/duct-framework/duct/wiki/Configuration" target="_blank">duct-style</a> vector (of middleware)</li>
|
||||
<li>Middleware can be mounted as a <a href="https://github.com/duct-framework/duct/wiki/Configuration" target="_blank">duct-style</a> vector (of middleware)</li>
|
||||
<li>Middleware can be optimized & <a href="compiling_middleware.html">compiled</a> againt an endpoint</li>
|
||||
<li>Middleware chain can be transformed by the router</li>
|
||||
</ol>
|
||||
<h2 id="middleware-as-data">Middleware as data</h2>
|
||||
<p>All values in the <code>:middleware</code> vector in the route data are coerced into <code>reitit.middleware/Middleware</code> Records with using the <code>reitit.middleware/IntoMiddleware</code> Protocol. By default, functions, maps and <code>Middleware</code> records are allowed.</p>
|
||||
<p>All values in the <code>:middleware</code> vector in the route data are expanded into <code>reitit.middleware/Middleware</code> Records with using the <code>reitit.middleware/IntoMiddleware</code> Protocol. By default, functions, maps and <code>Middleware</code> records are allowed.</p>
|
||||
<p>Records can have arbitrary keys, but the following keys have a special purpose:</p>
|
||||
<table>
|
||||
<thead>
|
||||
|
|
@ -582,6 +582,12 @@
|
|||
(<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">::acc</span> (<span class="hljs-name">fnil</span> conj []) id))))
|
||||
</code></pre>
|
||||
<h3 id="map">Map</h3>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> wrap3
|
||||
{<span class="hljs-symbol">:name</span> <span class="hljs-symbol">::wrap3</span>
|
||||
<span class="hljs-symbol">:description</span> <span class="hljs-string">"Middleware that does things."</span>
|
||||
<span class="hljs-symbol">:wrap</span> wrap})
|
||||
</code></pre>
|
||||
<h3 id="record">Record</h3>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.middleware <span class="hljs-symbol">:as</span> middleware])
|
||||
|
||||
|
|
@ -591,12 +597,6 @@
|
|||
<span class="hljs-symbol">:description</span> <span class="hljs-string">"Middleware that does things."</span>
|
||||
<span class="hljs-symbol">:wrap</span> wrap}))
|
||||
</code></pre>
|
||||
<h3 id="map">Map</h3>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> wrap3
|
||||
{<span class="hljs-symbol">:name</span> <span class="hljs-symbol">::wrap3</span>
|
||||
<span class="hljs-symbol">:description</span> <span class="hljs-string">"Middleware that does things."</span>
|
||||
<span class="hljs-symbol">:wrap</span> wrap})
|
||||
</code></pre>
|
||||
<h2 id="using-middleware">Using Middleware</h2>
|
||||
<p><code>:middleware</code> is merged to endpoints by the <code>router</code>.</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.ring <span class="hljs-symbol">:as</span> ring])
|
||||
|
|
@ -628,9 +628,10 @@
|
|||
<span class="hljs-symbol">:handler</span> handler}}]]
|
||||
{<span class="hljs-symbol">::middleware/transform</span> #(<span class="hljs-name">interleave</span> % (<span class="hljs-name"><span class="hljs-builtin-name">repeat</span></span> [wrap <span class="hljs-symbol">:debug</span>]))})))
|
||||
</code></pre>
|
||||
<pre><code>(app {:request-method :get, :uri "/api/ping"})
|
||||
; {:status 200, :body [1 :debug 2 :debug 3 :debug :handler]}
|
||||
</code></pre><h4 id="reversing-the-middleware-chain">Reversing the middleware chain</h4>
|
||||
<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">"/api/ping"</span>})
|
||||
<span class="hljs-comment">; {:status 200, :body [1 :debug 2 :debug 3 :debug :handler]}</span>
|
||||
</code></pre>
|
||||
<h4 id="reversing-the-middleware-chain">Reversing the middleware chain</h4>
|
||||
<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>
|
||||
|
|
@ -639,13 +640,13 @@
|
|||
<span class="hljs-symbol">:handler</span> handler}}]]
|
||||
{<span class="hljs-symbol">::middleware/transform</span> reverse)})))
|
||||
</code></pre>
|
||||
<pre><code>(app {:request-method :get, :uri "/api/ping"})
|
||||
; {:status 200, :body [3 2 1 :handler]}
|
||||
</code></pre><h2 id="roadmap-for-middleware">Roadmap for middleware</h2>
|
||||
<p>Some things bubblin' under:</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">"/api/ping"</span>})
|
||||
<span class="hljs-comment">; {:status 200, :body [3 2 1 :handler]}</span>
|
||||
</code></pre>
|
||||
<h2 id="ideas-for-the-future">Ideas for the future</h2>
|
||||
<ul>
|
||||
<li>Re-package all useful middleware into (optimized) data-driven Middleware<ul>
|
||||
<li>just package or a new community-repo with rehosting stuffm?</li>
|
||||
<li>just package or a new community-repo with rehosting stuff?</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Support <code>Keyword</code> expansion into Middleware, enabling external Middleware Registries (duct/integrant/macchiato -style)</li>
|
||||
|
|
@ -699,7 +700,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Data-driven Middleware","level":"1.5.3","depth":2,"next":{"title":"Pluggable Coercion","level":"1.5.4","depth":2,"path":"ring/coercion.md","ref":"ring/coercion.md","articles":[]},"previous":{"title":"Dynamic Extensions","level":"1.5.2","depth":2,"path":"ring/dynamic_extensions.md","ref":"ring/dynamic_extensions.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/data_driven_middleware.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Data-driven Middleware","level":"1.5.3","depth":2,"next":{"title":"Pluggable Coercion","level":"1.5.4","depth":2,"path":"ring/coercion.md","ref":"ring/coercion.md","articles":[]},"previous":{"title":"Dynamic Extensions","level":"1.5.2","depth":2,"path":"ring/dynamic_extensions.md","ref":"ring/dynamic_extensions.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/data_driven_middleware.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -538,7 +538,8 @@
|
|||
<h1 id="dynamic-extensions">Dynamic Extensions</h1>
|
||||
<p><code>ring-handler</code> injects the <code>Match</code> into a request and it can be extracted at runtime with <code>reitit.ring/get-match</code>. This can be used to build ad-hoc extensions to the system.</p>
|
||||
<p>Example middleware to guard routes based on user roles:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[clojure.set <span class="hljs-symbol">:as</span> set])
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.ring <span class="hljs-symbol">:as</span> ring])
|
||||
(<span class="hljs-name">require</span> '[clojure.set <span class="hljs-symbol">:as</span> set])
|
||||
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">defn</span></span> wrap-enforce-roles [handler]
|
||||
(<span class="hljs-name"><span class="hljs-builtin-name">fn</span></span> [{<span class="hljs-symbol">:keys</span> [<span class="hljs-symbol">::roles</span>] <span class="hljs-symbol">:as</span> request}]
|
||||
|
|
@ -571,6 +572,7 @@
|
|||
<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">"/api/admin/ping"</span>, <span class="hljs-symbol">::roles</span> #{<span class="hljs-symbol">:admin</span>}})
|
||||
<span class="hljs-comment">; {:status 200, :body "ok"}</span>
|
||||
</code></pre>
|
||||
<p>Dynamic extensions are nice, but we can do much better. See <a href="data_driven_middleware.html">data-driven middleware</a> and <a href="compiling_middleware.html">compiling routes</a>.</p>
|
||||
|
||||
|
||||
</section>
|
||||
|
|
@ -614,7 +616,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Dynamic Extensions","level":"1.5.2","depth":2,"next":{"title":"Data-driven Middleware","level":"1.5.3","depth":2,"path":"ring/data_driven_middleware.md","ref":"ring/data_driven_middleware.md","articles":[]},"previous":{"title":"Ring-router","level":"1.5.1","depth":2,"path":"ring/ring.md","ref":"ring/ring.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/dynamic_extensions.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Dynamic Extensions","level":"1.5.2","depth":2,"next":{"title":"Data-driven Middleware","level":"1.5.3","depth":2,"path":"ring/data_driven_middleware.md","ref":"ring/data_driven_middleware.md","articles":[]},"previous":{"title":"Ring-router","level":"1.5.1","depth":2,"path":"ring/ring.md","ref":"ring/ring.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/dynamic_extensions.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -587,7 +587,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Ring","level":"1.5","depth":1,"next":{"title":"Ring-router","level":"1.5.1","depth":2,"path":"ring/ring.md","ref":"ring/ring.md","articles":[]},"previous":{"title":"Route Validation","level":"1.4.3","depth":2,"path":"advanced/route_validation.md","ref":"advanced/route_validation.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/README.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Ring","level":"1.5","depth":1,"next":{"title":"Ring-router","level":"1.5.1","depth":2,"path":"ring/ring.md","ref":"ring/ring.md","articles":[]},"previous":{"title":"Route Validation","level":"1.4.3","depth":2,"path":"advanced/route_validation.md","ref":"advanced/route_validation.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/README.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -536,7 +536,11 @@
|
|||
<section class="normal markdown-section">
|
||||
|
||||
<h1 id="ring-router">Ring Router</h1>
|
||||
<p><a href="https://github.com/ring-clojure/ring" target="_blank">Ring</a>-router adds support for <a href="https://github.com/ring-clojure/ring/wiki/Concepts#handlers" target="_blank">handlers</a>, <a href="https://github.com/ring-clojure/ring/wiki/Concepts#middleware" target="_blank">middleware</a> and routing based on <code>:request-method</code>. Ring-router is created with <code>reitit.ring/router</code> function. It runs a custom route compiler, creating a optimized stucture for handling route matches, with compiled middleware chain & handlers for all request methods. It also ensures that all routes have a <code>:handler</code> defined.</p>
|
||||
<p><a href="https://github.com/ring-clojure/ring" target="_blank">Ring</a> is a Clojure web applications library inspired by Python's WSGI and Ruby's Rack. By abstracting the details of HTTP into a simple, unified API, Ring allows web applications to be constructed of modular components that can be shared among a variety of applications, web servers, and web frameworks.</p>
|
||||
<pre><code class="lang-clj">[metosin/reitit-ring <span class="hljs-string">"0.1.0-SNAPSHOT"</span>]
|
||||
</code></pre>
|
||||
<p>Ring-router adds support for <a href="https://github.com/ring-clojure/ring/wiki/Concepts#handlers" target="_blank">handlers</a>, <a href="https://github.com/ring-clojure/ring/wiki/Concepts#middleware" target="_blank">middleware</a> and routing based on <code>:request-method</code>. Ring-router is created with <code>reitit.ring/router</code> function. It uses a custom route compiler, creating a optimized data structure for handling route matches, with compiled middleware chain & handlers for all request methods. It also ensures that all routes have a <code>:handler</code> defined. <code>reitit.ring/ring-handler</code> is used to create a Ring handler out of ring-router.</p>
|
||||
<h3 id="example">Example</h3>
|
||||
<p>Simple Ring app:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[reitit.ring <span class="hljs-symbol">:as</span> ring])
|
||||
|
||||
|
|
@ -551,8 +555,8 @@
|
|||
<p>Applying the handler:</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">"/favicon.ico"</span>})
|
||||
<span class="hljs-comment">; nil</span>
|
||||
|
||||
(<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">"/ping"</span>})
|
||||
</code></pre>
|
||||
<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">"/ping"</span>})
|
||||
<span class="hljs-comment">; {:status 200, :body "ok"}</span>
|
||||
</code></pre>
|
||||
<p>The expanded routes shows the compilation results:</p>
|
||||
|
|
@ -563,7 +567,7 @@
|
|||
<span class="hljs-comment">; :handler #object[...],</span>
|
||||
<span class="hljs-comment">; :middleware []}}]]</span>
|
||||
</code></pre>
|
||||
<p>Note that the compiled resuts as third element in the route vector.</p>
|
||||
<p>Note the compiled resuts as third element in the route vector.</p>
|
||||
<h1 id="request-method-based-routing">Request-method based routing</h1>
|
||||
<p>Handler are also looked under request-method keys: <code>:get</code>, <code>:head</code>, <code>:patch</code>, <code>:delete</code>, <code>:options</code>, <code>:post</code> or <code>:put</code>. Top-level handler is used if request-method based handler is not found.</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name"><span class="hljs-builtin-name">def</span></span> app
|
||||
|
|
@ -604,10 +608,13 @@
|
|||
<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-comment">;; a middleware function</span>
|
||||
[<span class="hljs-string">"/api"</span> {<span class="hljs-symbol">:middleware</span> [#(<span class="hljs-name">wrap</span> % <span class="hljs-symbol">:api</span>)]}
|
||||
[<span class="hljs-string">"/ping"</span> handler]
|
||||
<span class="hljs-comment">;; a middleware vector at top level</span>
|
||||
[<span class="hljs-string">"/admin"</span> {<span class="hljs-symbol">:middleware</span> [[wrap <span class="hljs-symbol">:admin</span>]]}
|
||||
[<span class="hljs-string">"/db"</span> {<span class="hljs-symbol">:middleware</span> [[wrap <span class="hljs-symbol">:db</span>]]
|
||||
<span class="hljs-comment">;; a middleware vector at under a method</span>
|
||||
<span class="hljs-symbol">:delete</span> {<span class="hljs-symbol">:middleware</span> [[wrap <span class="hljs-symbol">:delete</span>]]
|
||||
<span class="hljs-symbol">:handler</span> handler}}]]])))
|
||||
</code></pre>
|
||||
|
|
@ -730,7 +737,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Ring-router","level":"1.5.1","depth":2,"next":{"title":"Dynamic Extensions","level":"1.5.2","depth":2,"path":"ring/dynamic_extensions.md","ref":"ring/dynamic_extensions.md","articles":[]},"previous":{"title":"Ring","level":"1.5","depth":1,"path":"ring/README.md","ref":"ring/README.md","articles":[{"title":"Ring-router","level":"1.5.1","depth":2,"path":"ring/ring.md","ref":"ring/ring.md","articles":[]},{"title":"Dynamic Extensions","level":"1.5.2","depth":2,"path":"ring/dynamic_extensions.md","ref":"ring/dynamic_extensions.md","articles":[]},{"title":"Data-driven Middleware","level":"1.5.3","depth":2,"path":"ring/data_driven_middleware.md","ref":"ring/data_driven_middleware.md","articles":[]},{"title":"Pluggable Coercion","level":"1.5.4","depth":2,"path":"ring/coercion.md","ref":"ring/coercion.md","articles":[]},{"title":"Route Data Validation","level":"1.5.5","depth":2,"path":"ring/route_data_validation.md","ref":"ring/route_data_validation.md","articles":[]},{"title":"Compiling Middleware","level":"1.5.6","depth":2,"path":"ring/compiling_middleware.md","ref":"ring/compiling_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/ring.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Ring-router","level":"1.5.1","depth":2,"next":{"title":"Dynamic Extensions","level":"1.5.2","depth":2,"path":"ring/dynamic_extensions.md","ref":"ring/dynamic_extensions.md","articles":[]},"previous":{"title":"Ring","level":"1.5","depth":1,"path":"ring/README.md","ref":"ring/README.md","articles":[{"title":"Ring-router","level":"1.5.1","depth":2,"path":"ring/ring.md","ref":"ring/ring.md","articles":[]},{"title":"Dynamic Extensions","level":"1.5.2","depth":2,"path":"ring/dynamic_extensions.md","ref":"ring/dynamic_extensions.md","articles":[]},{"title":"Data-driven Middleware","level":"1.5.3","depth":2,"path":"ring/data_driven_middleware.md","ref":"ring/data_driven_middleware.md","articles":[]},{"title":"Pluggable Coercion","level":"1.5.4","depth":2,"path":"ring/coercion.md","ref":"ring/coercion.md","articles":[]},{"title":"Route Data Validation","level":"1.5.5","depth":2,"path":"ring/route_data_validation.md","ref":"ring/route_data_validation.md","articles":[]},{"title":"Compiling Middleware","level":"1.5.6","depth":2,"path":"ring/compiling_middleware.md","ref":"ring/compiling_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/ring.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -438,33 +438,7 @@
|
|||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.6" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../performance.html">
|
||||
<li class="chapter " data-level="1.6" data-path="../performance.html">
|
||||
|
||||
<a href="../performance.html">
|
||||
|
||||
|
|
@ -475,6 +449,32 @@
|
|||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.7" data-path="../interceptors.html">
|
||||
|
||||
<a href="../interceptors.html">
|
||||
|
||||
|
||||
Interceptors (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.8" data-path="../openapi.html">
|
||||
|
||||
<a href="../openapi.html">
|
||||
|
||||
|
||||
Swagger & Openapi (WIP)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li class="chapter " data-level="1.9" data-path="../faq.html">
|
||||
|
|
@ -542,7 +542,6 @@
|
|||
<li>With <code>clojure.spec</code> validation, Middleware can contribute to route spec via <code>:specs</code> key. The effective route data spec is router spec merged with middleware specs.</li>
|
||||
</ul>
|
||||
<h2 id="example">Example</h2>
|
||||
<p>Let's build a ring app with with both explicit (via middleware) and implicit (fully-qualified keys) spec validation.</p>
|
||||
<p>A simple app with spec-validation turned on:</p>
|
||||
<pre><code class="lang-clj">(<span class="hljs-name">require</span> '[clojure.spec.alpha <span class="hljs-symbol">:as</span> s])
|
||||
(<span class="hljs-name">require</span> '[reitit.ring <span class="hljs-symbol">:as</span> ring])
|
||||
|
|
@ -728,7 +727,7 @@
|
|||
<span class="hljs-comment">; should be one of: `:admin`,`:manager`</span>
|
||||
</code></pre>
|
||||
<h3 id="pushing-the-data-to-the-endpoints">Pushing the data to the endpoints</h3>
|
||||
<p>Ability to define (and reuse) route-data in sub-paths is a powerful feature, but having data scattered all around might be harder to reason about. There is always an option to push all data to the endpoints.</p>
|
||||
<p>Ability to define (and reuse) route-data in mid-paths is a powerful feature, but having data defined all around might be harder to reason about. There is always an option to define all data at the endpoints.</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>
|
||||
|
|
@ -825,7 +824,7 @@
|
|||
<script>
|
||||
var gitbook = gitbook || [];
|
||||
gitbook.push(function() {
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Data Validation","level":"1.5.5","depth":2,"next":{"title":"Compiling Middleware","level":"1.5.6","depth":2,"path":"ring/compiling_middleware.md","ref":"ring/compiling_middleware.md","articles":[]},"previous":{"title":"Pluggable Coercion","level":"1.5.4","depth":2,"path":"ring/coercion.md","ref":"ring/coercion.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/route_data_validation.md","mtime":"2018-02-02T12:48:38.754Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-02T12:49:15.950Z"},"basePath":"..","book":{"language":""}});
|
||||
gitbook.page.hasChanged({"page":{"title":"Route Data Validation","level":"1.5.5","depth":2,"next":{"title":"Compiling Middleware","level":"1.5.6","depth":2,"path":"ring/compiling_middleware.md","ref":"ring/compiling_middleware.md","articles":[]},"previous":{"title":"Pluggable Coercion","level":"1.5.4","depth":2,"path":"ring/coercion.md","ref":"ring/coercion.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/route_data_validation.md","mtime":"2018-02-11T19:35:28.398Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-11T19:36:06.764Z"},"basePath":"..","book":{"language":""}});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue