Back to Interview PrepGet interview ready with AILearn each topic the way interviewers ask it, then answer like you would in the interview.

Chapter 13 of 13

Top 45 Express Interview Questions

Routing, middleware, request/response handling, error handling, security, and database integration - organized by topic and difficulty, with explanations that go beyond a one-line definition and a code example for each one. Search or filter to find what you need, and share a direct link to any question.

Level:

Showing 45 of 45 questions

Questions reviewed0/45 · 0%

The first 15 of 45 questions are free to read. Sign up free to unlock every answer and track your progress.

Unlock all 45

Express is a minimal web framework built on top of Node's built-in http module. It adds routing, middleware, and convenience methods for requests and responses, without hiding the underlying Node.js server. A common mistake is treating Express as a separate runtime from Node.js - it is simply a library that runs inside a normal Node.js process. Reach for Express when you want structured routing and middleware without a heavier, more opinionated framework.

Example

const express = require('express');
const app = express();

app.get('/', (req, res) => res.send('Hello Express'));
app.listen(3000);

Call express() to get an app object, register routes and middleware on it, then call app.listen(port, callback) to start listening for connections. A common mistake is forgetting to call app.listen() at all (the server never starts) or hardcoding the port instead of reading it from process.env.PORT, which breaks on hosting platforms that assign their own port. Always fall back to a default port with process.env.PORT || 3000.

Example

const express = require('express');
const app = express();

app.listen(process.env.PORT || 3000, () => {
  console.log('Server started');
});

The app object, returned by calling express(), is the central object of an Express program - it is where you register routes, attach middleware, configure settings, and ultimately start the underlying HTTP server. A common mistake is creating multiple app instances unintentionally (for example in tests) and being confused about which one a route was registered on. In most apps there should be exactly one app object, created once and exported from a single module.

Raw http.createServer() gives you a single callback that must manually parse the URL, check the method, read the body, and set headers for every request. Express adds declarative routing (app.get/post/etc.), a middleware pipeline for cross-cutting concerns, and response helpers like res.json() and res.status(). A common mistake is assuming Express replaces Node - it is a thin, additive layer, and you can still reach into the underlying req/res objects (which are Node's own) at any time.

Express does not mandate a project structure, ORM, templating engine, or authentication approach - it provides a small routing and middleware core and leaves everything else to the ecosystem of npm packages and the developer's own conventions. A common mistake is expecting Express to include things larger frameworks bundle by default, like validation or an ORM, and being surprised when a fresh app has none of that wired up. Plan on adding the pieces you need (body parsing, validation, a database layer) explicitly.

Express walks its internal stack of middleware and routes in the exact order they were registered, checking each one for a method and path match, and runs the first one that matches (for routes) or every middleware whose path prefix matches, in order. A common mistake is assuming routes are matched by "best" or "most specific" match rather than "first" match, which causes bugs when a broad dynamic route is registered before a narrower static one. Always register more specific routes before more general ones that could shadow them.

Express exposes a method on the app object for each HTTP verb - app.get(), app.post(), app.put(), app.patch(), app.delete() - each taking a path and one or more handler functions. A route only matches when both the method and the path match, so the same path can have entirely separate handlers per verb. A common mistake is defining a route with app.get() and then wondering why a POST request to the same path returns a 404 - each method needs its own registration.

Example

app.get('/items', (req, res) => res.json([]));
app.post('/items', (req, res) => res.status(201).json({ created: true }));

Route parameters are named, colon-prefixed segments of a path (like /users/:id) that match any value in that position of the URL, made available on req.params keyed by name. A common mistake is forgetting that route parameters are always strings, even for numeric-looking segments, which can cause subtle bugs when comparing req.params.id === 5 (a number) instead of using Number() first.

Example

app.get('/users/:id', (req, res) => {
  res.json({ id: req.params.id, type: typeof req.params.id });
});
// GET /users/42 -> { id: '42', type: 'string' }

Route parameters (req.params) are part of the URL path and typically identify a specific resource, like /orders/:id. Query parameters (req.query) come after the ? in the URL and are meant for optional filtering, sorting, or pagination, like /orders?status=shipped. A common mistake is using a query parameter to identify a resource (e.g. /orders?id=5) when a route parameter would be more RESTful and cacheable, or vice versa, cramming filter options into the path.

Example

app.get('/orders/:id', (req, res) => res.json({ id: req.params.id }));
app.get('/orders', (req, res) => res.json({ status: req.query.status }));
// GET /orders/5              -> route param
// GET /orders?status=shipped -> query param

app.route(path) returns a chainable route object, letting you attach .get(), .post(), .put(), and .delete() handlers for the same path in one grouped statement, instead of repeating the path string in several separate app.METHOD calls. A common mistake is thinking app.route() changes matching behavior - it is purely an organizational shorthand with the exact same runtime behavior as separate calls.

Example

app.route('/tasks/:id')
  .get((req, res) => res.json({ id: req.params.id }))
  .delete((req, res) => res.status(204).end());

Appending a ? after the parameter name in the path, like /reports/:year/:month?, makes that segment optional so the same handler matches both with and without it. A common mistake is forgetting the parameter still exists as a key on req.params when omitted - its value is just undefined - so handlers should explicitly check for that rather than assuming its absence entirely.

Example

app.get('/reports/:year/:month?', (req, res) => {
  res.json({ year: req.params.year, month: req.params.month || 'all' });
});

Express matches routes in the order they were registered and stops at the first one that matches, so a dynamic route like /tasks/:id, if registered first, will match a request meant for a more specific static route like /tasks/new, since :id happily matches the literal string "new". A common mistake is assuming Express picks the "best" match; instead, always register more specific static routes above broader dynamic ones on the same path prefix.

Example

// Wrong order - /tasks/new never reached
app.get('/tasks/:id', (req, res) => res.json({ id: req.params.id }));
app.get('/tasks/new', (req, res) => res.send('New task form'));

// Correct order
app.get('/tasks/new', (req, res) => res.send('New task form'));
app.get('/tasks/:id', (req, res) => res.json({ id: req.params.id }));

Middleware is a function with the signature (req, res, next) that sits in the request-handling pipeline: it can inspect or modify req/res, run arbitrary code, and then either call next() to pass control along or send a response to end the cycle. A common mistake is forgetting to call next() (or send a response), which leaves the request hanging with no reply ever sent.

Example

app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
});

app.use(middlewareFn) registers middleware that runs for every incoming request regardless of method, before any route is matched. A common mistake is registering global middleware after the routes that need it (like body-parsing after a route that reads req.body), since Express only applies middleware to requests that reach it after it was registered.

Example

app.use(express.json()); // must come before routes that read req.body
app.post('/echo', (req, res) => res.json(req.body));

The request simply hangs - Express has no built-in timeout for a middleware that does nothing, so the client eventually times out waiting for a reply. A common mistake is writing a conditional inside middleware where one branch calls next() but another (perhaps an early return meant to fail the request) forgets to send a response or call next(err), silently stalling the request instead of failing fast.

16.How can you scope middleware to only a subset of routes?17.Why does the order in which middleware is registered matter?18.What is the difference between res.send() and res.json()?19.How do you set an HTTP status code on a response?20.What causes an "ERR_HTTP_HEADERS_SENT" error, and how do you avoid it?21.What is the difference between req.originalUrl and req.url inside a mounted router?22.What does res.redirect() do by default, and how do you change its behavior?23.How would you read a custom request header and validate its presence before continuing?24.How does Express recognize an error-handling middleware function?25.What does calling next(err) do?26.Where should error-handling middleware be registered relative to routes, and why?27.Why can an unhandled rejected Promise inside an async route handler be a problem?28.What is the benefit of centralizing error handling in one middleware instead of formatting errors in every route?29.What is the difference between authentication and authorization?30.What does express-session do?31.How do you structure middleware to protect a route from unauthenticated access?32.What is the tradeoff between session-based auth and JWT-based auth?33.What does the cors middleware actually do?34.What security benefit does helmet() provide, and what is a limitation of relying on it alone?35.How do you connect an Express app to MongoDB using Mongoose?36.What is the relationship between a Mongoose schema and a model?37.How would you write an async Express route that fetches a document by id and handles the "not found" case?38.What happens when Mongoose is given a malformed ObjectId, and how should a route handle it?39.Why is it important to pass { new: true } to findByIdAndUpdate(), and what does { runValidators: true } add?40.What is a common folder structure for a growing Express application?41.Why should configuration values like database URLs and secrets be read from environment variables rather than hardcoded?42.What belongs in a production checklist before deploying an Express app?43.Why is it useful to separate route definitions from controller logic in an Express app?44.How would you structure graceful shutdown for a production Express server?45.Why is it best practice to keep an Express app object separate from the file that actually starts listening?
You're viewing a free lesson. Sign up free to track your progress and unlock the full course.Sign up freeSign in