Bird
Raised Fist0
Expressframework~10 mins

API versioning strategies in Express - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - API versioning strategies
Client sends request
Check version info
Match version strategy
URL versioning
Header versioning
Query param versioning
Accept header versioning
Route to correct API handler
Send response
The server checks the client's version info using different strategies, then routes the request to the matching API version handler.
Execution Sample
Express
const express = require('express');
const app = express();

app.get('/v1/users', (req, res) => res.send('Users v1'));
app.get('/v2/users', (req, res) => res.send('Users v2'));

app.listen(3000);
This code shows URL versioning by using different URL paths for API versions.
Execution Table
StepRequest URLVersion DetectedRouting ActionResponse Sent
1/v1/usersv1Route to /v1/users handlerUsers v1
2/v2/usersv2Route to /v2/users handlerUsers v2
3/users?version=1No version in URL pathNo match, 404 or fallbackError or fallback response
4/usersNo version infoNo match, 404 or fallbackError or fallback response
💡 Requests without version info in URL path do not match any route and stop with error or fallback.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4
Request URL/v1/users/v2/users/users?version=1/users
Version DetectedNonev1v2NoneNone
Routing ActionNoneRoute to /v1/users handlerRoute to /v2/users handlerNo matchNo match
Response SentNoneUsers v1Users v2Error or fallbackError or fallback
Key Moments - 2 Insights
Why does the request to '/users?version=1' not match any route in the example?
Because the example only defines versioning in the URL path (like '/v1/users'), not in query parameters. So '/users?version=1' does not match any defined route (see execution_table row 3).
How does the server know which version to use when using URL versioning?
It looks at the URL path prefix like '/v1/' or '/v2/' to detect the version and route accordingly (see execution_table rows 1 and 2).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what response is sent when the request URL is '/v2/users'?
AUsers v1
BUsers v2
CError or fallback response
DNo response
💡 Hint
Check execution_table row 2 under 'Response Sent'
At which step does the version detection fail to find a version in the URL path?
AStep 1
BStep 2
CStep 3
DStep 4
💡 Hint
Look at 'Version Detected' column in execution_table rows 3 and 4
If we add a header versioning strategy, how would the routing action change for '/users' with header 'API-Version: 1'?
ARoute to /v1/users handler
BNo match, 404 or fallback
CRoute to /v2/users handler
DRoute to default handler
💡 Hint
Header versioning uses headers to detect version, so routing can match even if URL path lacks version
Concept Snapshot
API versioning lets servers handle multiple API versions.
Common strategies:
- URL versioning: /v1/resource
- Header versioning: custom header like 'API-Version'
- Query param versioning: ?version=1
Server checks version info, routes to matching handler.
Helps keep old clients working while updating API.
Full Transcript
API versioning strategies help servers manage different versions of an API. The server checks the client's request for version information using methods like URL path prefixes, headers, or query parameters. Based on the detected version, the server routes the request to the correct version handler. For example, URL versioning uses paths like '/v1/users' or '/v2/users' to distinguish versions. If a request lacks version info or uses an unsupported method, the server may return an error or fallback response. This approach allows APIs to evolve without breaking existing clients.

Practice

(1/5)
1. Which of the following is a common method to implement API versioning in Express?
easy
A. Using the URL path to specify the version, like /v1/users
B. Changing the database schema for each version
C. Using different port numbers for each API version
D. Renaming the Express app for each version

Solution

  1. Step 1: Understand common API versioning methods

    API versioning often uses the URL path, headers, or query parameters to distinguish versions.
  2. Step 2: Identify the correct method in Express

    Using the URL path like /v1/users is a standard and clear way to version APIs in Express.
  3. Final Answer:

    Using the URL path to specify the version, like /v1/users -> Option A
  4. Quick Check:

    URL path versioning = Using the URL path to specify the version, like /v1/users [OK]
Hint: API versions often appear in the URL path [OK]
Common Mistakes:
  • Thinking database changes are API versioning
  • Using different ports instead of URL or headers
  • Renaming the app does not affect API versioning
2. Which Express code snippet correctly sets up API versioning using URL path?
easy
A. app.get('v1/users', userRouter);
B. app.use('/v1/users', userRouter);
C. app.route('/users/v1').get(userRouter);
D. app.listen('/v1/users', userRouter);

Solution

  1. Step 1: Review Express routing syntax

    Express uses app.use(path, router) to mount routers on paths.
  2. Step 2: Identify correct versioning path usage

    Using app.use('/v1/users', userRouter); correctly mounts the router for version 1 users.
  3. Final Answer:

    app.use('/v1/users', userRouter); -> Option B
  4. Quick Check:

    Correct Express routing = app.use('/v1/users', userRouter); [OK]
Hint: Use app.use with path and router for versioning [OK]
Common Mistakes:
  • Missing leading slash in path
  • Using app.get instead of app.use for routers
  • Incorrect method like app.listen for routing
3. Given this Express code, what is the response when a client requests /api/users?
const express = require('express');
const app = express();

app.use('/api/v1/users', (req, res) => res.send('Version 1 users'));
app.use('/api/v2/users', (req, res) => res.send('Version 2 users'));

app.listen(3000);
medium
A. Cannot GET /api/users
B. Version 2 users
C. Version 1 users
D. Server error

Solution

  1. Step 1: Check defined routes

    Routes are defined only for /api/v1/users and /api/v2/users.
  2. Step 2: Analyze request path

    The request is for /api/users, which does not match any defined route.
  3. Final Answer:

    Cannot GET /api/users -> Option A
  4. Quick Check:

    Undefined route returns 404 = Cannot GET /api/users [OK]
Hint: Check exact route paths before guessing response [OK]
Common Mistakes:
  • Assuming /api/users matches /api/v1/users
  • Expecting default route without defining it
  • Confusing middleware with route handlers
4. Identify the error in this Express API versioning code:
const express = require('express');
const app = express();

app.use('/v1/users', userRouter);
app.use('/v2/users', userRouter);

app.listen(3000);
Assuming userRouter handles all user routes.
medium
A. Both versions use the same router instance, causing version conflicts
B. Missing const before userRouter
C. Routes should use app.get instead of app.use
D. No error; this is a valid versioning setup

Solution

  1. Step 1: Understand router reuse in Express

    Using the same router instance for different paths is valid and common in Express.
  2. Step 2: Check for syntax and method correctness

    Using app.use to mount routers on different paths is correct; no syntax errors present.
  3. Final Answer:

    No error; this is a valid versioning setup -> Option D
  4. Quick Check:

    Router reuse with different paths is valid = No error; this is a valid versioning setup [OK]
Hint: Reusing routers for versions is allowed in Express [OK]
Common Mistakes:
  • Thinking router reuse causes conflicts
  • Confusing app.use with app.get for routers
  • Expecting separate router instances per version
5. You want to support API versioning in Express using request headers instead of URL paths. Which code snippet correctly reads the version from the header X-API-Version and routes accordingly?
hard
A. app.use('/v1/users', userRouter); app.use('/v2/users', userV2Router);
B. app.use('/users', (req, res) => { const version = req.query.version; if (version === '1') userRouter(req, res); else userV2Router(req, res); });
C. app.use((req, res, next) => { const version = req.headers['x-api-version']; if (version === '1') userRouter(req, res, next); else if (version === '2') userV2Router(req, res, next); else res.status(400).send('Invalid API version'); });
D. app.get('/users', (req, res) => { const version = req.headers['api-version']; if (version === '1') res.send('User v1'); else res.send('User v2'); });

Solution

  1. Step 1: Identify header-based versioning approach

    Version is read from X-API-Version header in the request.
  2. Step 2: Check routing logic based on header

    app.use((req, res, next) => { const version = req.headers['x-api-version']; if (version === '1') userRouter(req, res, next); else if (version === '2') userV2Router(req, res, next); else res.status(400).send('Invalid API version'); }); reads the header, then calls the correct router or returns error if invalid.
  3. Final Answer:

    app.use((req, res, next) => { const version = req.headers['x-api-version']; if (version === '1') userRouter(req, res, next); else if (version === '2') userV2Router(req, res, next); else res.status(400).send('Invalid API version'); }); -> Option C
  4. Quick Check:

    Header-based routing = app.use((req, res, next) => { const version = req.headers['x-api-version']; if (version === '1') userRouter(req, res, next); else if (version === '2') userV2Router(req, res, next); else res.status(400).send('Invalid API version'); }); [OK]
Hint: Use middleware to check headers and route accordingly [OK]
Common Mistakes:
  • Using query parameters instead of headers
  • Not calling next() or router properly
  • Checking wrong header name