After this lesson, you will be able to: Handle file uploads (multer), send email (Resend / Nodemailer), call external APIs (fetch).
The three side-quests every real Node app needs.
For form-data uploads (the legacy approach).
import multer from "multer";import path from "node:path";const upload = multer({storage: multer.diskStorage({destination: "./uploads/",filename: (_req, file, cb) => cb(null, `${Date.now()}-${file.originalname}`),}),limits: { fileSize: 5 * 1024 * 1024 }, // 5MB capfileFilter: (_req, file, cb) => {if (![".jpg", ".png"].includes(path.extname(file.originalname))) {return cb(new Error("only images"));}cb(null, true);},});app.post("/upload", upload.single("image"), (req, res) => {res.json({ filename: req.file?.filename });});// Modern preference: presigned S3 URLs (browser uploads direct).
Best modern email API for Node.
import { Resend } from "resend";const resend = new Resend(process.env.RESEND_API_KEY);await resend.emails.send({from: "[email protected]",to: "[email protected]",subject: "Welcome",html: "<h1>Hello</h1><p>Welcome to our service.</p>",});// Always set up SPF, DKIM, DMARC on your sending domain.// Test with mail-tester.com; aim for 10/10 score.
fetch is global in Node 18+. Add timeout + retry for production.
async function fetchWithRetry(url, opts = {}, { tries = 3, timeoutMs = 5000 } = {}) {for (let i = 0; i < tries; i++) {try {const ctrl = new AbortController();const t = setTimeout(() => ctrl.abort(), timeoutMs);const r = await fetch(url, { ...opts, signal: ctrl.signal });clearTimeout(t);if (!r.ok) throw new Error(`HTTP ${r.status}`);return await r.json();} catch (e) {if (i === tries - 1) throw e;await new Promise((res) => setTimeout(res, 2 ** i * 500)); // backoff}}}// For heavy use: undici (Node's underlying fetch impl) supports connection pooling explicitly.
Trusting user-supplied filenames. Always sanitize or rename. Storing uploads on local disk in cloud deploys. Ephemeral container filesystems lose data. Use S3/R2/Blob. Sending email from `[email protected]` without proper SPF/DKIM/DMARC. Goes to spam. No timeout on fetch. Hangs forever when API is slow.
Pick the cleanest answer.
Sign in and purchase access to unlock this lesson.