Dualo
Backend Architectures Deep Dive

Request lifecycle — the shape they all share

Every framework does the same dance: parse → route → middleware → handler → serialize → respond. Learn the shape once, read any framework faster.

1 min read

Every web framework executes the same seven steps per request: (1) receive bytes, (2) parse HTTP, (3) route to a handler, (4) run middleware, (5) run the handler, (6) serialize the response, (7) send bytes back. The syntax differs; the shape doesn't.

Middleware is the 'onion' model: each layer wraps the next. A typical chain: request-ID → logging → CORS → auth → rate-limit → handler → response-logging. Each layer can inspect, modify, or short-circuit (e.g., auth fails → return 401 without calling the handler).

Order matters: app.use(logger); app.use(auth) logs before authenticating — you see unauthorized requests in logs. Swapping them means only authenticated requests are logged. Not a bug, just a choice — but you need to MAKE the choice consciously.

Once you internalize this skeleton, reading a new framework becomes 10× faster. Express's app.use(), Django's MIDDLEWARE list, FastAPI's app.add_middleware, Rails's config.middleware, Next.js's middleware.ts — all the same concept.

Common hooks to learn in ANY framework you pick up: before-request (global preprocessing), after-request (logging, response headers), exception handler (map domain errors to HTTP codes), route decorator (associate URL + method with handler). Find these four in any framework and you can work in it.

Grounded on https://docs.djangoproject.com/en/stable/topics/http/middleware/

Next up

ORM & data layer patterns

Active Record, Data Mapper, Query Builder, raw SQL. The data access pattern your framework ships shapes how you think about persistence.