reitit

jcf 2025-01-09T08:20:03.274499Z

What’s the recommended approach to adding SSE support to a Reitit app? I’ve held off on interceptors up until now, but it looks like swapping out the executor is required if I want to add support for SSE.

juhoteperi 2025-01-09T08:22:50.843669Z

It depends on what you want. Routing doesn't really have to have much do with SSE (or WS). Once the request is routed, your handled can do what ever you want. Then handling the SSE response only depends on your http adapter (http-kit or whatever.)

juhoteperi 2025-01-09T08:23:27.647509Z

Though yes, this means that Muuntaja and other Reitit middleware won't see the SSE messages. But it doesn't matter much, you just handle encoding those messages in the code yourself.

juhoteperi 2025-01-09T08:23:50.015509Z

I think you can even get the active Muuntaja instance from the Reitit request and use that.

juhoteperi 2025-01-09T08:25:35.031159Z

In general, I don't know if I would recommend SSE now. Both Clj http server and JS client support is somewhat limited.

juhoteperi 2025-01-09T08:28:54.646489Z

Ring-jetty-adapter tests have some SSE test cases: https://github.com/ring-clojure/ring/blob/master/ring-jetty-adapter/test/ring/adapter/test/jetty.clj#L547-L574

juhoteperi 2025-01-09T08:30:28.743269Z

It just needs to use the async ring handler arity and then return a response implementing StreamableResponseBody which can then write messages to the response connection.

jcf 2025-01-09T08:49:24.975759Z

Hmm, I’ve switched ring.adapter.jetty9 to async mode and I’m seeing Reitit call my handler with a single argument rather than three though. https://github.com/sunng87/ring-jetty9-adapter I know async is in place as a couple of my custom middleware weren’t setup for async, which triggered exceptions. I assumed there wasn’t async support inside the default execution path of Reitit because of this arity error I ran into.

jcf 2025-01-09T09:21:53.174069Z

["/stream"
 {:name :app.route/stream
  :get
  {:handler
   (fn [& args]
     (throw (ex-info "Stream!" {:n (count args) :args args})))}}]
[nrepl  ] 09:20:08.109 INFO  app.web {:msg "Uncaught exception processing request.", :request-method :get, :uri "/stream", :exception #error {
[nrepl  ]  :cause "Stream!"
[nrepl  ]  :data {:n 1, :args ({:reitit.core/match #reitit.core.Match{:template "/stream" […]
Maybe this is a ring-jetty9-adapter issue. think_beret

jcf 2025-01-09T09:25:15.697769Z

https://caniuse.com/eventsource looks good across the clients I need to support, and ring-jetty9-adapter supports async so I’d expect this to be a relatively simple solution to pushing updates to a client.

gtbono 2025-01-09T18:29:23.385049Z

is it possible to exclude some routes from being included in the openapi/swagger ui?

neural 2025-01-09T18:34:39.202689Z

long time don't use it ... but maybe the :no-doc keyword?

valtteri 2025-01-09T19:13:49.109579Z

Yep, documented here https://github.com/metosin/reitit/blob/master/doc/ring/openapi.md#openapi-data