Intermediate everything in Backend Dev, page 4
404 vs 500: missing resource vs server failure
A missing resource returns 404 Not Found (client asked for something absent); a database failure returns 500 Internal Server Error (server-side fault).
Idempotency: PUT vs POST in REST
Idempotent means repeated identical requests leave the same server state; PUT is idempotent, POST is not. Use PUT to overwrite a resource at a known URL.
Modularize routes with express.Router
Create a Router per resource in its own file, define routes on it, export it, and mount with app.use('/products', router).
Middleware execution order and sharing data via req
Middleware runs top-down in registration order; each calls next(); attach data like req.user that later handlers read.
Express error-handling middleware signature
(err, req, res, next) with err first, identified by arity, placed last after all routes.
Application-level vs router-level middleware
App.use() binds to the app and runs everywhere; router.use() binds to a Router and runs only for that router's routes.
Express route order and matching
Express checks routes in definition order, /items/new matches the literal route first, if /:id came first new would be captured as an id.
res.send vs res.json vs res.end
Send is flexible and sets content type by type, json serializes and sets JSON content type, end is the raw http terminator with no body helpers.
Parsing JSON bodies with express.json
Register express.json via app.use so it reads the request stream and populates req.body before handlers run, place it before routes.
fs.watch vs fs.watchFile
Watch uses OS event notifications, efficient but inconsistent across platforms, watchFile polls stat at an interval, reliable but slower.
path.resolve vs path.join
Join concatenates and normalizes relative segments, resolve builds an absolute path right to left from cwd and resets on any absolute segment.
Reading a POST body from the request stream
Body arrives in chunks via data events, accumulate them, on the end event concatenate and JSON.parse inside try/catch.
Counting lines in a 5GB log file efficiently
ReadFile loads all 5GB into RAM and may exceed buffer limits, instead stream with createReadStream plus readline and count line by line.
Comparing the three async error-handling styles
Callbacks pass err as first arg; Promises route errors to catch; async/await uses try/catch; an unhandled rejection can crash the Node process.
Handling async errors in Express middleware
Await inside try/catch and call next(err) on failure, or wrap the handler in an async error adapter; never let a rejected Promise go uncaught.
Running independent requests with Promise.all and race
Start all requests then await Promise.all to get all results or fail fast on first rejection; use Promise.race when only the fastest settled result matters.
Output order of sync, microtask, and macrotask
C runs first synchronously, then B drains from the microtask queue, then A from the macrotask queue.
SemVer and the caret vs tilde range operators
MAJOR.MINOR.PATCH signals breaking/feature/fix; caret allows minor and patch updates, tilde allows only patch; use tilde for tighter control.
Layered structure for a scalable Express API
Routes map URLs, controllers handle HTTP, services hold business logic, data layer talks to the DB; keep each layer ignorant of HTTP except controllers.
Choosing between CommonJS and ES Modules
ESM is the standard with static import/export and top-level await; set type to module; CJS uses require and module.exports and is synchronous.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles