Web Server with Express.js
Express as API Server
Express.js is commonly used to build RESTful APIs.
// Install dependencies
npm init -y
npm install express cors
// Create api-server.js
const express = require('express');
const cors = require('cors');
const app = express();
// Middleware
app.use(cors());
app.use(express.json());
// Sample data
let todos = [
{ id: 1, text: 'Learn Express', completed: false },
{ id: 2, text: 'Build an API', completed: true }
];
// GET all todos
app.get('/api/todos', (req, res) => {
res.json(todos);
});
// GET single todo
app.get('/api/todos/:id', (req, res) => {
const todo = todos.find(t => t.id === parseInt(req.params.id));
if (!todo) return res.status(404).json({ error: 'Todo not found' });
res.json(todo);
});
// POST new todo
app.post('/api/todos', (req, res) => {
const todo = {
id: todos.length + 1,
text: req.body.text,
completed: false
};
todos.push(todo);
res.status(201).json(todo);
});
// PUT update todo
app.put('/api/todos/:id', (req, res) => {
const todo = todos.find(t => t.id === parseInt(req.params.id));
if (!todo) return res.status(404).json({ error: 'Todo not found' });
todo.text = req.body.text || todo.text;
todo.completed = req.body.completed ?? todo.completed;
res.json(todo);
});
// DELETE todo
app.delete('/api/todos/:id', (req, res) => {
const todoIndex = todos.findIndex(t => t.id === parseInt(req.params.id));
if (todoIndex === -1) return res.status(404).json({ error: 'Todo not found' });
todos.splice(todoIndex, 1);
res.status(204).send();
});
app.listen(3000, () => {
console.log('API Server running on port 3000');
}); Test the API with curl:
# Get all todos
curl http://localhost:3000/api/todos
# Create a new todo
curl -X POST http://localhost:3000/api/todos \
-H "Content-Type: application/json" \
-d '{"text": "New todo"}'
# Update a todo
curl -X PUT http://localhost:3000/api/todos/1 \
-H "Content-Type: application/json" \
-d '{"completed": true}'
# Delete a todo
curl -X DELETE http://localhost:3000/api/todos/1 Express Middleware
Middleware functions have access to the request and response objects:
// Logger middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something broke!' });
}); Best Practices
- Use middleware for common functionality (logging, authentication)
- Structure routes in separate files
- Implement proper error handling
- Validate input data
- Use environment variables for configuration
- Implement rate limiting for APIs
- Add proper security headers