First time using pedastal and having a rather fundamental issue which I can't get working properly. Based on this: http://pedestal.io/pedestal/0.6/guides/hello-world-content-types.html, I want to have a different content in the response based on the content negotation. The content negotation seems to fail (I'm trying to make the interceptors global, not route-specific). With this code:
(def routes
(route/expand-routes
#{["/api/hello" :get respond-hello :route-name :hello]}))
(def debug-content-negotiation
{:name ::debug-content-negotiation
:enter
(fn [context]
(println "Before negotiation: " (:request context))
context)})
(def service
(http/create-server
{::http/routes routes
::http/type :jetty
::http/port 8080
}))
I do get the expected output (`Hello, world!`).
curl -i -H "Accept: text/html"
HTTP/1.1 200 OK
Date: Sat, 25 Jan 2025 14:00:11 GMT
Strict-Transport-Security: max-age=31536000; includeSubdomains
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Content-Security-Policy: object-src 'none'; script-src 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:;
Content-Type: text/plain
Transfer-Encoding: chunked
Hello, world!
With a debug-content-negotiation interceptor:
(def debug-content-negotiation
{:name ::debug-content-negotiation
:enter
(fn [context]
(println "Before negotiation: " (:request context))
context)})
(def service
(http/create-server
{::http/routes routes
::http/type :jetty
::http/port 8080
::http/interceptors [debug-content-negotiation]
}))
I do get an empty result:
curl -i -H "Accept: text/html"
HTTP/1.1 200 OK
Date: Sat, 25 Jan 2025 14:02:53 GMT
Content-Length: 0
When activating the content negotation:
(def service
(http/create-server
{::http/routes routes
::http/type :jetty
::http/port 8080
::http/interceptors [(content-negotiation/negotiate-content supported-types)]
}))
I get an internal server error:
curl -i -H "Accept: text/html"
HTTP/1.1 500 Server Error
Date: Sat, 25 Jan 2025 13:49:19 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Internal server error: no response
What I expect to happen is that the enter-functions of the global interceptors are executed (as long as there's on response in the context), the function of the get of the hello route is executed (generating a body) and than the interceptor leave-functions are executed (in reverse order). I don't really understand where the 'no response' is coming from. It seems, when I add interceptors, the response-hello function isn't executed for some reason. What do I miss?Did you read this: http://pedestal.io/pedestal/0.6/reference/default-interceptors.html There is a big difference between omitting the interceptors key and specifying one
I didn't read it, but now I did. However, I still fail to see how to make it work. I now add interceptors by using the 'update' (which makes sense, so now I still have the default ones as well). When I do that, I still have the same issue: I get an empty result whenever I add interceptors.
(def debug-content-negotiation
{:name ::debug-content-negotiation
:enter
(fn [context]
(println "Before negotiation: " (:request context))
context)})
(def service-map
(->
{::http/routes routes
::http/type :jetty
::http/port 8008}
(http/default-interceptors)
(update ::http/interceptors conj debug-content-negotiation)))
(defn start []
(-> service-map
http/create-server
http/start))
gives:
$ curl -i
HTTP/1.1 200 OK
Date: Sat, 25 Jan 2025 18:06:34 GMT
Content-Length: 0
If I don't add the interceptors, all works fine:
(def service-map
(->
{::http/routes routes
::http/type :jetty
::http/port 8008}
(http/default-interceptors)
))
(defn start []
(-> service-map
http/create-server
http/start))
this works fine:
curl -i
HTTP/1.1 200 OK
Date: Sat, 25 Jan 2025 18:10:08 GMT
Strict-Transport-Security: max-age=31536000; includeSubdomains
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Content-Security-Policy: object-src 'none'; script-src 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:;
Content-Type: text/plain
Transfer-Encoding: chunked
Hello, world!
Thx!oh crap, nvm, got it, need to pass the interceptor map to the interceptor function so I create an interceptor record. problem solved 🙂.