From b3a24f2908ff8fb543a7027a0a344819153b71a4 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sun, 2 Sep 2018 19:40:25 +0300 Subject: [PATCH] http --- doc/http/interceptors.md | 82 +++++++++------------------------------- 1 file changed, 17 insertions(+), 65 deletions(-) diff --git a/doc/http/interceptors.md b/doc/http/interceptors.md index 011c15b6..d3ec0a2c 100644 --- a/doc/http/interceptors.md +++ b/doc/http/interceptors.md @@ -1,77 +1,29 @@ # 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 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 -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). +```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 -### Standalone +### Sieppari -* [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}) -``` +See code at: https://github.com/metosin/reitit/tree/master/examples/http ### Pedestal -**TODO** +See example at: https://github.com/metosin/reitit/tree/master/examples/pedestal