This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-04-13
Channels
- # beginners (42)
- # boot (33)
- # cider (4)
- # clara (1)
- # cljs-dev (2)
- # clojars (3)
- # clojure (207)
- # clojure-boston (1)
- # clojure-france (3)
- # clojure-india (7)
- # clojure-miami (1)
- # clojure-nl (8)
- # clojure-poland (13)
- # clojure-russia (102)
- # clojure-spec (22)
- # clojure-uk (37)
- # clojureremote (15)
- # clojurescript (229)
- # cursive (9)
- # datomic (1)
- # emacs (7)
- # figwheel (2)
- # funcool (1)
- # garden (1)
- # hoplon (7)
- # jobs (12)
- # jobs-discuss (27)
- # juxt (2)
- # leiningen (6)
- # luminus (9)
- # lumo (18)
- # off-topic (3)
- # onyx (9)
- # re-frame (54)
- # reagent (5)
- # remote-jobs (3)
- # ring (3)
- # rum (3)
- # specter (28)
- # yada (30)
@malcolmsparks I looked into extending Yada with those namespaced keywords on the resource. It would mean adding an extra arg or args to to-body
and render-map
+ render-seq
. E.g.:
(defprotocol MessageBody
(to-body [resource representation & [opts]] "Construct the reponse body for the given resource, given the negotiated representation (metadata)")
...)
(defmulti render-map (fn [resource representation & [opts]] (-> representation :media-type :name)))
(defmethod render-map "application/json"
[m representation & [opts]
(let [escape-non-ascii (get opts :yada.cheshire/escape-non-ascii)
pretty (get-in representation [:media-type :parameters "pretty"])]
(str (json/encode m {:pretty pretty :escape-non-ascii escape-non-ascii}) \newline)))
(defn create-response
[ctx]
(let [method (:method ctx)
produces (get-in ctx [:response :produces])
body (body/to-body (get-in ctx [:response :body]) produces (select-keys (:resource ctx) [:yada.cheshire/escape-non-ascii])
...
How do you feel about this solution?We could also pass all namespaced keys to the opts in create-response
to be less specific
And possibly doing this with other defmultis as well, but we can refactor this on a by need basis
I don't understand. Why can't you get the namespaced keyword from the resource / first param?
@dominicm Because that isn’t the Yada resource, but some object like a String or map
oh, so that pretty
parameter is supplied by the api consumer, not onto the resource or anything like that.
Worth noting that yada doesn't need to be configurable here. copy/paste programming is OK, and you can override the method with your own version, which knows the opts ahead of time.
dynamic vars are intended for ad-hoc options (it's why elisp defaults to dynamic scoping) so maybe that's preferred? Just thinking out loud here.
I don’t like dynamic vars that much, don’t know how they behave with Manifold etc. But yeah, overriding the methods is definitely an option.
Maybe to be more extensible, yada could separate implementations of protocols/multimethods into their own functions, and let them have their own rules of what they support (pass through chesire options & so on). That would make overriding it be as simple as:
(defmethod render-map "application/json" [m representation]
(yada.impl.render-map/cheshire m representation {:cheshire-opts {:ascii-thing true}})
I now have this, which is a pretty thin copy/paste operation:
(defmethod render-map "application/json"
[m representation]
(let [pretty (get-in representation [:media-type :parameters "pretty"])]
(str (json/encode m {:pretty pretty
:escape-non-ascii true})
\newline)))
You can have contracts that make sense with each impl. If it makes sense to have 5 params, you can.