Fork me on GitHub
#pedestal
<
2018-12-17
>
bobcalco02:12:48

@mtnygard Let me try first more simply to describe what I want: A static "landing" page at "/", an api root of /api/* which is handled server side, and an admin console at /admin that itself has many logical sub-"routes" using bidi with re-frame. The static page at "/" has different style completely from the admin console at "/admin" (which is a SPA). Currently I'm slurping up two different starter index.html files, but I'd rather make the entire page rendering dynamic (looking at rum for that). I have not changed the code much from what you find at https://github.com/pdlug/re-frame-starter. Anyway.... the abstract question is, how to get pedestal routes to play nice with bidi routes in the case where the SPA is not being created off root "/" but rather off "/admin" (for example). I am refactoring things a bit right now so code posts aren't practical at this precise moment. I'm trying to think differently about my problem and see if I can't find a solution that doesn't fight the frameworks expected behavior. For example: I'd be happy putting every page in the SPA if I could render entirely different CSS styling/JS for logged in vs not logged in scenarios. This is why I separated them in the first place - the need to have different stuff in the <head> and different JS at the bottom.

mtnygard03:12:31

@bob592 I see. I just took a look at bidi’s code. They don’t directly support Pedestal, but I think you could make a very simple interceptor to glue a Pedestal route to the bidi router. That would be the sole interceptor on ‘/admin’. Then that interceptor would call the bidi router directly and pass it the request map from the context.

bobcalco12:12:10

@mtnygard Thing is, I don't want the admin console SPA reloaded every time Pedestal detects a route that "belongs" to it, as it would be harder (if not impossible or in any case highly non-performant) to maintain application state. Might as well do MVC post-backs (ahem). The request shouldn't even be making it to the server if bidi has it "covered," no? Maybe I should just use a different routing engine. The more interesting problem is, how do I support more than one CSS theme/design? I'm coming to the conclusion that I should just run two separate instances of pedestal - one HTTP and the other (once in production) HTTPS. Usually routing could split those hairs with interceptors but I don't know a way to generate the CSS I need in the <head> on the fly, as reagent is mounting the "app" div in the <body>, although I can probably do it by generating my own <link> tags since hiccups doesn't. A flask of Rum is sounding good perhaps for this. Alas, frameworks are as much a source of incidental complexity as language syntax...

mtnygard18:12:41

@bob592 I'm lost. How does bidi affect your SPA state at all? I thought it was a back end routing framework.

bobcalco18:12:36

@mtnygard It's a front-end routing library AFAIK, and on the #re-frame channel I'm getting some help that seems to be on point by @mateus.pimentel.w... he recommends I combine bidi with pushy on the client. Apparently it can prevent the call to the server for subroutes but I'm still not entirely clear myself how it is supposed to play nice with pedestal's server-side routing. The link the the article he pointed me to talks only about compojure. However, if it does require server side cooperation, your original idea about an interceptor for /admin may be the key after all. I still feel like I need more fundamentally to rethink what I'm trying to do. The motivation for all of this is simply to have different styling for a not-logged-in landing page, and a separate styling for the logged-in admin SPA.

madstap18:12:14

Bidi is portable between clj/cljs and only cares about translating string paths to/from data structures.

madstap18:12:30

Both using it on the backend with pedestal and on the frontend with pushy make sense, but are different things.

ddeaguiar18:12:26

Hi @bob592! I think it’s best to distinguish between front-end and service api here. There will be some endpoints provided by your service api to satisfy app needs. How you coordinate that interaction is an orthogonal issue.

☝️ 4
bobcalco18:12:27

@ddeaguiar Yes, I'm trying to think that through. As usual, starter projects and templates create more headaches than starting from first principles.

ddeaguiar18:12:06

yeah, we don’t have starter projects which dive into this area

bobcalco18:12:10

they only save you time if your app requirements are of the "hello, world" variety.

ddeaguiar18:12:49

I recommend two different projects for front-end and service api

ddeaguiar18:12:02

they can be in the same repo if you want but I think the separation is useful

ddeaguiar18:12:33

I’d also consider implementing a mechanism to stub out service api interactions in the front-end code

Whiskas18:12:59

@bob592 My provisory solution is to return index.html for everything but resources/files and let pushy to change the route for me with the help of bidi

Whiskas18:12:32

but the ideal solution would be to use the same routes you set on client, on the server, returning index for them

Whiskas18:12:19

since you are doing full stack clojure i think this should not be hard since the route definition can be done in a shared file and transformed into the appropriate format for the server

Whiskas18:12:25

i’m not a specialist in this subject tho

bobcalco18:12:13

@mateus.pimentel.w What i want to avoid in that case is constantly re-initializing application state each time the server posts back an index. I need some way to get the client and server to cooperate with whole-page rendering, not just the "app" div. At least, that's what I think I need. Separating the two seems like a good idea until you need to debug the round trip for API calls.

ddeaguiar18:12:43

One thing to keep in mind is that it’s quite nice to separate front-end index.html from the backend service. Completely decouple them. For example, serve the front-end from s3 or something

ddeaguiar18:12:30

front-end just makes service calls for data it needs. How you do this is up to you. Here’s where folks stumble on too coarse-grained or fine-grained service apis and what implementations like graphQL try to solve.

ddeaguiar18:12:57

I don’t think there’s one good answer because it’s context-specific

bobcalco19:12:01

@ddeaguiar In concept I agree of course. But development and deployment are two different worlds with their own exigencies and "incidental compexities"... Alas, the language can't really help us with those as much as we might like, especially once we start having to live with various design decisions and their sometimes unforeseeable consequences. I won't even mention the incidental complexities of development on a platform like the JVM with diverse tooling options and related ceremonies, and the seemingly infinite smorgasbord of library choices with varying interdependencies and version complexities... never a dull moment. 🙂

Whiskas19:12:48

@bob592 are you developing a non-spa ?

Whiskas19:12:00

here i just switch views using re-frame/dispatch

Whiskas19:12:06

and the url is synced

Whiskas19:12:23

the url is synced in case you want to copy paste the url for that specific url

Whiskas19:12:39

if you want to use the cached index i think you will have to add # to the url