ClojureScript Follow Up Questions + Answers
Some follow-up questions and answers from this gist. -- C. Oakman, 05 Oct 2020
We serve JS, CSS, image assets from the same server that serves API requests. For our traffic loads in hospitals, this is not a issue. If I were serving more traffic on a public-facing website I would probably default to a dedicated nginx instance for serving only static assets, and then if that wasn't enough I would look to a CDN.
I am not "anti-CDN": they serve a valuable purpose for some web properties. But I think most people do not need them and they add complexity to deployment and testing.
testing the client-side code in isolation
I would recommend doing this to the extent that it makes sense. In other words, some things can be tested well in isolation without a backing service, and other things it doesn't make sense to test without the backing service.
For example, our diagnostic logic for detecting sepsis is testable via unit tests, so we have plenty of those. Some of this logic is tested via integration tests as well, but not as thoroughly as the unit tests.
Contrast the diagnostic logic with our tests for user login / auth flows. It only makes sense to test that UI code against a working backend, so that's what we do via integration (ie: Cypress) tests.
deploying to something like S3 with semantic versioning (then changing the src pointer or manifest.json from the UI server)
This is doable, but IMO complex compared to just serving the assets from a web server you control.
Do you have separate VC (GitHub/Lab, etc) for the platform code and one or more client-side repos? Or do you have the client-side code mixed in with the platform code?
I strongly recommend keeping all code for a single project in the same repo (ie: a monorepo) and have a script that is able to produce build artifact(s) from each commit.
The Codebase section of twelve-factor app applies here.
you either don't have a separate API server or you proxy the API server in with nginx to avoid cross-origin stuff?
In general I like to reverse proxy and/or load balance with nginx. It doesn't work at all levels of scale, but does work for 99% of sites out there and gives you a lot of flexibility behind the web server for multiple concurrent services.
As a bonus, you can avoid a lot of CORS concerns too.
If so that would lead into some questions about local development practices. Meaning, do you have the entire UI server spun up with a minor replica dataset (to mimic the functionality of same-origin sessions), or do you use some other practice? So far I've been using separate services with API tokens to handle that sort of work -- primarily to avoid needing to spin up a replica of the entire architecture when doing local development and to simplify CI/CD. But curious to see what others are doing.
This is different from project to project, but in general I like to set up my development environment as close as possible to the production environment. I find in many cases where this is not possible it is often a smell of some unnecessary complexity in the production architecture setup (super common with overly-complicated cloud things these days). Or a smell that a piece of the system can be broken off as an independent project and worked on in isolation.
I would advise caution against mocking backing services like a database for the purposes of development and testing. It is doable, but often small differences can eat your lunch in terms of environment setup time and having to create a bunch of additional abstractions for the local development use case. It is usually faster to just stand up whatever is running in production and get a small dataset that works locally.