How the Pieces Talk
Page loads, API calls, and what a single-page app asks of the server.
Learning objectives
- Trace one user action across browser, app, and database
- Tell a page request apart from an API call
- Explain why login state and secrets live on the server
- Describe what a single-page app still asks the server for
One click is a conversation
A visitor clicks Reserve on the Thursday pottery class. The browser does not write to the database. It sends an HTTP request to a URL your app exposed. The backend checks that the class exists, that a seat is free, and that this person is allowed to book. Then it writes a row and returns a result the page can show. Book 8 (HTTP APIs & Automation) is the full version of that conversation. You only need the shape here.
POST /api/bookings with the class id and the session cookie.
Reads the cookie, loads the class, refuses the booking if the seat count is already full.
Inserts one booking row. The unique constraint stops two people taking the last seat.
201 and a confirmation, or 409 if the seat was just taken.
What changes when the frontend is a single-page app
On a multi-page site, “open the Thursday class” is a request for HTML. On a single-page app, the first visit downloads the shell — index.html plus the JavaScript bundle. Every later click is an API call: GET /api/classes/thursday returns JSON, and the JavaScript draws the page. The Reserve button is still the POST from the diagram above. The SPA did not remove the backend. It moved the drawing into the browser and left the rules on the server.
One hosting detail falls out of that. If the visitor refreshes /classes/thursday, the browser asks the server for that path as if it were a file. The SPA does not have a file there. The server has to answer with the same index.html and let the JavaScript read the URL. That rewrite is part of deploying an SPA. Forget it and every deep link is a 404, even though the home page works.
Three words that show up in every generated app
| Word | What it is doing | Where it must live |
|---|---|---|
| API route | A URL the frontend calls, such as /api/bookings. It is still your backend. | On the server. The browser only calls it. |
| Session or token | Proof of who is logged in, sent along with later requests. | The secret that signs it stays on the server. The browser holds only the resulting cookie or token. |
| Environment variable | A setting injected when the process starts: database URL, secret, public site URL. | On the host, in the panel or a file that is not in git. Never in the JavaScript the browser downloads. |
A generated page sometimes disables the Reserve button when seats === 0. That is a courtesy for the visitor. Anyone can still call the URL directly. The rule that protects the last seat has to run in the backend, against the database, or it is not a rule.
Trace the click
In one sentence each: what does the browser send, what must the backend decide, and what must the database guarantee for “reserve the last seat”?
Answer
The browser sends the class id and some proof of who is logged in. The backend decides whether that person may book and whether a seat is still free. The database guarantees that two simultaneous reservations cannot both commit for the same last seat — usually a transaction and a unique constraint or a seat counter updated in one statement. A button label cannot do that job.