Most Rails APIs happen rather than get designed: a format.json branch grows into a contract nobody wrote down. Here is the structure that fixes it: path versioning, a three-layer controller hierarchy, token auth outside the versioned tree, v2 without copying v1, and NRQL to prove when v1 can be deleted.
Everything native with Procfile.dev, or everything in containers with docker-compose? The setup that works best day to day sits in between: native app processes, stateful services in containers, and a container runtime that does not eat your RAM.
Link preview crawlers don't run JavaScript, so every route of a static SPA shares the same generic card. Here's how a Lambda in front of AWS Amplify injects per-page Open Graph tags, the six bugs that kept it from working, and the lean version that does.