This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-01-05
Channels
- # announcements (1)
- # babashka (61)
- # babashka-sci-dev (1)
- # beginners (54)
- # biff (17)
- # cider (4)
- # circleci (1)
- # clj-commons (39)
- # clj-kondo (26)
- # cljdoc (40)
- # clojure (41)
- # clojure-europe (32)
- # clojure-norway (4)
- # clojure-portugal (1)
- # clojure-uk (2)
- # clojurescript (59)
- # clr (69)
- # conjure (7)
- # cursive (22)
- # data-science (16)
- # datalevin (1)
- # datomic (19)
- # docker (31)
- # funcool (1)
- # honeysql (6)
- # hoplon (1)
- # hyperfiddle (41)
- # introduce-yourself (1)
- # juxt (2)
- # leiningen (5)
- # nbb (14)
- # nextjournal (38)
- # off-topic (47)
- # polylith (2)
- # rdf (5)
- # re-frame (4)
- # reitit (27)
- # releases (6)
- # scittle (10)
- # shadow-cljs (24)
- # sql (11)
- # squint (1)
- # tools-build (33)
- # tree-sitter (4)
- # vim (39)
I am still dont understand how to structure Reitit routes for a full-stack application, where we have API backend part and CLJS frontend part. I have shared cljc
routes and use it with custom expand func both in frontend and backend code
I tried to build this structure:
• Frontend app on the root /
path with routes like these: /login
, /todos
etc
• Backend app on the /api
path with routes like these: /api/todos
, /api/auth
etc
But I could not find the way to do it
Then I tried to build following structure:
• Frontend app on the root /app
path with routes like these: /app/login
, /app/todos
etc
• Backend app on the /api
path with routes like these: /api/todos
, /api/auth
etc
And I think it works well, but what is about middleware? I need to apply them only for backend routes, how to do it?
we don't use the expander thing, and instead just use cljc injections
[["/top" ?#@(:clj [:interceptors [some-interceptor]])
["/page" {:name :page
?#@(:clj [:get {:handler my-handler-fn}])}]]]
this way we have fine-grained control at the Read step rather than as a runtime Eval step
client side we use the by-name method to generate paths for api requests / links to other pages in the app, server side we use the reitit http router
But how ring server will know all backend/frontend routes (to understand when to show 404), if you cut the frontend part inside your ‘cljc’ file?
it may be helpful to understand that you're not building one app, you're building two
you can use cljc conditionals to control which app gets to see which parts of the route table
you might conditionally keep some routes clj only, and some cljs only
if you have a catchall page e.g. /app*
on the server, in which your cljs app will run and handle lots of /app/ routes like /app/foo and /app/bar, then you actually need two mutually exclusive routing tables - one that the server mounts (with the catchall), and one that the client mounts (with all the named routes).
BUT, both the server and the client would need access to the latter for the purposes of generating links
a big reason for using reitit, is that it's all just data
so approach it as a 'data visibility in my app' problem first, and a routing problem second
does that help?
another approach may be not to use catchall route, but instead to allow the server to directly render each route via server-side-rendering
in that case, client and server would share a routing table
Thank you @U0509NKGK will try tomorrow
good luck!
is it correct? This way I create 1 cljc
file where put all my front/back routes
All routes has :name
key so to use API routes on frontend
that's what we're doing, yes 🙂
we also conditionally add interceptors where appropriate, and sometimes provide some routes on the backend only
Oh finally I start to understand that big reitit knowledge gap! Thanks man @U0509NKGK
I need to add #?@(:clj [:get handlers/frontend-handler])
for each frontend route, is it ok or there is some way to avoid that code duplication?
This route for the case when user load page in browser on some frontend route, not from root
handlers/frontend-handler
just renders html page with front-app mounted
i find that it's actually not all that much noise
it makes the fact and the intention clear; hiding it away makes the system feel less deterministic and more magical to me
to be clear, magic=bad in this context 😅
Agreed