mirror of
https://github.com/metosin/reitit.git
synced 2026-02-07 04:13:12 +00:00
commit
e25c90010d
17 changed files with 165 additions and 223 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"root": "doc",
|
"root": "doc",
|
||||||
"plugins": ["editlink", "github", "highlight"],
|
"plugins": ["hints", "editlink", "github", "highlight"],
|
||||||
"pluginsConfig": {
|
"pluginsConfig": {
|
||||||
"editlink": {
|
"editlink": {
|
||||||
"base": "https://github.com/metosin/reitit/tree/master/doc",
|
"base": "https://github.com/metosin/reitit/tree/master/doc",
|
||||||
|
|
|
||||||
|
|
@ -1,46 +1,63 @@
|
||||||
# Summary
|
# Summary
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
* [Introduction](README.md)
|
* [Introduction](README.md)
|
||||||
* [Basics](basics/README.md)
|
|
||||||
* [Route Syntax](basics/route_syntax.md)
|
## Basics
|
||||||
* [Router](basics/router.md)
|
|
||||||
* [Path-based Routing](basics/path_based_routing.md)
|
* [Route Syntax](basics/route_syntax.md)
|
||||||
* [Name-based Routing](basics/name_based_routing.md)
|
* [Router](basics/router.md)
|
||||||
* [Route Data](basics/route_data.md)
|
* [Path-based Routing](basics/path_based_routing.md)
|
||||||
* [Route Data Validation](basics/route_data_validation.md)
|
* [Name-based Routing](basics/name_based_routing.md)
|
||||||
* [Route Conflicts](basics/route_conflicts.md)
|
* [Route Data](basics/route_data.md)
|
||||||
* [Coercion](coercion/README.md)
|
* [Route Data Validation](basics/route_data_validation.md)
|
||||||
* [Coercion Explained](coercion/coercion.md)
|
* [Route Conflicts](basics/route_conflicts.md)
|
||||||
* [Plumatic Schema](coercion/schema_coercion.md)
|
|
||||||
* [Clojure.spec](coercion/clojure_spec_coercion.md)
|
## Coercion
|
||||||
* [Data-specs](coercion/data_spec_coercion.md)
|
|
||||||
* [Ring](ring/README.md)
|
* [Coercion Explained](coercion/coercion.md)
|
||||||
* [Ring-router](ring/ring.md)
|
* [Plumatic Schema](coercion/schema_coercion.md)
|
||||||
* [Reverse-routing](ring/reverse_routing.md)
|
* [Clojure.spec](coercion/clojure_spec_coercion.md)
|
||||||
* [Default handler](ring/default_handler.md)
|
* [Data-specs](coercion/data_spec_coercion.md)
|
||||||
* [Static Resources](ring/static.md)
|
|
||||||
* [Dynamic Extensions](ring/dynamic_extensions.md)
|
## Ring
|
||||||
* [Data-driven Middleware](ring/data_driven_middleware.md)
|
|
||||||
* [Transforming Middleware Chain](ring/transforming_middleware_chain.md)
|
* [Ring-router](ring/ring.md)
|
||||||
* [Middleware Registry](ring/middleware_registry.md)
|
* [Reverse-routing](ring/reverse_routing.md)
|
||||||
* [Default Middleware](ring/default_middleware.md)
|
* [Default handler](ring/default_handler.md)
|
||||||
* [Pluggable Coercion](ring/coercion.md)
|
* [Static Resources](ring/static.md)
|
||||||
* [Route Data Validation](ring/route_data_validation.md)
|
* [Dynamic Extensions](ring/dynamic_extensions.md)
|
||||||
* [Compiling Middleware](ring/compiling_middleware.md)
|
* [Data-driven Middleware](ring/data_driven_middleware.md)
|
||||||
* [Swagger Support](ring/swagger.md)
|
* [Transforming Middleware Chain](ring/transforming_middleware_chain.md)
|
||||||
* [Advanced](advanced/README.md)
|
* [Middleware Registry](ring/middleware_registry.md)
|
||||||
* [Configuring Routers](advanced/configuring_routers.md)
|
* [Default Middleware](ring/default_middleware.md)
|
||||||
* [Composing Routers](advanced/composing_routers.md)
|
* [Pluggable Coercion](ring/coercion.md)
|
||||||
* [Different Routers](advanced/different_routers.md)
|
* [Route Data Validation](ring/route_data_validation.md)
|
||||||
* [Route Validation](advanced/route_validation.md)
|
* [Compiling Middleware](ring/compiling_middleware.md)
|
||||||
* [Dev Workflow](advanced/dev_workflow.md)
|
* [Swagger Support](ring/swagger.md)
|
||||||
* [Patterns](patterns/README.md)
|
|
||||||
* [Shared Routes](patterns/shared_routes.md)
|
## Frontend
|
||||||
* [Frontend](frontend/README.md)
|
|
||||||
* [Basics](frontend/basics.md)
|
* [Basics](frontend/basics.md)
|
||||||
* [Browser integration](frontend/browser.md)
|
* [Browser integration](frontend/browser.md)
|
||||||
* [Controllers (WIP)](frontend/controllers.md)
|
* [Controllers (WIP)](frontend/controllers.md)
|
||||||
|
|
||||||
|
## HTTP
|
||||||
|
|
||||||
|
* [Interceptors](http/interceptors.md)
|
||||||
|
|
||||||
|
## Advanced
|
||||||
|
|
||||||
|
* [Configuring Routers](advanced/configuring_routers.md)
|
||||||
|
* [Composing Routers](advanced/composing_routers.md)
|
||||||
|
* [Different Routers](advanced/different_routers.md)
|
||||||
|
* [Route Validation](advanced/route_validation.md)
|
||||||
|
* [Dev Workflow](advanced/dev_workflow.md)
|
||||||
|
* [Shared Routes](advanced/shared_routes.md)
|
||||||
|
|
||||||
|
## Misc
|
||||||
|
|
||||||
* [Performance](performance.md)
|
* [Performance](performance.md)
|
||||||
* [Interceptors (WIP)](interceptors.md)
|
|
||||||
* [Development Instructions](development.md)
|
* [Development Instructions](development.md)
|
||||||
* [FAQ](faq.md)
|
* [FAQ](faq.md)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# Advanced
|
|
||||||
|
|
||||||
* [Configuring Routers](configuring_routers.md)
|
|
||||||
* [Composing Routers](composing_routers.md)
|
|
||||||
* [Different Routers](different_routers.md)
|
|
||||||
* [Route Validation](route_validation.md)
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
# Basics
|
|
||||||
|
|
||||||
* [Route Syntax](route_syntax.md)
|
|
||||||
* [Router](router.md)
|
|
||||||
* [Path-based Routing](path_based_routing.md)
|
|
||||||
* [Name-based Routing](name_based_routing.md)
|
|
||||||
* [Route Data](route_data.md)
|
|
||||||
* [Route Data Validation](route_data_validation.md)
|
|
||||||
* [Route Conflicts](route_conflicts.md)
|
|
||||||
|
|
@ -9,56 +9,47 @@
|
||||||
:cljdoc.doc/tree
|
:cljdoc.doc/tree
|
||||||
[["Introduction" {:file "doc/README.md"}]
|
[["Introduction" {:file "doc/README.md"}]
|
||||||
["Basics"
|
["Basics"
|
||||||
{:file "doc/basics/README.md"}
|
|
||||||
["Route Syntax" {:file "doc/basics/route_syntax.md"}]
|
["Route Syntax" {:file "doc/basics/route_syntax.md"}]
|
||||||
["Router" {:file "doc/basics/router.md"}]
|
["Router" {:file "doc/basics/router.md"}]
|
||||||
["Path-based Routing" {:file "doc/basics/path_based_routing.md"}]
|
["Path-based Routing" {:file "doc/basics/path_based_routing.md"}]
|
||||||
["Name-based Routing" {:file "doc/basics/name_based_routing.md"}]
|
["Name-based Routing" {:file "doc/basics/name_based_routing.md"}]
|
||||||
["Route Data" {:file "doc/basics/route_data.md"}]
|
["Route Data" {:file "doc/basics/route_data.md"}]
|
||||||
["Route Data Validation"
|
["Route Data Validation" {:file "doc/basics/route_data_validation.md"}]
|
||||||
{:file "doc/basics/route_data_validation.md"}]
|
|
||||||
["Route Conflicts" {:file "doc/basics/route_conflicts.md"}]]
|
["Route Conflicts" {:file "doc/basics/route_conflicts.md"}]]
|
||||||
["Coercion"
|
["Coercion"
|
||||||
{:file "doc/coercion/README.md"}
|
|
||||||
["Coercion Explained" {:file "doc/coercion/coercion.md"}]
|
["Coercion Explained" {:file "doc/coercion/coercion.md"}]
|
||||||
["Plumatic Schema" {:file "doc/coercion/schema_coercion.md"}]
|
["Plumatic Schema" {:file "doc/coercion/schema_coercion.md"}]
|
||||||
["Clojure.spec" {:file "doc/coercion/clojure_spec_coercion.md"}]
|
["Clojure.spec" {:file "doc/coercion/clojure_spec_coercion.md"}]
|
||||||
["Data-specs" {:file "doc/coercion/data_spec_coercion.md"}]]
|
["Data-specs" {:file "doc/coercion/data_spec_coercion.md"}]]
|
||||||
["Ring"
|
["Ring"
|
||||||
{:file "doc/ring/README.md"}
|
|
||||||
["Ring-router" {:file "doc/ring/ring.md"}]
|
["Ring-router" {:file "doc/ring/ring.md"}]
|
||||||
["Reverse-routing" {:file "doc/ring/reverse_routing.md"}]
|
["Reverse-routing" {:file "doc/ring/reverse_routing.md"}]
|
||||||
["Default handler" {:file "doc/ring/default_handler.md"}]
|
["Default handler" {:file "doc/ring/default_handler.md"}]
|
||||||
["Static Resources" {:file "doc/ring/static.md"}]
|
["Static Resources" {:file "doc/ring/static.md"}]
|
||||||
["Dynamic Extensions" {:file "doc/ring/dynamic_extensions.md"}]
|
["Dynamic Extensions" {:file "doc/ring/dynamic_extensions.md"}]
|
||||||
["Data-driven Middleware"
|
["Data-driven Middleware" {:file "doc/ring/data_driven_middleware.md"}]
|
||||||
{:file "doc/ring/data_driven_middleware.md"}]
|
["Transforming Middleware Chain" {:file "doc/ring/transforming_middleware_chain.md"}]
|
||||||
["Transforming Middleware Chain"
|
|
||||||
{:file "doc/ring/transforming_middleware_chain.md"}]
|
|
||||||
["Middleware Registry" {:file "doc/ring/middleware_registry.md"}]
|
["Middleware Registry" {:file "doc/ring/middleware_registry.md"}]
|
||||||
["Default Middleware" {:file "doc/ring/default_middleware.md"}]
|
["Default Middleware" {:file "doc/ring/default_middleware.md"}]
|
||||||
["Pluggable Coercion" {:file "doc/ring/coercion.md"}]
|
["Pluggable Coercion" {:file "doc/ring/coercion.md"}]
|
||||||
["Route Data Validation"
|
["Route Data Validation" {:file "doc/ring/route_data_validation.md"}]
|
||||||
{:file "doc/ring/route_data_validation.md"}]
|
|
||||||
["Compiling Middleware" {:file "doc/ring/compiling_middleware.md"}]
|
["Compiling Middleware" {:file "doc/ring/compiling_middleware.md"}]
|
||||||
["Swagger Support" {:file "doc/ring/swagger.md"}]]
|
["Swagger Support" {:file "doc/ring/swagger.md"}]]
|
||||||
["Advanced"
|
|
||||||
{:file "doc/advanced/README.md"}
|
|
||||||
["Configuring Routers"
|
|
||||||
{:file "doc/advanced/configuring_routers.md"}]
|
|
||||||
["Composing Routers" {:file "doc/advanced/composing_routers.md"}]
|
|
||||||
["Different Routers" {:file "doc/advanced/different_routers.md"}]
|
|
||||||
["Route Validation" {:file "doc/advanced/route_validation.md"}]
|
|
||||||
["Dev Workflow" {:file "doc/advanced/dev_workflow.md"}]]
|
|
||||||
["Patterns"
|
|
||||||
{:file "doc/patterns/README.md"}
|
|
||||||
["Shared Routes" {:file "doc/patterns/shared_routes.md"}]]
|
|
||||||
["Frontend"
|
["Frontend"
|
||||||
{:file "doc/frontend/README.md"}
|
|
||||||
["Basics" {:file "doc/frontend/basics.md"}]
|
["Basics" {:file "doc/frontend/basics.md"}]
|
||||||
["Browser integration" {:file "doc/frontend/browser.md"}]
|
["Browser integration" {:file "doc/frontend/browser.md"}]
|
||||||
["Controllers (WIP)" {:file "doc/frontend/controllers.md"}]]
|
["Controllers (WIP)" {:file "doc/frontend/controllers.md"}]]
|
||||||
["Performance" {:file "doc/performance.md"}]
|
["HTTP"
|
||||||
["Interceptors (WIP)" {:file "doc/interceptors.md"}]
|
["Interceptors" {:file "doc/http/interceptors.md"}]]
|
||||||
["Development Instructions" {:file "doc/development.md"}]
|
["Advanced"
|
||||||
["FAQ" {:file "doc/faq.md"}]]}
|
["Configuring Routers" {:file "doc/advanced/configuring_routers.md"}]
|
||||||
|
["Composing Routers" {:file "doc/advanced/composing_routers.md"}]
|
||||||
|
["Different Routers" {:file "doc/advanced/different_routers.md"}]
|
||||||
|
["Route Validation" {:file "doc/advanced/route_validation.md"}]
|
||||||
|
["Dev Workflow" {:file "doc/advanced/dev_workflow.md"}]
|
||||||
|
["Shared Routes" {:file "doc/patterns/shared_routes.md"}]]
|
||||||
|
["Misc"
|
||||||
|
["Performance" {:file "doc/performance.md"}]
|
||||||
|
["Interceptors (WIP)" {:file "doc/interceptors.md"}]
|
||||||
|
["Development Instructions" {:file "doc/development.md"}]
|
||||||
|
["FAQ" {:file "doc/faq.md"}]]]}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# Coercion
|
|
||||||
|
|
||||||
* [Coercion Explained](coercion.md)
|
|
||||||
* [Plumatic Schema](schema_coercion.md)
|
|
||||||
* [Clojure.spec](clojure_spec_coercion.md)
|
|
||||||
* [Data-specs](data_spec_coercion.md)
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
# Frontend
|
|
||||||
|
|
||||||
* [Basics](basics.md)
|
|
||||||
* [Browser integration](browser.md)
|
|
||||||
* [Controllers (WIP)](controllers.md)
|
|
||||||
29
doc/http/interceptors.md
Normal file
29
doc/http/interceptors.md
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Interceptors (WIP)
|
||||||
|
|
||||||
|
Reitit also support for [Pedestal](pedestal.io)-style [interceptors](http://pedestal.io/reference/interceptors) as an alternative to using middleware. Basic interceptor handling is implemented in `reitit.interceptor` package. There is no interceptor executor shipped, but you can use libraries like [Pedestal Interceptor](https://github.com/pedestal/pedestal/tree/master/interceptor) or [Sieppari](https://github.com/metosin/sieppari) to execute the chains.
|
||||||
|
|
||||||
|
## Current Status
|
||||||
|
|
||||||
|
Work-in-progress and considered alpha quality.
|
||||||
|
|
||||||
|
## Reitit-http
|
||||||
|
|
||||||
|
```clj
|
||||||
|
[metosin/reitit-http "0.2.0-alpha1"]
|
||||||
|
```
|
||||||
|
|
||||||
|
An module for http-routing using interceptors instead of middleware. Builds on top of the [`reitit-ring`](../ring/ring.md) module. The differences:
|
||||||
|
|
||||||
|
* instead of `:middleware`, uses `:interceptors`
|
||||||
|
* compared to `reitit.http/http-router` takes an extra options map with mandatory key `:executor` (of type `reitit.interceptor/Executor`) and optional top level `:interceptors` - wrapping both routes and default handler.
|
||||||
|
* optional entry poitn `reitit.http/routing-interceptor` to provide a routing interceptor, to be used with Pedestal.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Sieppari
|
||||||
|
|
||||||
|
See code at: https://github.com/metosin/reitit/tree/master/examples/http
|
||||||
|
|
||||||
|
### Pedestal
|
||||||
|
|
||||||
|
See example at: https://github.com/metosin/reitit/tree/master/examples/pedestal
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
# Interceptors (WIP)
|
|
||||||
|
|
||||||
Reitit also support for [Pedestal](pedestal.io)-style [interceptors](http://pedestal.io/reference/interceptors) as an alternative to Middleware. Basic interceptor handling is implemented in `reitit.interceptor` package. There is no interceptor executor shipped, but you can use libraries like [Pedestal Interceptor](https://github.com/pedestal/pedestal/tree/master/interceptor) or [Sieppari](https://github.com/metosin/sieppari) to execute the chains.
|
|
||||||
|
|
||||||
## Reitit-http
|
|
||||||
|
|
||||||
An alternative to `reitit-ring`, using interceptors instead of middleware. Currently not finalized, you can track progress in [here](https://github.com/metosin/reitit/pull/124).
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
### Standalone
|
|
||||||
|
|
||||||
* [Sieppari](https://github.com/metosin/sieppari) for executing the chain
|
|
||||||
* [Manifold](https://github.com/ztellman/manifold) for async
|
|
||||||
* [data-specs](https://github.com/metosin/spec-tools/blob/master/README.md#data-specs) for coercion
|
|
||||||
|
|
||||||
```clj
|
|
||||||
(require '[reitit.interceptor.sieppari :as sieppari])
|
|
||||||
(require '[reitit.http.coercion :as coercion])
|
|
||||||
(require '[reitit.http :as http])
|
|
||||||
(require '[reitit.ring :as ring])
|
|
||||||
(require '[reitit.coercion.spec])
|
|
||||||
(require '[clojure.set :as set])
|
|
||||||
(require '[manifold.deferred :as d])
|
|
||||||
(require '[ring.adapter.jetty :as jetty])
|
|
||||||
|
|
||||||
(def auth-interceptor
|
|
||||||
"Interceptor that mounts itself if route has `:roles` data. Expects `:roles`
|
|
||||||
to be a set of keyword and the context to have `[:user :roles]` with user roles.
|
|
||||||
responds with HTTP 403 if user doesn't have the roles defined, otherwise no-op."
|
|
||||||
{:name ::auth
|
|
||||||
:compile (fn [{:keys [roles]} _]
|
|
||||||
(if (seq roles)
|
|
||||||
{:description (str "requires roles " roles)
|
|
||||||
:spec {:roles #{keyword?}}
|
|
||||||
:context-spec {:user {:roles #{keyword}}}
|
|
||||||
:enter (fn [{{user-roles :roles} :user :as ctx}]
|
|
||||||
(if (not (set/subset? roles user-roles))
|
|
||||||
(assoc ctx :response {:status 403, :body "forbidden"})
|
|
||||||
ctx))}))})
|
|
||||||
|
|
||||||
(def async-interceptor
|
|
||||||
{:enter (fn [ctx] (d/future ctx))})
|
|
||||||
|
|
||||||
(def app
|
|
||||||
(http/ring-handler
|
|
||||||
(http/router
|
|
||||||
["/api" {:interceptors [async-interceptor auth-interceptor]}
|
|
||||||
["/ping" {:name ::ping
|
|
||||||
:get (constantly
|
|
||||||
{:status 200
|
|
||||||
:body "pong"})}]
|
|
||||||
["/plus/:z" {:name ::plus
|
|
||||||
:post {:parameters {:query {:x int?}
|
|
||||||
:body {:y int?}
|
|
||||||
:path {:z int?}}
|
|
||||||
:responses {200 {:body {:total pos-int?}}}
|
|
||||||
:roles #{:admin}
|
|
||||||
:handler (fn [{:keys [parameters]}]
|
|
||||||
(let [total (+ (-> parameters :query :x)
|
|
||||||
(-> parameters :body :y)
|
|
||||||
(-> parameters :path :z))]
|
|
||||||
{:status 200
|
|
||||||
:body {:total total}}))}}]]
|
|
||||||
{:data {:coercion reitit.coercion.spec/coercion
|
|
||||||
:interceptors [coercion/coerce-exceptions-interceptor
|
|
||||||
coercion/coerce-request-interceptor
|
|
||||||
coercion/coerce-response-interceptor]}})
|
|
||||||
(ring/create-default-handler)
|
|
||||||
{:executor sieppari/executor}))
|
|
||||||
|
|
||||||
(jetty/run-jetty #'app {:port 3000, :join? false, :async? true})
|
|
||||||
```
|
|
||||||
|
|
||||||
### Pedestal
|
|
||||||
|
|
||||||
**TODO**
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# Patterns
|
|
||||||
|
|
||||||
* [Shared Routes](shared_routes.md)
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
# Ring
|
|
||||||
|
|
||||||
* [Ring-router](ring.md)
|
|
||||||
* [Reverse-routing](reverse_routing.md)
|
|
||||||
* [Default handler](default_handler.md)
|
|
||||||
* [Static Resources](static.md)
|
|
||||||
* [Dynamic Extensions](dynamic_extensions.md)
|
|
||||||
* [Data-driven Middleware](data_driven_middleware.md)
|
|
||||||
* [Transforming Middleware Chain](transforming_middleware_chain.md)
|
|
||||||
* [Middleware Registry](middleware_registry.md)
|
|
||||||
* [Default Middleware](default_middleware.md)
|
|
||||||
* [Pluggable Coercion](coercion.md)
|
|
||||||
* [Route Data Validation](route_data_validation.md)
|
|
||||||
* [Compiling Middleware](compiling_middleware.md)
|
|
||||||
* [Swagger Support](swagger.md)
|
|
||||||
|
|
@ -10,8 +10,10 @@
|
||||||
Go with browser to:
|
Go with browser to:
|
||||||
|
|
||||||
* http://localhost:3000/api/sync - synchronous
|
* http://localhost:3000/api/sync - synchronous
|
||||||
* http://localhost:3000/api/async - with core.async
|
* http://localhost:3000/api/async - with [core.async](https://github.com/clojure/core.async) channels
|
||||||
* http://localhost:3000/api/future - with futures
|
* http://localhost:3000/api/future - with [futures](https://clojuredocs.org/clojure.core/future)
|
||||||
|
* http://localhost:3000/api/deferred - with [manifold](https://github.com/ztellman/manifold) deferred
|
||||||
|
* http://localhost:3000/api/promesa - with [promesa](http://funcool.github.io/promesa/latest/) promises
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
:description "Reitit Ring App with Swagger"
|
:description "Reitit Ring App with Swagger"
|
||||||
:dependencies [[org.clojure/clojure "1.9.0"]
|
:dependencies [[org.clojure/clojure "1.9.0"]
|
||||||
[org.clojure/core.async "0.4.474"]
|
[org.clojure/core.async "0.4.474"]
|
||||||
|
[funcool/promesa "1.9.0"]
|
||||||
|
[manifold "0.1.8"]
|
||||||
[ring "1.6.3"]
|
[ring "1.6.3"]
|
||||||
[metosin/reitit "0.2.0-alpha1"]]
|
[metosin/reitit "0.2.0-alpha1"]]
|
||||||
:repl-options {:init-ns example.server})
|
:repl-options {:init-ns example.server})
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,62 @@
|
||||||
(ns example.server
|
(ns example.server
|
||||||
(:require [reitit.http :as http]
|
(:require [reitit.http :as http]
|
||||||
[reitit.ring :as ring]
|
[reitit.ring :as ring]
|
||||||
[clojure.core.async :as a]
|
|
||||||
[reitit.interceptor.sieppari]
|
[reitit.interceptor.sieppari]
|
||||||
[ring.adapter.jetty :as jetty]))
|
[ring.adapter.jetty :as jetty]
|
||||||
|
[muuntaja.interceptor]
|
||||||
|
[clojure.core.async :as a]
|
||||||
|
[manifold.deferred :as d]
|
||||||
|
[promesa.core :as p]))
|
||||||
|
|
||||||
(defn -interceptor [f x]
|
(defn interceptor [f x]
|
||||||
{:enter (fn [ctx] (f (update-in ctx [:request :via] (fnil conj []) x)))
|
{:enter (fn [ctx] (f (update-in ctx [:request :via] (fnil conj []) {:enter x})))
|
||||||
:leave (fn [ctx] (f (update-in ctx [:response :body] str "\n<- " x)))})
|
:leave (fn [ctx] (f (update-in ctx [:response :body] conj {:leave x})))})
|
||||||
|
|
||||||
(def interceptor (partial -interceptor identity))
|
(defn handler [f]
|
||||||
(def future-interceptor (partial -interceptor #(future %)))
|
(fn [{:keys [via]}]
|
||||||
(def async-interceptor (partial -interceptor #(a/go %)))
|
(f {:status 200,
|
||||||
|
:body (conj via :handler)})))
|
||||||
|
|
||||||
(defn -handler [f {:keys [via]}]
|
(def <sync> identity)
|
||||||
(f {:status 200,
|
(def <future> #(future %))
|
||||||
:body (str (apply str (map #(str "-> " % "\n") via)) " hello!")}))
|
(def <async> #(a/go %))
|
||||||
|
(def <deferred> d/success-deferred)
|
||||||
(def handler (partial -handler identity))
|
(def <promesa> p/promise)
|
||||||
(def future-handler (partial -handler #(future %)))
|
|
||||||
(def async-handler (partial -handler #(a/go %)))
|
|
||||||
|
|
||||||
(def app
|
(def app
|
||||||
(http/ring-handler
|
(http/ring-handler
|
||||||
(http/router
|
(http/router
|
||||||
["/api"
|
["/api"
|
||||||
{:interceptors [(interceptor :api)]}
|
{:interceptors [(interceptor <sync> :api)]}
|
||||||
|
|
||||||
["/sync"
|
["/sync"
|
||||||
{:interceptors [(interceptor :sync)]
|
{:interceptors [(interceptor <sync> :sync)]
|
||||||
:get {:interceptors [(interceptor :hello)]
|
:get {:interceptors [(interceptor <sync> :get)]
|
||||||
:handler handler}}]
|
:handler (handler <sync>)}}]
|
||||||
|
|
||||||
["/future"
|
["/future"
|
||||||
{:interceptors [(future-interceptor :future)]
|
{:interceptors [(interceptor <future> :future)]
|
||||||
:get {:interceptors [(future-interceptor :hello)]
|
:get {:interceptors [(interceptor <future> :get)]
|
||||||
:handler future-handler}}]
|
:handler (handler <future>)}}]
|
||||||
|
|
||||||
["/async"
|
["/async"
|
||||||
{:interceptors [(async-interceptor :async)]
|
{:interceptors [(interceptor <async> :async)]
|
||||||
:get {:interceptors [(async-interceptor :async-hello)]
|
:get {:interceptors [(interceptor <async> :get)]
|
||||||
:handler async-handler}}]])
|
:handler (handler <async>)}}]
|
||||||
|
|
||||||
|
["/deferred"
|
||||||
|
{:interceptors [(interceptor <deferred> :deferred)]
|
||||||
|
:get {:interceptors [(interceptor <deferred> :get)]
|
||||||
|
:handler (handler <deferred>)}}]
|
||||||
|
|
||||||
|
["/promesa"
|
||||||
|
{:interceptors [(interceptor <promesa> :promesa)]
|
||||||
|
:get {:interceptors [(interceptor <promesa> :get)]
|
||||||
|
:handler (handler <promesa>)}}]])
|
||||||
|
|
||||||
(ring/create-default-handler)
|
(ring/create-default-handler)
|
||||||
{:executor reitit.interceptor.sieppari/executor}))
|
{:executor reitit.interceptor.sieppari/executor
|
||||||
|
:interceptors [(muuntaja.interceptor/format-interceptor)]}))
|
||||||
|
|
||||||
(defn start []
|
(defn start []
|
||||||
(jetty/run-jetty #'app {:port 3000, :join? false, :async? true})
|
(jetty/run-jetty #'app {:port 3000, :join? false, :async? true})
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,11 @@
|
||||||
["/upload"
|
["/upload"
|
||||||
{:post {:summary "upload a file"
|
{:post {:summary "upload a file"
|
||||||
:parameters {:multipart {:file multipart/temp-file-part}}
|
:parameters {:multipart {:file multipart/temp-file-part}}
|
||||||
:responses {200 {:body {:file multipart/temp-file-part}}}
|
:responses {200 {:body {:name string?, :size int?}}}
|
||||||
:handler (fn [{{{:keys [file]} :multipart} :parameters}]
|
:handler (fn [{{{:keys [file]} :multipart} :parameters}]
|
||||||
{:status 200
|
{:status 200
|
||||||
:body {:file file}})}}]
|
:body {:name (:filename file)
|
||||||
|
:size (:size file)}})}}]
|
||||||
|
|
||||||
["/download"
|
["/download"
|
||||||
{:get {:summary "downloads a file"
|
{:get {:summary "downloads a file"
|
||||||
|
|
@ -37,7 +38,8 @@
|
||||||
:handler (fn [_]
|
:handler (fn [_]
|
||||||
{:status 200
|
{:status 200
|
||||||
:headers {"Content-Type" "image/png"}
|
:headers {"Content-Type" "image/png"}
|
||||||
:body (io/input-stream (io/resource "reitit.png"))})}}]]
|
:body (io/input-stream
|
||||||
|
(io/resource "reitit.png"))})}}]]
|
||||||
|
|
||||||
["/math"
|
["/math"
|
||||||
{:swagger {:tags ["math"]}}
|
{:swagger {:tags ["math"]}}
|
||||||
|
|
|
||||||
12
project.clj
12
project.clj
|
|
@ -27,7 +27,7 @@
|
||||||
[metosin/ring-swagger-ui "2.2.10"]
|
[metosin/ring-swagger-ui "2.2.10"]
|
||||||
[metosin/muuntaja "0.6.0-alpha5"]
|
[metosin/muuntaja "0.6.0-alpha5"]
|
||||||
[metosin/jsonista "0.2.1"]
|
[metosin/jsonista "0.2.1"]
|
||||||
[metosin/sieppari "0.0.0-alpha4"]]
|
[metosin/sieppari "0.0.0-alpha5"]]
|
||||||
|
|
||||||
:plugins [[jonase/eastwood "0.2.6"]
|
:plugins [[jonase/eastwood "0.2.6"]
|
||||||
[lein-doo "0.1.10"]
|
[lein-doo "0.1.10"]
|
||||||
|
|
@ -64,7 +64,7 @@
|
||||||
[ikitommi/immutant-web "3.0.0-alpha1"]
|
[ikitommi/immutant-web "3.0.0-alpha1"]
|
||||||
[metosin/muuntaja "0.6.0-alpha5"]
|
[metosin/muuntaja "0.6.0-alpha5"]
|
||||||
[metosin/ring-swagger-ui "2.2.10"]
|
[metosin/ring-swagger-ui "2.2.10"]
|
||||||
[metosin/sieppari "0.0.0-alpha4"]
|
[metosin/sieppari "0.0.0-alpha5"]
|
||||||
[metosin/jsonista "0.2.1"]
|
[metosin/jsonista "0.2.1"]
|
||||||
|
|
||||||
[criterium "0.4.4"]
|
[criterium "0.4.4"]
|
||||||
|
|
@ -72,6 +72,10 @@
|
||||||
[org.clojure/tools.namespace "0.2.11"]
|
[org.clojure/tools.namespace "0.2.11"]
|
||||||
[com.gfredericks/test.chuck "0.2.9"]
|
[com.gfredericks/test.chuck "0.2.9"]
|
||||||
|
|
||||||
|
[org.clojure/core.async "0.4.474"]
|
||||||
|
[manifold "0.1.8"]
|
||||||
|
[funcool/promesa "1.9.0"]
|
||||||
|
|
||||||
;; https://github.com/bensu/doo/issues/180
|
;; https://github.com/bensu/doo/issues/180
|
||||||
[fipp "0.6.12"]]}
|
[fipp "0.6.12"]]}
|
||||||
:perf {:jvm-opts ^:replace ["-server"
|
:perf {:jvm-opts ^:replace ["-server"
|
||||||
|
|
@ -84,7 +88,9 @@
|
||||||
[io.pedestal/pedestal.service "0.5.4"]
|
[io.pedestal/pedestal.service "0.5.4"]
|
||||||
[io.pedestal/pedestal.jetty "0.5.4"]
|
[io.pedestal/pedestal.jetty "0.5.4"]
|
||||||
[org.clojure/core.async "0.4.474"]
|
[org.clojure/core.async "0.4.474"]
|
||||||
[metosin/sieppari "0.0.0-alpha4"]
|
[manifold "0.1.8"]
|
||||||
|
[funcool/promesa "1.9.0"]
|
||||||
|
[metosin/sieppari "0.0.0-alpha5"]
|
||||||
[yada "1.2.13"]
|
[yada "1.2.13"]
|
||||||
[ring/ring-defaults "0.3.2"]
|
[ring/ring-defaults "0.3.2"]
|
||||||
[ataraxy "0.4.0"]
|
[ataraxy "0.4.0"]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue