API Versioning Strategies
API versioning lets you evolve your API without breaking existing clients.
URL Path Versioning
GET /api/v1/users
GET /api/v2/users
// Express.js
const v1Router = express.Router();
const v2Router = express.Router();
v1Router.get('/users', v1UserController.list);
v2Router.get('/users', v2UserController.list); // enhanced response
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
// NestJS
@Controller({ version: '1', path: 'users' })
class UsersV1Controller { }
@Controller({ version: '2', path: 'users' })
class UsersV2Controller { }
Pros: Simple, visible in URLs, easy to route Cons: URL should represent resource, not version; cache fragmentation
Header Versioning
GET /api/users
Accept-Version: 1.0
# or
API-Version: 2
// Express middleware
function versionMiddleware(req: Request, res: Response, next: NextFunction) {
const version = req.header('API-Version') || req.header('Accept-Version') || '1';
req.apiVersion = parseInt(version);
next();
}
app.get('/api/users', versionMiddleware, (req, res) => {
if (req.apiVersion >= 2) {
return userController.listV2(req, res);
}
return userController.listV1(req, res);
});
Pros: Clean URLs, RESTful Cons: Less visible, harder to test in browser
Content Negotiation (Accept Header)
GET /api/users
Accept: application/vnd.myapp.v2+json
app.get('/api/users', (req, res) => {
const accept = req.header('Accept') || '';
if (accept.includes('vnd.myapp.v2')) {
return res.json(formatV2(users));
}
return res.json(formatV1(users));
});
Deprecation Strategy
// Add deprecation headers
app.use('/api/v1/*', (req, res, next) => {
res.set('Deprecation', 'true');
res.set('Sunset', 'Sat, 1 Jan 2026 00:00:00 GMT');
res.set('Link', '</api/v2>; rel="successor-version"');
next();
});
Versioning Checklist
- [ ] Define what constitutes a breaking change:
- Removing fields
- Changing field types
- Removing endpoints
- Changing authentication
- [ ] Non-breaking changes don't need new version:
- Adding optional fields
- Adding new endpoints
- Adding optional query params
- [ ] Communicate sunset dates to API consumers
- [ ] Maintain versions for minimum 12 months after sunset announcement
For most APIs, URL versioning offers the best balance of simplicity and visibility.