Webhooks and File Uploads in REST APIs
webhooks, webhook design, webhook security, HMAC signature, file upload, multipart form data, Multer, cloud storage, S3 upload, file validation
Webhooks and File Uploads in REST APIs
REST APIs are request-response systems โ the client asks, the server answers. But many real-world scenarios require the server to notify the client when something happens asynchronously. Webhooks solve this problem. File uploads are another common REST API requirement that requires special handling.
What Are Webhooks
A webhook is an HTTP POST request sent by your server to a URL provided by the client when a specific event occurs. Instead of the client polling your API every minute to check for new orders, your API sends a POST to the client's webhook URL the moment an order is placed. Webhooks are used by Stripe (payment events), GitHub (repository events), and Twilio (SMS delivery receipts).
Webhook Security with HMAC Signatures
When you send a webhook, sign the payload with HMAC-SHA256 and include the signature in a header. The recipient verifies it to confirm the request came from you and was not tampered with:
const crypto = require('crypto');
const signWebhook = (payload, secret) => {
return crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
};
const verifyWebhook = (payload, signature, secret) => {
const expected = signWebhook(payload, secret);
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
};Always use crypto.timingSafeEqual for signature comparison to prevent timing attacks.
File Uploads with Multer
npm install multer
const upload = multer({
limits: { fileSize: 5 * 1024 * 1024 },
fileFilter: (req, file, cb) => {
const allowed = ['image/jpeg', 'image/png', 'image/webp'];
cb(null, allowed.includes(file.mimetype));
}
});
router.post('/avatar', protect, upload.single('avatar'), uploadAvatar);Always validate file type by checking the MIME type, not just the file extension. Enforce maximum file size limits. Never store uploaded files on the application server โ upload them to cloud storage (AWS S3, Cloudinary) and store only the URL in your database.
