reitit

itaied 2024-10-31T12:57:06.028769Z

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

juhoteperi 2024-10-31T13:02:18.858419Z

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

juhoteperi 2024-10-31T13:02:33.823939Z

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

juhoteperi 2024-10-31T13:02:56.368519Z

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

itaied 2024-10-31T13:10:48.163849Z

should it be a ring/resource-handler?

juhoteperi 2024-10-31T13:12:41.318739Z

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.

itaied 2024-10-31T13:17:46.483999Z

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

itaied 2024-10-31T13:17:58.438929Z

But I'm still getting 404 and not index html

itaied 2024-10-31T13:18:24.277029Z

(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))

juhoteperi 2024-10-31T13:19:22.968299Z

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)

juhoteperi 2024-10-31T13:20:02.053029Z

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

itaied 2024-10-31T13:26:15.095719Z

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

juhoteperi 2024-10-31T13:26:32.144989Z

for resources, yes

itaied 2024-10-31T13:26:43.048779Z

I have used the file-handler for reitit ring

itaied 2024-10-31T13:32:25.895869Z

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!

itaied 2024-10-31T14:23:00.925279Z

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