A WIP application for friends to rate, share and discuss movies.
mockbuster is an Actix Web application for users to rate, share and discuss movies. It follows an SSR + Client Side Hydration approach for a UI that allows users to rate, discuss and share movies with their friends.
The UI follows a Server Side Rendered, Client Side Hydrated strategy. Each page is built off of yew components whose compile targets are both static strings (for HTML) and dynamic WASM components (for client side rendering). On each GET
request, actix renders out each page of yew components and responds with the complete Document, the traditional SSR approach. Once rendered on the client, that Document requests it's associated WASM counterpart code via <script />
tags, which builds an identical V-DOM to replace the server generated HTML. This approach splits the appropriate responsibilites across server and client, allowing for SEO + fast response times from our server while still achieving a highly interactive & performant UI that scores highly across all Core Web Vital metrics.
Example / explanation using the LoginView page:
- The main component is defined + written to be compatible with both server + client scenarios (login_view).
- That same component is then also exported via wasm-bindgen for WASM environments (run_login_view), with explicit instructions to hydrate an existing version of itself within a DOM.
- On any
GET
request to/login
, a Document is generated + sent in its correct state via the server rendering oflogin_view
(get) - Once sent to the client, that document immediately makes a request to fetch + run it's associated WASM (get, loginView)
- Once
loginView.js
is executed, the DOM sent by the servers rendering oflogin_view
will be hydrated by the WASM code withinrun_login_view
, replacing it with an identical V-DOM in markup that contains all event listeners & other UI logic.
No (good) reason in particular - as a Rust fan this stack is a POC to check out Rusts web development ecosystem / ergonomics. A goal of mockbuster was to write as little client side TypeScript as possible - no matter how painful / inefficient - and get a sense of if this stack is production ready. (I'm aware using bootstrap is sort of cheating here, but you get the idea.)
- bootstrap for all styles + UI logic (dropdowns, modals, etc)
- wasm-bindgen for generating WASM code from yew
- web-sys for binding the Browser API to WASM
- reqwasm as an HTTP client
- webpack for bundling FE dependencies (bootstrap, etc)
- wasm-pack for bundling WASM components via webpack
- yew Client side templating
- Actix Web for document, asset + REST requests
- SeaORM ORM & all interfacing with postgres
- yew Server side templating
- Docker for Postgres + Redis containers
- docker-compose for composability
- yew for UI components, compiled on both server + client (see FE TL;DR).
- validators for shared validation logic across server + client code.
You must use https as it's needed for ServiceWorkers, which powers the Progressive Web App. You'll need to generate an SSL certificate + private key within the nginx
dir:
## Install mkcert && generate trusted self-signed certs
brew install mkcert;
mkcert -install;
mkcert localhost;
Rename localhost.pem
to certificate.crt
and localhost-key.pem
to private.key
, then move both of those files into /nginx
. Double click certificate.crt
to open it, and follow the instructions to have your machine trust it.
After this step, macOs + linux users may need to restart their machine for Chromium browsers to trust this cert.
Then generate the keys needed for VAPID and insert them in the .env
file. You can visit a site such as this to have keys generated for you.
Finally, mockbuster uses Docker & docker-compose. To run all the services, you can simply run
docker-compose up -d;
in the root to spin up all services needed. You can use Docker Desktop to monitor the logs of the resulting containers, or you can attach to their logs in a terminal. I recommend viewing these outputs at least:
docker attach nginx;
docker attach postgres;
docker attach server;
docker attach wasm-builder;
All Rust & TS code across FE & BE will recompile on save, and the services will restart.