Fork me on GitHub
#biff
<
2022-09-12
>
2FO22:09:38

Hello, I'm trying to inspect the req and response maps in the repl. I have following handler set-up with an inline def app.clj

(defn app [req]
  (def req)
  (ui/page
   {}
   [:div "Games"]))
router
(def features
  {:routes ["/app"
            ["" {:get app}]]})
after making a request to /app I evaluated the req var in the repl instead of the request map it returns:
#object[clojure.lang.Var$Unbound 0x6219bdef "Unbound: #']
How can I go about inspecting both the request and response maps in biff?

Jacob O'Bryant23:09:46

you need to change (def req) to (def req req)

1
2FO00:09:15

Thanks Jacob, on a similar note if I want to inspect a xtdb document in the repl in vanilla xtdb I'm aware that this can be achieved by evaluating a query like this:

(def my-node (xt/start-node {}))

(xt/q (xt/db my-node)
      '{:find [name id email]
        :where....)
;; => #{[data][data]....
How would this be done in biff?

👌 1
Jacob O'Bryant00:09:00

the xtdb node is stored at (:biff.xtdb/node @com.biffweb/system), so you pass that to xtdb.api/db and query it in the usual way. there's an example in the repl.clj file that uses a get-sys helper function.

1
2FO00:09:20

Got it thanks

2FO17:09:08

I used this var to query xtdb:

......
(:require [com.game.repl :as rp]))

(def inspect
(let [{:keys [biff/db] :as sys} (rp/get-sys)]
  (biff/q db
     '{:find [title]
       :where [[_ :game/title title]]})))
It works when implemented on an already running system, but stops the app from compiling between restarts.
Execution error (IllegalArgumentException) at xtdb.api/eval7979$fn$G (api.clj:306).
No implementation of method: :db of protocol: #'xtdb.api/DBProvider found for class: nil

Jacob O'Bryant18:09:56

Yeah, I would change that to a function like (defn inspect [] ...) , so it only runs when you call it yourself from the repl.

1
Jacob O'Bryant18:09:34

(My repl.clj files tend to accumulate lots of functions just like that)

Jacob O'Bryant18:09:49

You can also store forms within a (comment ...) block. If there are functions I call often I sometimes put the invocation in there:

(defn foo []
  ...)

(comment
  (foo)
 
  ...)

🙏 1
2FO18:09:14

I've found when querying the request as so:

(defn app [req]
  (def req req) ......

req
I get a very detailed map of the 'system', with the request appended at the end.
Class: clojure.lang.PersistentHashMap
Contents: 
  :biff.xtdb/topology = :standalone
  :mailersend/defaults = { [ :from :email.........
org.rocksdb.RocksDB@.....
:reitit.core/match = .....
biff/db = {....
biff.xtdb/node = {.......
I'm interested in querying a limited set of values from the request e.g headers, port, uri, path-params, response, body etc How can I obtain these values and omit the other information?

Jacob O'Bryant18:09:39

Yes, it's because the system map gets merged with all incoming requests. If you'd like to see only some keys from the repl you could do e.g. (:headers req), or (select-keys req [:headers :port ...]), or even (apply dissoc req (keys @com.biffweb/system) .

1
2FO19:09:51

Thanks for the explanation, super useful. As a bonus I now understand the purpose of those sys symbols 🎉

Jacob O'Bryant22:09:36

heh, yeah... I'm sort of haphazard about calling it req vs. sys. I've been wondering if I should just always call it ctx (short for context) instead