Bird
Raised Fist0
Expressframework~20 mins

API versioning strategies in Express - Practice Problems & Coding Challenges

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
Challenge - 5 Problems
🎖️
API Versioning Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
🧠 Conceptual
intermediate
2:00remaining
Understanding URL Path Versioning
In Express.js, what is the main advantage of using URL path versioning like /api/v1/resource for API versioning?
AIt automatically updates the API version without changing client requests.
BIt hides the API version from clients to simplify URLs.
CIt allows clients to specify the API version in the URL, making it easy to route requests to different handlers.
DIt forces all clients to use the latest API version only.
Attempts:
2 left
💡 Hint
Think about how the server knows which version of the API to use based on the request URL.
component_behavior
intermediate
2:00remaining
Header Versioning Behavior
Given an Express.js API that uses a custom header X-API-Version to determine the API version, what happens if a client sends a request without this header?
Express
app.use((req, res, next) => {
  const version = req.headers['x-api-version'] || '1';
  if(version === '1') {
    // handle v1
    res.send('Response from API v1');
  } else if(version === '2') {
    // handle v2
    res.send('Response from API v2');
  } else {
    res.status(400).send('Unsupported API version');
  }
});
AThe server responds with 'Response from API v2' by default.
BThe server responds with 'Response from API v1' because it defaults to version 1.
CThe server crashes due to missing header.
DThe server responds with 'Unsupported API version' error.
Attempts:
2 left
💡 Hint
Look at how the version variable is assigned when the header is missing.
📝 Syntax
advanced
2:00remaining
Middleware Version Routing Syntax
Which Express.js middleware setup correctly routes requests to different API versions using URL path versioning?
Express
const express = require('express');
const app = express();

// Version 1 handler
const v1Router = express.Router();
v1Router.get('/users', (req, res) => res.send('Users from v1'));

// Version 2 handler
const v2Router = express.Router();
v2Router.get('/users', (req, res) => res.send('Users from v2'));

// Mount routers here
// ???

app.listen(3000);
A
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
B
app.use('/v1/api', v1Router);
app.use('/v2/api', v2Router);
C
app.use('/api', v1Router);
app.use('/api', v2Router);
D
app.use(v1Router);
app.use(v2Router);
Attempts:
2 left
💡 Hint
Think about how the URL path should include the version segment before the resource path.
🔧 Debug
advanced
2:00remaining
Debugging Query Parameter Versioning
Consider this Express.js code snippet that tries to version an API using a query parameter ?version=2. What is the bug causing all requests to respond with 'Version 2 response' regardless of the query parameter?
Express
app.get('/api/users', (req, res) => {
  const version = req.query.version;
  if(version === '2') {
    res.send('Version 2 response');
  } else {
    res.send('Version 1 response');
  }
});
AThe route path should include the version like /api/v2/users.
BThe query parameter should be accessed as req.params.version, not req.query.version.
CThe res.send calls are missing return statements.
DThe code uses assignment (=) instead of comparison (===) in the if condition.
Attempts:
2 left
💡 Hint
Check the if condition syntax carefully.
state_output
expert
2:00remaining
Output of Combined Versioning Middleware
What is the output when a client sends a GET request to /api/users with header X-API-Version: 2 given this Express.js code?
Express
const express = require('express');
const app = express();

app.use('/api', (req, res, next) => {
  req.apiVersion = req.headers['x-api-version'] || '1';
  next();
});

app.get('/api/users', (req, res) => {
  switch(req.apiVersion) {
    case '1':
      res.send('Users from API v1');
      break;
    case '2':
      res.send('Users from API v2');
      break;
    default:
      res.status(400).send('Unsupported API version');
  }
});

app.listen(3000);
AUsers from API v2
BUsers from API v1
CUnsupported API version
DError: Cannot read property 'apiVersion' of undefined
Attempts:
2 left
💡 Hint
Look at how the middleware sets req.apiVersion and how the route uses it.

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