Learn how to build a Node Express REST API with CRUD operations using this step-by-step guide for developers. We'll cover everything from initialization to deployment, creating an API that includes validation and routing using modern coding practices.
Prerequisites
Before beginning, ensure you have the following:
prerequisites
- Node.js installed on your system (v16 or later recommended).
- Basic understanding of JavaScript and Node.js.
- A code editor, such as Visual Studio Code.
- Knowledge of HTTP methods (GET, POST, PUT, DELETE) and REST API conventions.
Project Initialization
Follow these steps to set up the project and install necessary dependencies.
steps
- Create a new folder (e.g.,
express-demo). - Open a terminal and navigate into the folder:bash
cd express-demo - Initialize the project with
npm:bashThis will generate anpm init -ypackage.jsonfile. - Install Express:bash
npm install express - (Optional) Install nodemon for automatic server restarts:bash
npm install -g nodemon
Setting Up Your First Express Server
In this section, we'll create a basic Express server.
steps
- Create a new file called
index.js:bashtouch index.js - Add the following code to
index.js:javascriptconst express = require('express'); const app = express(); app.use(express.json()); // Middleware for parsing JSON requests app.get('/', (req, res) => { res.send('Welcome to the Express API!'); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); - Start the server:bashOr, with nodemon:
node index.jsbashnodemon index.js - Open a browser and visit
http://localhost:3000/to see the "Welcome to the Express API!" message.
Implementing CRUD Operations
Here, we'll define routes for Create, Read, Update, and Delete actions.
steps
- Add the following code to
index.js(after the initial setup and beforeapp.listen):javascriptlet items = []; // In-memory storage // Get all items app.get('/api/items', (req, res) => { res.send(items); }); // Get a single item by ID app.get('/api/items/:id', (req, res) => { const item = items.find(i => i.id === Number(req.params.id)); if (!item) return res.status(404).send('Item not found'); res.send(item); }); // Create a new item app.post('/api/items', (req, res) => { if (!req.body.name || req.body.name.length < 3) { return res.status(400).send('Name is required and should be at least 3 characters.'); } const newItem = { id: items.length + 1, name: req.body.name }; items.push(newItem); res.send(newItem); }); // Update an existing item app.put('/api/items/:id', (req, res) => { const item = items.find(i => i.id === Number(req.params.id)); if (!item) return res.status(404).send('Item not found'); if (!req.body.name || req.body.name.length < 3) { return res.status(400).send('Name is required and should be at least 3 characters.'); } item.name = req.body.name; res.send(item); }); // Delete an item app.delete('/api/items/:id', (req, res) => { const item = items.find(i => i.id === Number(req.params.id)); if (!item) return res.status(404).send('Item not found'); items = items.filter(i => i.id !== Number(req.params.id)); res.send(item); }); - Use a REST client like Postman, curl, or a browser extension tool to test the following routes:
- GET
/api/items - POST
/api/itemswith a JSON body:{ "name": "Sample Item" } - PUT
/api/items/:idwith a JSON body:{ "name": "Updated Item" } - DELETE
/api/items/:id
- GET
Organizing Code and Enhancing User Experience
Refactor your project structure to keep the codebase maintainable and reusable.
steps
- Create a new folder named
routes:bashmkdir routes - Create a new file in the
routesfolder for managing items:bashtouch routes/items.js - Move the
.get(),.post(),.put(), and.delete()routes toroutes/items.js:javascriptconst express = require('express'); const router = express.Router(); let items = []; // In-memory storage router.get('/', (req, res) => { res.send(items); }); router.get('/:id', (req, res) => { const item = items.find(i => i.id === Number(req.params.id)); if (!item) return res.status(404).send('Item not found'); res.send(item); }); router.post('/', (req, res) => { if (!req.body.name || req.body.name.length < 3) { return res.status(400).send('Name is required and should be at least 3 characters.'); } const newItem = { id: items.length + 1, name: req.body.name }; items.push(newItem); res.send(newItem); }); router.put('/:id', (req, res) => { const item = items.find(i => i.id === Number(req.params.id)); if (!item) return res.status(404).send('Item not found'); if (!req.body.name || req.body.name.length < 3) { return res.status(400).send('Name is required and should be at least 3 characters.'); } item.name = req.body.name; res.send(item); }); router.delete('/:id', (req, res) => { const item = items.find(i => i.id === Number(req.params.id)); if (!item) return res.status(404).send('Item not found'); items = items.filter(i => i.id !== Number(req.params.id)); res.send(item); }); module.exports = router; - Update
index.jsto use this router:javascriptconst express = require('express'); const itemsRouter = require('./routes/items'); const app = express(); app.use(express.json()); app.use('/api/items', itemsRouter); app.get('/', (req, res) => { res.send('Welcome to the Express API!'); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); - Restart your server with
nodemonto test the refactored code.
Deploying the Application
Deploying prepares your API for production.
steps
- Ensure dynamic port allocation is in place:javascript
const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); - Test thoroughly to ensure all endpoints work as expected.
- Choose a hosting provider (e.g., AWS, Heroku, Digital Ocean).
- Follow your provider's guides for uploading your application.
FAQ
How do I test a Node Express REST API locally?
You can use tools like Postman, curl, or browser extensions to send HTTP requests to the API endpoints running on your local server (e.g., http://localhost:3000/api).
What is Express used for in a Node.js REST API?
Express is a web framework for Node.js that simplifies building REST APIs by providing a structured way to define routes, handle middleware, and process HTTP requests.
Do I need a database for CRUD operations in Express?
Not necessarily. For simplicity, you can use in-memory storage (like an array) during development, but in production, a database like MongoDB or PostgreSQL is typically used for persistence.
Official reference: Express API reference.