Quick reference Express.js. Routing, middleware, request/response, error handling, dan best practices untuk building Node.js REST APIs.
Cara menginstall Express.js dan dependencies yang diperlukan untuk memulai development.
npm init -y
npm install express
# With TypeScript
npm install --save-dev typescript @types/node @types/expressCara membuat server Express.js sederhana dengan route dasar untuk memulai aplikasi.
const express = require('express');
const app = express();
const PORT = 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});Routing adalah cara Express menangani permintaan HTTP ke endpoint yang berbeda.
Metode HTTP yang didukung Express untuk berbagai jenis operasi API.
app.get('/users', (req, res) => {}); // GET
app.post('/users', (req, res) => {}); // POST
app.put('/users/:id', (req, res) => {}); // PUT
app.patch('/users/:id', (req, res) => {});// PATCH
app.delete('/users/:id', (req, res) => {});// DELETE
// All methods
app.all('/secret', (req, res) => {});
// Multiple methods on same route
app.route('/book')
.get((req, res) => {})
.post((req, res) => {})
.put((req, res) => {});Route parameters memungkinkan kita menangkap nilai dinamis dari URL.
// Single parameter
app.get('/users/:id', (req, res) => {
const id = req.params.id;
res.send(`User ${id}`);
});
// Multiple parameters
app.get('/users/:userId/posts/:postId', (req, res) => {
const { userId, postId } = req.params;
});
// Optional parameters (regex)
app.get('/users/:id(\\d+)?', (req, res) => {});Query parameters adalah bagian dari URL yang mengandung data tambahan seperti filter atau pagination.
// /search?q=javascript&page=2
app.get('/search', (req, res) => {
const { q, page = 1 } = req.query;
res.json({ q, page });
});Router module memungkinkan kita memisahkan route ke file terpisah untuk organisasi kode yang lebih baik.
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {});
router.post('/', (req, res) => {});
router.put('/:id', (req, res) => {});
module.exports = router;
// server.js
const usersRouter = require('./routes/users');
app.use('/users', usersRouter);Middleware adalah fungsi yang menjalankan tugas tertentu sebelum request sampai ke route handler.
Middleware bawaan Express untuk parsing request body dan serving static files.
// Parse JSON body
app.use(express.json());
// Parse URL-encoded body
app.use(express.urlencoded({ extended: true }));
// Serve static files from 'public' directory
app.use(express.static('public'));
// Serve from specific path
app.use('/static', express.static('public'));Cara membuat middleware custom untuk keperluan tertentu seperti logging atau authentication.
// Application-level
app.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});
// Route-level
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
};
app.get('/users', logger, (req, res) => {});
// Multiple middleware
app.get('/users', middleware1, middleware2, (req, res) => {});Middleware dari package npm yang populer untuk menambah fitur keamanan dan utility.
npm install cors helmet morgan compression cookie-parserconst cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const compression = require('compression');
const cookieParser = require('cookie-parser');
app.use(cors()); // CORS
app.use(helmet()); // Security headers
app.use(morgan('dev')); // Logging
app.use(compression()); // Gzip
app.use(cookieParser()); // Parse cookiesCara menangani error di Express dengan middleware khusus untuk error.
// 404 handler (after all routes)
app.use((req, res, next) => {
res.status(404).json({ error: 'Not Found' });
});
// Error handler (4 parameters!)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(err.status || 500).json({
error: err.message
});
});Request object berisi semua informasi tentang HTTP request yang masuk ke server.
app.post('/api/users', (req, res) => {
// Body data
const { name, email } = req.body;
// Route parameters
const id = req.params.id;
// Query parameters
const page = req.query.page;
// Headers
const userAgent = req.get('User-Agent');
const auth = req.headers.authorization;
// Cookies
const token = req.cookies.token;
// Request properties
req.method; // POST
req.url; // Full URL
req.path; // Path only
req.hostname; // Domain
req.ip; // Client IP
req.protocol; // http or https
req.secure; // true if HTTPS
});Berbagai method yang tersedia untuk mengirim response kembali ke client.
app.get('/api/demo', (req, res) => {
// Send string/HTML
res.send('Hello');
res.send('<h1>Hello</h1>');
// Send JSON
res.json({ name: 'Galih' });
// Send status only
res.sendStatus(404); // Sends "Not Found"
// Set status + send
res.status(201).json({ created: true });
// Redirect
res.redirect('/new-url');
res.redirect(301, '/permanent-url');
// Download file
res.download('/path/to/file.pdf');
// Send file
res.sendFile('/path/to/file.html');
// Set headers
res.set('Content-Type', 'text/html');
res.header('X-Custom', 'value');
// Set cookie
res.cookie('name', 'value', {
maxAge: 900000,
httpOnly: true,
secure: true
});
// Clear cookie
res.clearCookie('name');
// End response
res.end();
});Contoh lengkap implementasi REST API dengan semua operasi CRUD dasar.
const express = require('express');
const app = express();
app.use(express.json());
let users = [];
// GET all
app.get('/api/users', (req, res) => {
res.json(users);
});
// GET one
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === req.params.id);
if (!user) return res.status(404).json({ error: 'Not found' });
res.json(user);
});
// CREATE
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
const user = { id: Date.now().toString(), name, email };
users.push(user);
res.status(201).json(user);
});
// UPDATE
app.put('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === req.params.id);
if (!user) return res.status(404).json({ error: 'Not found' });
Object.assign(user, req.body);
res.json(user);
});
// DELETE
app.delete('/api/users/:id', (req, res) => {
const index = users.findIndex(u => u.id === req.params.id);
if (index === -1) return res.status(404).json({ error: 'Not found' });
users.splice(index, 1);
res.sendStatus(204);
});Cara mengintegrasikan Express dengan berbagai database untuk penyimpanan data.
Cara menggunakan PostgreSQL sebagai database dengan package pg.
npm install pgconst { Pool } = require('pg');
const pool = new Pool({
user: 'postgres',
host: 'localhost',
database: 'mydb',
password: 'password',
port: 5432,
});
app.get('/api/users', async (req, res) => {
const result = await pool.query('SELECT * FROM users');
res.json(result.rows);
});ORM modern untuk Node.js yang memudahkan interaksi dengan database.
npm install @prisma/client
npx prisma initconst { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
app.get('/api/users', async (req, res) => {
const users = await prisma.user.findMany();
res.json(users);
});Library untuk validasi data yang type-safe dan mudah digunakan.
npm install zodconst { z } = require('zod');
const userSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
age: z.number().int().min(18).optional()
});
const validate = (schema) => (req, res, next) => {
try {
schema.parse(req.body);
next();
} catch (err) {
res.status(400).json({ errors: err.errors });
}
};
app.post('/api/users', validate(userSchema), (req, res) => {
res.status(201).json(req.body);
});Implementasi authentication menggunakan JSON Web Tokens untuk keamanan API.
npm install jsonwebtoken bcryptconst jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const SECRET = process.env.JWT_SECRET;
// Register
app.post('/auth/register', async (req, res) => {
const { email, password } = req.body;
const hash = await bcrypt.hash(password, 10);
// Save to database
res.status(201).json({ message: 'User created' });
});
// Login
app.post('/auth/login', async (req, res) => {
const { email, password } = req.body;
// Find user from database
const user = { id: 1, email, password: '$hash' };
const isValid = await bcrypt.compare(password, user.password);
if (!isValid) return res.status(401).json({ error: 'Invalid' });
const token = jwt.sign({ userId: user.id }, SECRET, { expiresIn: '1h' });
res.json({ token });
});
// Auth middleware
const authenticate = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'No token' });
try {
const decoded = jwt.verify(token, SECRET);
req.user = decoded;
next();
} catch {
res.status(403).json({ error: 'Invalid token' });
}
};
// Protected route
app.get('/api/profile', authenticate, (req, res) => {
res.json({ user: req.user });
});Middleware untuk menangani upload file dari client ke server.
npm install multerconst multer = require('multer');
const storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, 'uploads/'),
filename: (req, file, cb) => {
const uniqueName = `${Date.now()}-${file.originalname}`;
cb(null, uniqueName);
}
});
const upload = multer({
storage,
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
fileFilter: (req, file, cb) => {
if (file.mimetype.startsWith('image/')) {
cb(null, true);
} else {
cb(new Error('Only images allowed'));
}
}
});
// Single file
app.post('/upload', upload.single('file'), (req, res) => {
res.json({ file: req.file });
});
// Multiple files
app.post('/upload-multi', upload.array('files', 5), (req, res) => {
res.json({ files: req.files });
});Cara menggunakan environment variables untuk konfigurasi aplikasi yang aman.
npm install dotenvPORT=3000
DATABASE_URL=postgresql://user:pass@localhost:5432/db
JWT_SECRET=your-secret-key
NODE_ENV=developmentrequire('dotenv').config();
const PORT = process.env.PORT || 3000;
const DB_URL = process.env.DATABASE_URL;Praktik keamanan penting untuk melindungi aplikasi Express dari berbagai ancaman.
npm install helmet cors express-rate-limitconst helmet = require('helmet');
const cors = require('cors');
const rateLimit = require('express-rate-limit');
// Security headers
app.use(helmet());
// CORS
app.use(cors({
origin: 'https://yourdomain.com',
credentials: true
}));
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 min
max: 100 // 100 requests per window
});
app.use('/api/', limiter);
// Body size limit
app.use(express.json({ limit: '10mb' }));Cara menangani error dalam kode async/await dengan elegan.
// Wrapper function
const asyncHandler = (fn) => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
// Usage
app.get('/api/users/:id', asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) throw new Error('Not found');
res.json(user);
}));
// Custom error class
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
}
}
// Throw custom error
throw new AppError('User not found', 404);Cara menulis dan menjalankan test untuk API Express menggunakan Jest dan Supertest.
npm install --save-dev jest supertestconst request = require('supertest');
const app = require('./app');
describe('GET /api/users', () => {
it('should return all users', async () => {
const res = await request(app).get('/api/users');
expect(res.statusCode).toBe(200);
expect(res.body).toBeInstanceOf(Array);
});
});
describe('POST /api/users', () => {
it('should create user', async () => {
const res = await request(app)
.post('/api/users')
.send({ name: 'Test', email: 'test@example.com' });
expect(res.statusCode).toBe(201);
expect(res.body).toHaveProperty('id');
});
});Struktur folder yang direkomendasikan untuk proyek Express.js yang terorganisir.
my-app/
├── src/
│ ├── controllers/
│ │ ├── userController.js
│ │ └── authController.js
│ ├── routes/
│ │ ├── userRoutes.js
│ │ └── authRoutes.js
│ ├── middleware/
│ │ ├── auth.js
│ │ ├── validate.js
│ │ └── errorHandler.js
│ ├── models/
│ │ └── User.js
│ ├── utils/
│ │ └── helpers.js
│ └── app.js
├── .env
├── .gitignore
├── package.json
└── server.jsKode status HTTP yang umum digunakan dalam response API.
| Code | Meaning |
|---|---|
| 200 | OK - Success |
| 201 | Created - Resource created |
| 204 | No Content - Success, no response body |
| 400 | Bad Request - Invalid input |
| 401 | Unauthorized - Not authenticated |
| 403 | Forbidden - Not authorized |
| 404 | Not Found - Resource not found |
| 409 | Conflict - Duplicate resource |
| 422 | Unprocessable Entity - Validation failed |
| 500 | Internal Server Error - Server error |
Cara deploy aplikasi Express ke production menggunakan PM2.
# Install PM2
npm install -g pm2
# Start app
pm2 start server.js --name my-app
# Auto-restart on crash
pm2 startup
pm2 save
# Monitor
pm2 monit
# Logs
pm2 logs
# Stop/Restart
pm2 stop my-app
pm2 restart my-appDaftar praktik terbaik yang harus diikuti untuk membuat aplikasi Express yang berkualitas.
NODE_ENV=productionLink-link berguna untuk belajar Express.js lebih dalam.
Happy building!
Login atau daftar akun gratis untuk membaca cheat sheet ini.