正在加载,请稍候…

API Versioning Strategies: URL, Header, and Content Negotiation

Choose the right API versioning strategy for your REST API. Compare URL versioning, header versioning, and content negotiation with practical implementation examples.

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.