This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-11
Channels
- # aws (2)
- # beginners (38)
- # boot (21)
- # boot-dev (8)
- # cider (51)
- # cljsrn (3)
- # clojars (23)
- # clojure (99)
- # clojure-austin (7)
- # clojure-brasil (1)
- # clojure-dev (8)
- # clojure-dusseldorf (1)
- # clojure-estonia (20)
- # clojure-greece (4)
- # clojure-italy (3)
- # clojure-russia (1)
- # clojure-spec (28)
- # clojure-uk (47)
- # clojurescript (47)
- # core-logic (3)
- # cursive (9)
- # data-science (1)
- # datomic (50)
- # docs (12)
- # emacs (5)
- # fulcro (60)
- # graphql (33)
- # hoplon (8)
- # jobs-discuss (1)
- # keechma (31)
- # lein-figwheel (10)
- # leiningen (4)
- # off-topic (70)
- # om (1)
- # onyx (15)
- # pedestal (5)
- # re-frame (185)
- # reagent (14)
- # remote-jobs (8)
- # ring-swagger (7)
- # rum (17)
- # shadow-cljs (193)
- # specter (6)
- # sql (51)
- # unrepl (8)
http://pedestal.io/reference/servlet-interceptor Says this: Before invoking the :enter functions, the servlet interceptor sets up a “terminator” predicate on the context. It terminates the interceptor chain when the context map returned by an interceptor has a response map attached. My server has this:
(ns wp-server.server
(:gen-class) ; for -main method in uberjar
(:require
[io.pedestal.http :as server]
[io.pedestal.http.route :as route]
[wp-server.service :as service]
[wp-server.datomic :as datomic]))
(defonce runnable-service (atom nil))
(defn -main
"The entry-point for 'lein run'"
[& args]
(println "/nConnecting to datomic...")
(datomic/connect!)
(println "\nCreating your server...")
(reset! runnable-service (server/create-servlet service/service))
(server/start runnable-service))
(defn create-runnable-dev-service
"The entry-point for 'lein run-dev'"
[& args]
(println "\nConnecting to [DEV] database...")
(datomic/connect-dev!)
(println "\nCreating your [DEV] server...")
(-> service/service
(merge {:env :dev
::server/join? false
::server/routes #(route/expand-routes (deref #'service/routes))
::server/allowed-origins {:creds true :allowed-origins (constantly true)}
::server/secure-headers {:content-security-policy-settings {:object-src "none"}}})
server/default-interceptors
server/dev-interceptors
server/create-servlet))
My service looks like this:
(ns wp-server.service
(:require
[datomic.api :as d]
[io.pedestal.http :as http]
[io.pedestal.http.body-params :as body-params]
[io.pedestal.http.route :as route]
[ring.util.response :as ring-resp]
[wp-server.datomic :as datomic]
[wp-common.client :as wp-common-client]
[wp-common.core :as wp-common-core]
[clojure.spec.alpha :as s]
[ring.util.response :as ring-response]))
(def home-page
{:name :home-page
:enter (fn [context]
(prn "TWO")
(assoc context :response {:status 200 :body "Hello, world!"}))})
(def common-interceptors [datomic/db-interceptor (body-params/body-params) http/html-body])
(defn create-spec-validator
[spec]
{:name :validate-spec
:enter
(fn [{{:keys [:edn-params]} :request :as context}]
(prn "ONE")
(if-let [explained (s/explain-data spec edn-params)]
(assoc context
:response {:status 400 :body explained})))})
(def routes #{
;["/" :get (conj common-interceptors `home-page)]
["/clients" :post (conj common-interceptors (create-spec-validator ::wp-common-client/schema) home-page)]
["/db-test" :get (conj common-interceptors `db-test-page)]
["/about" :get (conj common-interceptors `about-page)]})
(def service {:env :prod
::http/routes routes
::http/type :jetty
::http/port 5000
::http/container-options {:h2c? true
:h2? false
:ssl? false}})
When sending a request to localhost:5000/clients with a body that does not pass spec, the create-spec-validator interceptor adds a response to the context. I have confirmed this by logging the context in the home-page interceptor. I would expect the home-page interceptor to be skipped as per documentation. This does not happen. Instead the :enter function of the home-page interceptor is called and the response overwritten.
Why isn’t the home-page interceptor being skipped when the create-spec-validator prior to it is returning context with a response?the SO post for this is https://stackoverflow.com/questions/48198671/pedestal-early-termination-is-not-working
I need to use io.pedestal.interceptor.chain/terminate. We believe those docs are out of data
@caleb.macdonaldblack Might not be an issue here, but your :validate-spec
interceptor does not return the context
on a successful validation. If you return nil
, does Pedestal assume the unmodified context?
@caleb.macdonaldblack Here you go: the :response
has to be a valid response according to ring.util.response/response?
, so it needs to be a map with :status
and :headers
:
(defn response?
"True if the supplied value is a valid response map."
{:added "1.1"}
[resp]
(and (map? resp)
(integer? (:status resp))
(map? (:headers resp))))