reitit 2024-10-31

Hey all, how can I serve both SPA and API in the same server? My api is prefixed with /api and I need that requests will arrive to the inner application router (i.e, index.html ) This is my setup:

(:require [reitit.ring :as ring])

(def router
  (ring/ring-handler
   (ring/router
    ["/api"
     ["/apps/:id" {:get read-app}]
     ...]
    {:data {:middleware [exception-middleware]}})
   (ring/routes
    (ring/create-file-handler {:path "/"})
    (ring/create-default-handler))))
When I hit the refresh in the browser tho, it response with a 404 because it is not directed to the index.html

you could also have a regular handler fn after create-file-handler to just return response with index.html always

(fn [_req] {:status 200 :body "index"})

and then returning File / URL or just the string for index.html

should it be a ring/resource-handler?

reitit.ring? That uses the request path to figure out which resource to return. If you always want to return index.html, I don't think there is a util fn for that.

there's resource-response from ring.util.response

But I'm still getting 404 and not index html

(ring/router
    ["/api"
     ["/apps/:id" {:get read-app}]
     ...]
    {:data {:middleware [exception-middleware]}})
   (ring/routes
    (ring/create-file-handler {:path ""})
    (ring/ring-handler
     (ring/router
      [["/*" {:get (fn [_] (resource-response "index.html" {:root "public"}))}]]))
    (ring/create-default-handler))

doesn't really matter if you use resource-response or just io/resource, it doesn't do anything special (ok, url-response fn adds content-length and last-modified headers which could be nice)

check if the handler fn is being called, then check if the resource-response finds a resource with those options

the handler is being called it returns nil Should the files be in the classpath?

for resources, yes

I have used the file-handler for reitit ring

I have added the public to my deps :paths and now it works

(ring/ring-handler
   (ring/router
    ["/api"
     ["/apps/:id" {:get read-app}]
     ...]
    {:data {:middleware [exception-middleware]}})
   (ring/routes
    (ring/create-file-handler {:path ""})
    (ring/ring-handler
     (ring/router
      [["/*" {:get (fn [_] (resource-response "index.html"))}]]))
    (ring/create-default-handler)))
Thank you very much!

how can I avoid the first request (`/`) from redirect me to /index.html ? I want it to just return the file to the browser