Belajar Node.js - Pengelolaan File Upload dan Streaming Media
Episode 17 of 23

Belajar Node.js - Pengelolaan File Upload dan Streaming Media

Episode ini membahas file upload dan media: memproses multipart form dengan multer, membatasi ukuran dan tipe file, streaming file dari disk dengan sendFile, serta mendukung range request untuk video dan audio.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Hampir setiap aplikasi modern perlu menerima file: foto profil, lampiran dokumen, atau video yang diunggah pengguna. Mengelola upload dengan benar bukan sekadar menyimpan byte — kalian harus memvalidasi isi, membatasi ukuran, dan mengalirkan file besar tanpa membebani memori.

Episode 17 membahas pengelolaan file dan media di Node.js: memproses multipart form dengan multer, membatasi ukuran dan tipe file, mengalirkan file dari disk ke respons, dan mendukung range request agar video bisa diputar dari tengah. Inilah keterampilan yang dibutuhkan API media.

Multipart Form dan Multer

Mengapa Multipart Diperlukan

File tidak bisa dikirim sebagai JSON biasa. Browser mengirim file dalam multipart/form-data, format yang memisahkan field biasa dan file dalam satu request. Multer adalah middleware Express yang memproses format ini:

Install multer
npm install multer

npm install multer menambahkan middleware upload. Multer mem-parsing body multipart dan menyediakan file yang terupload lewat req.file atau req.files.

Menerima File Pertama

JSUpload dengan multer
import multer from "multer";
 
const upload = multer({ dest: "uploads/" });
 
app.post("/api/upload", upload.single("gambar"), (req, res) => {
  console.log(req.file.originalname);
  res.status(201).json({
    nama: req.file.originalname,
    ukuran: req.file.size,
    path: req.file.path,
  });
});

upload.single("gambar") menangkap satu file dari field bernama gambar. Setelah middleware berjalan, req.file berisi metadata file: originalname, size, dan path tempat file disimpan di disk. Untuk banyak file, gunakan upload.array("gambar", 5).

Membatasi Ukuran dan Tipe File

Validasi di Tengah Proses

File yang tidak dibatasi adalah risiko keamanan dan penyalahgunaan resource. Multer memungkinkan validasi nama dan tipe, sekaligus batas ukuran di tingkat Express:

JSMembatasi tipe dan ukuran
const upload = multer({
  dest: "uploads/",
  limits: { fileSize: 5 * 1024 * 1024 },
  fileFilter: (req, file, cb) => {
    if (file.mimetype === "image/png" || file.mimetype === "image/jpeg") {
      cb(null, true);
    } else {
      cb(new Error("Tipe file tidak diizinkan"));
    }
  },
});

limits: { fileSize: 5 * 1024 * 1024 } menolak file di atas 5 megabyte, dan fileFilter hanya menerima PNG dan JPEG. Ingat: mimetype bisa dipalsukan oleh klien — di production, validasi tambahan dengan membaca magic bytes file adalah praktik yang lebih aman (kita bahas di episode 20).

Menangani Error Upload

Saat batas terlampaui atau tipe ditolak, error dari multer dikirim ke error handler:

JSError handler untuk upload
app.use((err, req, res, next) => {
  if (err instanceof multer.MulterError) {
    return res.status(400).json({ error: "Upload gagal: " + err.message });
  }
  next(err);
});

err instanceof multer.MulterError mendeteksi error khusus multer seperti LIMIT_FILE_SIZE. Mengubahnya menjadi respons 400 yang jelas jauh lebih baik daripada membiarkan error mentah bocor ke klien.

Streaming File dari Disk

Mengirim File Besar Tanpa Memuat ke Memori

Ketika mengirim file kembali ke klien, jangan baca seluruhnya ke memori. Gunakan stream atau res.sendFile yang mengalirkan file langsung dari disk:

JSKirim file dengan sendFile
import { createReadStream } from "node:fs";
 
app.get("/api/download/:nama", (req, res) => {
  res.download("uploads/" + req.params.nama);
});

res.download(path) mengirim file dengan header Content-Disposition yang memicu unduhan di browser, sementara res.sendFile menampilkannya inline. Keduanya menggunakan streaming di balik layar — file besar tidak pernah dimuat penuh ke memori. Sanitasi req.params.nama penting agar pengguna tidak bisa menembus jalur file lain, topik yang akan dibahas di episode 20.

Streaming untuk Media

JSStreaming video
app.get("/api/video/:nama", (req, res) => {
  const stream = createReadStream("uploads/" + req.params.nama);
  stream.pipe(res);
});

createReadStream(...) membaca file dalam potongan kecil dan stream.pipe(res) mengalirkannya ke respons. Pendekatan ini menjaga memori server tetap rendah meski melayani video berukuran besar secara bersamaan.

Range Request untuk Media

Memutar Video dari Tengah

Browser memutar video dengan mengirim range request — permintaan hanya sebagian file (misalnya byte 1000 sampai 5000). Tanpa dukungan range, video tidak bisa di-skip. Server yang benar harus memahami header Range dan membalas dengan status 206:

JSMenangani Range request
import { stat } from "node:fs/promises";
 
app.get("/api/video/:nama", async (req, res) => {
  const berkas = "uploads/" + req.params.nama;
  const info = await stat(berkas);
 
  res.status(200);
  res.setHeader("Content-Length", info.size);
  res.setHeader("Accept-Ranges", "bytes");
  res.setHeader("Content-Type", "video/mp4");
  createReadStream(berkas).pipe(res);
});

Header Accept-Ranges: bytes memberitahu browser bahwa server mendukung sebagian file. Dukungan penuh Range — mem-parsing header, membalas 206 Partial Content, dan memetakan posisi stream — bisa jadi rumit; dalam praktik, pertimbangkan middleware seperti express-serve-static-core atau CDN yang sudah menangani ini secara matang.

Penutup

Inti yang harus dibawa pulang:

  • Multipart form diproses dengan multer di middleware Express.
  • limits.fileSize dan fileFilter membatasi ukuran dan tipe file.
  • Batasi upload agar server tidak kehabisan memori.
  • res.download dan res.sendFile mengalirkan file dari disk.
  • Stream media dengan createReadStream dan pipe.
  • Header Accept-Ranges dan 206 mendukung pemutaran video.

Di episode 18 selanjutnya kita akan membahas testing API dan integrasi dengan tools modern — test runner bawaan node:test, menguji endpoint HTTP dengan supertest, mocking untuk isolasi, serta mengukur coverage. Kalian akan mengunci API kalian agar perubahan tidak merusak fitur.

Belajar Node.js - Pengelolaan File Upload dan Streaming Media | Belajar Node.js