API version control v1 v2 in NodeJs (loosely coupled)
Step 1: Create a Node.js Project
mkdir node-api-version-control
cd node-api-version-control
npm init -y
Step 2: Install Express.js
npm install express
Step 3: Create an Express App (app.js)
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
app.get('/api/v1/resource', (req, res) => {
res.json({ version: 'v1', data: 'Resource data for version 1' });
});
app.get('/api/v2/resource', (req, res) => {
res.json({ version: 'v2', data: 'Resource data for version 2' });
});
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
Step 4: Run the Node.js Server
node app.js
Step 5: Test API Endpoints - Open a web browser or use tools like curl or Postman to test the following endpoints: - http://localhost:3000/api/v1/resource - http://localhost:3000/api/v2/resource
Step 6: Separate Route Handlers Create a folder named "routes" and create separate files for each version (v1.js and v2.js).
v1.js:
const express = require('express');
const router = express.Router();
router.get('/resource', (req, res) => {
res.json({ version: 'v1', data: 'Resource data for version 1' });
});
module.exports = router;
v2.js:
const express = require('express');
const router = express.Router();
router.get('/resource', (req, res) => {
res.json({ version: 'v2', data: 'Resource data for version 2' });
});
module.exports = router;
Update app.js:
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
const v1Routes = require('./routes/v1');
const v2Routes = require('./routes/v2');
app.use('/api/v1', v1Routes);
app.use('/api/v2', v2Routes);
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
Step 7: Enhance Version Control (Middleware) Create a middleware function to handle versioning.
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
const versionMiddleware = (req, res, next) => {
const apiVersion = req.params.version;
if (apiVersion === 'v1') {
req.apiVersion = 'v1';
next();
} else if (apiVersion === 'v2') {
req.apiVersion = 'v2';
next();
} else {
res.status(400).json({ error: 'Invalid API version' });
}
};
app.use('/api/:version/resource', versionMiddleware, (req, res) => {
const { apiVersion } = req;
res.json({ version: apiVersion, data: `Resource data for ${apiVersion}` });
});
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
Step 8: Test Enhanced Version Control
- Update the routes in v1.js and v2.js to use /:version/resource
.
- Test the following endpoints:
- http://localhost:3000/api/v1/resource
- http://localhost:3000/api/v2/resource
- http://localhost:3000/api/invalid/resource (should return a 400 error)
Step 9: Loose Coupling (Dependency Injection) Use dependency injection to make route handlers independent of the app object.
Update v1.js and v2.js:
const express = require('express');
const router = express.Router();
const resourceHandler = (req, res) => {
const { apiVersion } = req;
res.json({ version: apiVersion, data: `Resource data for ${apiVersion}` });
};
router.get('/resource', resourceHandler);
module.exports = { resourceHandler };
Update app.js:
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
const versionMiddleware = (req, res, next) => {
const apiVersion = req.params.version;
if (apiVersion === 'v1') {
req.apiVersion = 'v1';
next();
} else if (apiVersion === 'v2') {
req.apiVersion = 'v2';
next();
} else {
res.status(400).json({ error: 'Invalid API version' });
}
};
const v1Routes = require('./routes/v1');
const v2Routes = require('./routes/v2');
app.use('/api/v1', versionMiddleware, v1Routes.resourceHandler);
app.use('/api/v2', versionMiddleware, v2Routes.resourceHandler);
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});