yada icon indicating copy to clipboard operation
yada copied to clipboard

Document how to use :consumer to coerce request bodies

Open danielcompton opened this issue 7 years ago • 2 comments

The Yada docs don't discuss :consumer. This is an invaluable feature when you need to get the raw body of the request.

One use-case for this is when you want to verify a Stripe webhook is valid. To check the webhook signature, you need to use the exact bytes (as a string) that were sent in the body. You need to specify that your resource :consumes "application/json", but if you do that without specifying a custom :consumer, Yada will parse the JSON body into a Clojure map. What you need is something like this:

(defn string-consumer [ctx content-type body]
  (assoc ctx :body (bs/to-string body)))

(defn webhook-routes [db stripe]
  {"/webhooks/stripe"
   (yada/resource
     {:id :deps.webhooks/stripe
      :methods
      {:post
       {:consumes "application/json"
        :produces "application/json"
        :consumer string-consumer
        :response (fn [ctx]
                    (let [payload ^String (:body ctx)
                          sig-header (resp/get-header (:request ctx) "Stripe-Signature")]
                      (try (let [event (Webhook/constructEvent payload sig-header secret)]

danielcompton avatar Jan 10 '19 06:01 danielcompton

Agree - this is a useful feature and needs documentation. I've added a module to Edge to explain basic file upload, so could extend this to show streaming upload. The yada docs are going to get a refresh in due course, to align to the 'new' Edge.

malcolmsparks avatar Jan 10 '19 10:01 malcolmsparks

@danielcompton Thank you! This was a life saver for a similar webhook integration.

titonbarua avatar Dec 30 '20 18:12 titonbarua