Skip to content

Commit

Permalink
Add table-routes option to specify initial interceptors
Browse files Browse the repository at this point in the history
  • Loading branch information
hlship committed Oct 19, 2024
1 parent 4638f0e commit 4ab83b3
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 7 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ The main focus of this release is to improve routing.
- Sawtooth identfies conflicting routes
- Sawtooth is now the *default router*

Other changes:

- Table routes may now specify :interceptors (in the options map); these are prefixed on any
interceptors provided by the route

## 0.7.1 -- 27 Sep 2024

Changes:
Expand Down
8 changes: 8 additions & 0 deletions docs/modules/reference/pages/routing-quick-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ can also be differentiated by the host. A somewhat common example is an outward
application exposed outside a company's firewall on one port, and an inward-facing set of endpoints
for operations (status, metrics, management, and so forth) on a different port.

[WARNING]
====
Defining routes and setting up the servlet container are two separate functions; just because you have
a route mapped to a port or host doesn't mean that the servlet container is configured to accept
requests for that port or host. You have to connect those dots by setting up the servlet container's
configuration in the xref:service-map.adoc[].
====

== Library

The library api:*[ns=io.pedestal.http.route] namespace
Expand Down
3 changes: 3 additions & 0 deletions docs/modules/reference/pages/table-syntax.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ The "handler position" can be anything that satisfies the api:IntoInterceptor[ns
- Map
- List (of the above)

The options provided to `table-routes` may include an :interceptors key; this is a seq of interceptors that is
prefixed to any interceptors provided by the route.

=== Route Name Clause

A route name clause is the keyword :route-name followed by a keyword. Route names must be unique.
Expand Down
17 changes: 11 additions & 6 deletions route/src/io/pedestal/http/route/definition/table.clj
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
[{:keys [remaining] :as ctx}]
(error ctx (format "there were unused elements %s." remaining)))

(def ^:private known-options [:app-name :host :port :scheme :verbs])
(def ^:private known-options [:app-name :host :port :scheme :verbs :interceptors])
(def ^:private default-verbs #{:any :get :put :post :delete :patch :options :head})

(defn- make-parse-context
Expand Down Expand Up @@ -71,13 +71,16 @@

(defn- parse-handlers
[ctx]
(let [[handlers & more] (:remaining ctx)]
(let [{:keys [interceptors remaining]} ctx
[handlers & more] remaining]
(if (vector? handlers)
(assert (every? #(satisfies? interceptor/IntoInterceptor %) handlers) (syntax-error ctx "the vector of handlers" "a bunch of interceptors" handlers))
(assert (satisfies? interceptor/IntoInterceptor handlers) (syntax-error ctx "the handler" "an interceptor" handlers)))
(let [original-handlers (if (vector? handlers) (vec handlers) [handlers])
handlers (mapv interceptor/interceptor original-handlers)]
(assoc ctx :interceptors handlers
route-interceptors (map interceptor/interceptor original-handlers)
all-interceptors (into (vec interceptors)
route-interceptors)]
(assoc ctx :interceptors all-interceptors
:remaining more
:last-handler (last original-handlers)))))

Expand Down Expand Up @@ -142,9 +145,11 @@
The single parameter constructor looks for the first map as the options, then any other vectors
are the routes.
The options map may have keys :app-name, :host, :port, :scheme, and :verbs. The first four
The options map may have keys :app-name, :host, :port, :scheme, :interceptors, and :verbs. The first four
set the corresponding route keys of the routes; the :verbs key specifies the allowed verbs for
the routes."
the routes
The :interceptors option are a seq of interceptors that are prefixed to any interceptors specified in a route."
([routes]
(table-routes (or (first (filter map? routes)) {})
(filterv vector? routes)))
Expand Down
1 change: 1 addition & 0 deletions route/src/io/pedestal/http/route/specs.clj
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
::host
::port
::scheme
::interceptors
:io.pedestal.http.route.definition.table/verbs]))

(s/def :io.pedestal.http.route.definition.table/verbs (s/coll-of keyword?))
Expand Down
3 changes: 2 additions & 1 deletion tests/deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
nubank/matcher-combinators {:mvn/version "3.9.1"}
nubank/mockfn {:mvn/version "0.7.0"}
expound/expound {:mvn/version "0.9.0"}
medley/medley {:mvn/version "1.4.0"}

org.clojure/java.classpath {:mvn/version "1.1.0"}
org.clojure/tools.namespace {:mvn/version "1.5.0"}
Expand Down Expand Up @@ -76,7 +77,7 @@
{
:jvm-opts ["-Djdk.attach.allowAttachSelf"]
;; Need extra test runner to avoid test hangs
:exec-fn io.pedestal.test-runner/test}
:exec-fn io.pedestal.test-runner/test}

:otel
;; Enable the implementations of OpenTelemetry and configure sources, to allow experimenting at the REPL.
Expand Down
31 changes: 31 additions & 0 deletions tests/test/io/pedestal/http/route_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
[clojure.spec.test.alpha :as stest]
[clojure.spec.alpha :as s]
[expound.alpha :as expound]
[io.pedestal.http.route.definition.table :as table]
[io.pedestal.http.route.sawtooth :as sawtooth]
[io.pedestal.http.route.sawtooth.impl :as impl]
[io.pedestal.interceptor :refer [interceptor]]
io.pedestal.http.route.specs
[medley.core :as medley]
[ring.util.response :as ring-response]
[io.pedestal.interceptor.chain :as interceptor.chain]
[io.pedestal.http.route :as route :refer [expand-routes]]
Expand Down Expand Up @@ -1536,3 +1538,32 @@
(is (thrown-with-msg? ExceptionInfo
#"\QValue does not satisfy io.pedestal.http.route/ExpandableRoutes\E"
(expand-routes false))))

(def i-1
(interceptor {:name :i-1
:enter identity}))

(def i-2
(interceptor {:name :i-2
:enter identity}))

(def i-3
(interceptor {:name :i-3
:enter identity}))

(def handler
(interceptor {:name :handler
:enter identity}))

(deftest table-routes-interceptor-opt-is-prefix

(let [routes (table/table-routes {:interceptors [i-1 i-2]}
#{["/root/one" :get handler :route-name :one]
["/root/two" :get [i-3 handler] :route-name :two]
["/root/three" :get [handler] :route-name :three]})
by-name (medley/index-by :route-name (:routes routes))]
(is (match?
{:one {:interceptors [i-1 i-2 handler]}
:two {:interceptors [i-1 i-2 i-3 handler]}
:three {:interceptors [i-1 i-2 handler]}}
by-name))))

0 comments on commit 4ab83b3

Please sign in to comment.