← Back to Node.js Menu | 🏠 Hub
| Action | Method | URL | Status |
|---|---|---|---|
| Get all users | GET | /api/users | 200 |
| Get one user | GET | /api/users/:id | 200 / 404 |
| Create user | POST | /api/users | 201 |
| Update user | PUT | /api/users/:id | 200 / 404 |
| Delete user | DELETE | /api/users/:id | 204 / 404 |
// server.js — complete users API (no database yet)
const express = require('express');
const app = express();
app.use(express.json());
// In-memory "database"
let users = [
{ id: 1, name: 'Ko Ko', email: 'ko@example.com', role: 'admin' },
{ id: 2, name: 'Ma Ma', email: 'ma@example.com', role: 'user' },
];
let nextId = 3;
// GET all — with optional search
app.get('/api/users', (req, res) => {
const { search, role } = req.query;
let result = [...users];
if (search) result = result.filter(u =>
u.name.toLowerCase().includes(search.toLowerCase()) ||
u.email.toLowerCase().includes(search.toLowerCase())
);
if (role) result = result.filter(u => u.role === role);
res.json({ data: result, total: result.length });
});
// GET one
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === Number(req.params.id));
if (!user) return res.status(404).json({ error: 'User not found' });
res.json(user);
});
// POST — create
app.post('/api/users', (req, res) => {
const { name, email, role = 'user' } = req.body;
// Validation
if (!name || !email)
return res.status(400).json({ error: 'name and email required' });
if (users.find(u => u.email === email))
return res.status(409).json({ error: 'Email already exists' });
const user = { id: nextId++, name, email, role };
users.push(user);
res.status(201).json(user);
});
// PUT — update
app.put('/api/users/:id', (req, res) => {
const idx = users.findIndex(u => u.id === Number(req.params.id));
if (idx === -1) return res.status(404).json({ error: 'Not found' });
users[idx] = { ...users[idx], ...req.body, id: users[idx].id };
res.json(users[idx]);
});
// DELETE
app.delete('/api/users/:id', (req, res) => {
const idx = users.findIndex(u => u.id === Number(req.params.id));
if (idx === -1) return res.status(404).json({ error: 'Not found' });
users.splice(idx, 1);
res.status(204).end();
});
app.listen(3000, () => console.log('API at http://localhost:3000'));
// Manual validation helper
function validateUser(data) {
const errors = [];
if (!data.name || typeof data.name !== 'string')
errors.push('name is required and must be string');
if (data.name?.length < 2)
errors.push('name must be at least 2 characters');
if (!data.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email))
errors.push('valid email is required');
if (data.age && (isNaN(data.age) || data.age < 0 || data.age > 150))
errors.push('age must be 0-150');
return errors;
}
app.post('/api/users', (req, res) => {
const errors = validateUser(req.body);
if (errors.length) return res.status(400).json({ errors });
// proceed...
});
// Or use express-validator package
// npm install express-validator
const { body, validationResult } = require('express-validator');
app.post('/api/users', [
body('name').notEmpty().trim().isLength({ min: 2 }),
body('email').isEmail().normalizeEmail(),
body('age').optional().isInt({ min: 0, max: 150 })
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) return res.status(400).json({ errors: errors.array() });
// validated data available
});
// Consistent API response format
function success(res, data, statusCode = 200) {
return res.status(statusCode).json({
success: true,
data,
timestamp: new Date().toISOString()
});
}
function error(res, message, statusCode = 400) {
return res.status(statusCode).json({
success: false,
error: message,
timestamp: new Date().toISOString()
});
}
// Usage
app.get('/api/users', async (req, res) => {
try {
const users = await User.findAll();
return success(res, users);
} catch (err) {
return error(res, err.message, 500);
}
});
// Test with Thunder Client (VS Code) or curl:
// curl http://localhost:3000/api/users
// curl -X POST http://localhost:3000/api/users \
// -H "Content-Type: application/json" \
// -d '{"name":"Ko","email":"ko@test.com"}'
← Node.js 04 | Next: Node.js 06 → MySQL + .env →