Fork me on GitHub
#pedestal
<
2022-02-22
>
Miguel Rivas18:02:26

This is a bit of pedestal/reitit question. I'm using XTDB as data storage, they offer a https://github.com/xtdb/xtdb/blob/20a2632a18a36dae2e915ab032307ce0c5b3e150/modules/http-server/src/xtdb/http_server.clj#L446 for their web console and I've been trying to use it in my pedestal stack. So far I've been able to somewhat use it by converting the said handler into a pedestal interceptor, such as:

;; this is "xtdb-interceptor"
(-> xtdb-handler
    (io.pedestal.interceptor/interceptor))
and then adding it to my service-map config
(update service-map ::io.pedestal.http/interceptors conj xtdb-interceptor)
This works up until I try to interact with xtdb's console and say, run a query, the request seems to be handled ok and a response is returned such as:
{:status 200,
  :body <<StreamableResponse>>,
  :headers {"Content-Type" "application/edn; charset=utf-8"}}
However the StreamableResponse body is not being handled/coerced, causing a java.lang.IllegalArgumentException: No implementation of method: :write-body-to-stream of protocol: #'io.pedestal.http.impl.servlet-interceptor/WriteableBody found for class: juxt.clojars_mirrors.muuntaja.v0v6v8.muuntaja.protocols.StreamableResponse. I do notice that https://github.com/xtdb/xtdb/blob/20a2632a18a36dae2e915ab032307ce0c5b3e150/modules/http-server/src/xtdb/http_server.clj#L428 does provide coercion/middlewares for their console's routes, however this doesn't seem to be working. Maybe the approach of using the handler as an interceptor is wrong? Any ideas on how I could plug it into my pedestal config?

ddeaguiar20:02:14

Seems like you need to extend WritableBody to StreamableResponse or the concrete impl

Miguel Rivas18:02:26

just in case anyone tries to do the same and use this handler with pedestal, I got it working by extending Pedestal's io.pedestal.http.impl.servlet-interceptor/WriteableBody protocol like so:

(extend-protocol io.pedestal.http.impl.servlet-interceptor/WriteableBody
  (Class/forName "[B")
  (write-body-to-stream [^InputStream input-stream ^OutputStream output-stream]
    (with-open [out output-stream]
      (.write out ^bytes input-stream)))

  juxt.clojars_mirrors.muuntaja.v0v6v8.muuntaja.protocols.StreamableResponse
  (write-body-to-stream [^InputStream input-stream ^OutputStream output-stream]
    (with-open [out output-stream]
      ((.f input-stream) ^OutputStream out))))
I hope this helps anyone that may try to use xtdb's console with pedestal 😄

gratitude-thank-you 2