Kshitij Singh
Kshitij Singh

Reputation: 93

How do i server static html file with ring handler in clojure?

I am trying to server html over a ring based api server path . however everytime i hit the endpoint , i am getting this wierd error

java.lang.IllegalArgumentException: No implementation of method: :write-body-to-stream of protocol: #'ring.core.protocols/StreamableResponseBody found for class: clojure.lang.PersistentArrayMap
    at clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:583) ~[clojure-1.10.1.jar:?]
    at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:575) ~[clojure-1.10.1.jar:?]
    at ring.core.protocols$eval18503$fn__18504$G__18494__18513.invoke(protocols.clj:8) ~[?:?]
    at ring.util.servlet$update_servlet_response.invokeStatic(servlet.clj:106) ~[?:?]
    at ring.util.servlet$update_servlet_response.invoke(servlet.clj:91) ~[?:?]
    at ring.util.servlet$update_servlet_response.invokeStatic(servlet.clj:95) ~[?:?]
    at ring.util.servlet$update_servlet_response.invoke(servlet.clj:91) ~[?:?]
    at ring.adapter.jetty$proxy_handler$fn__18623.invoke(jetty.clj:27) ~[?:?]

Here is what my api is returning.

{:status 200
:body   (resource-response "index.html" {:root "public"})}

Whereas if i hit the index.html path directly it is accessible at this route

http://localhost:8080/index.html

Upvotes: 3

Views: 974

Answers (1)

user2609980
user2609980

Reputation: 10484

You get the error No implementation of method: :write-body-to-stream of protocol: #'ring.core.protocols/StreamableResponseBody found for class: clojure.lang.PersistentArrayMap because as a body you return a PersistentArrayMap instead of something that can be encoded as the body of a Ring HTTP response.

resource-response already returns a full response map (a PersistentArrayMap):

(resource-response "index.html")
;; => {:status 200,
;;     :headers
;;     {"Content-Length" "0", "Last-Modified" "Mon, 16 Nov 2020 14:22:48 GMT"},
;;     :body
;;     #object[java.io.File 0x239d3777 "/index.html"]}

so no need to wrap it in {:status 200, :body ...} since it becomes {:status 200 :body {:status 200, ...}} which lead to that error. To fix it your API can directly return:

(resource-response "index.html" {:root "public"})

Upvotes: 2

Related Questions