Let's assume, that I've got an endpoint POST /endpoint
that takes JSON as input data:
POST /endpoint
{
"resource": {
"name": "great"
}
}
Now, I want to check whether the incoming JSON is valid. I thought that :malformed?
hook would be a great place for doing that.
So I came up with such a code:
(ANY "/endpoint" []
(resource
:allowed-methods [:post]
:available-media-types ["application/json"]
:malformed? (fn [ctx] (let [body (get-body-from-request ctx)
is-malformed (not (is-body-valid body))]
is-malformed)
:post! (fn [ctx] (let [body (get-body-from-request ctx)]
(create-an-object body)))
:handle-created (fn [ctx] {:method :post :body (:body @request)})))
So my intention was:
- get the
body
from request, check if it's valid (is-body-valid
) - in
post!
hook, use thebody
again and do real work (create-an-object
)
The problem here is the get-body-from-request
function:
(defn get-body-from-request [ctx]
(json/read-str (slurp (get-in ctx [:request :body])) :key-fn keyword))
It works perfectly but the body
is an InputStream
, so I can read it only once.
Is there a way to use body
of the request in more than one hook NOT using atoms?
The solutions coming to my mind:
- A middleware wrapper that adds a string version of
body
to thectx
param. - Pass the result of
malformed?
topost!
... - Use atoms.
Thanks!