~/blog/file-upload-nodejs-menggunakan-expressjs-multer
Published on

File Upload Node.js Menggunakan Express.js dan Multer

book4 minutes read

Upload file node.js

source

Masih berhubungan dengan tulisan saya yang kemarin CRUD REST API Node.js Menggunakan Express.js dan MongoDB di tulisan kali ini saya ingin membuat tutorial bagaimana cara menangani file upload gambar menggunakan Node.js dengan Web Framework Express.js dan Multer.

Apa itu multer? Multer adalah middleware untuk menangani multipart/form-data, yang biasa digunakan untuk kebutuhan mengunggah berkas.

Lha terus apa itu middleware? yaitu penengah antara router dengan handler / controller. singkatnya saat kita request ke route atau endpoint tertentu, middleware akan melakukan suatu proses terlebih dahulu sebelum masuk ke proses handler. yang biasanya digunakan untuk proses autentikasi, logging, validasi input dan masih banyak lagi.

Persiapan

Sebelumnya, daftar tool yang saya gunakan saat membuat tutorial ini yaitu:

node.js v15.0.1
npm v7.0.3
yarn v1.22.5

Okee... langsung saja kita buat direktori baru dan inisiasi package.json untuk project nya

mkdir nodejs-file-upload
cd nodejs-file-upload
yarn init -y

Kemudian install paket yang dibutuhkan

yarn add express multer cors

Buat Main File

buat file baru index.js pada root direktori project

// ./index.js

const express = require('express');
const cors = require('cors');

const port = process.env.PORT || 1337;
const routes = require('./routes');

const app = express();

app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(routes);

app.listen(port, () => {
  console.log('The magic happen on port :' + port);
});

Buat Route

buat direktori routes pada root direktori project dan buat file baru index.js didalamnya

// routes/index.js

const express = require('express');
const router = express.Router();
const multer = require('multer');
const storage = multer.diskStorage({
  // set direktori dimana gambar yg di upload akan disimpan
  destination: 'public/',
  // set nama file ketika gambar disimpan
  filename: function (req, file, cb) {
    cb(null, file.originalname);
  }
});
const upload = multer({ storage: storage });
// import handler uploader nya
const handlerUploader = require('../handlers/uploader');

// Routing yang mengarah ke http://localhost:1337/
router.get('/', async (req, res) => {
  return res.json({ message: 'Hello World!' });
});
// Routing yang mengarah ke http://localhost:1337/uploader
router.post('/uploader', upload.single('image'), handlerUploader.single);

module.exports = router;

Buat Helper

buat direktori helpers pada root direktori project dan buat file baru uploader.js didalamnya

// helpers/uploader.js

const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
// fungsi untuk megenerate random string
exports.randomFilename = (length) => {
  return crypto
    .randomBytes(length)
    .toString("hex");
}

// fungsi untuk validasi ekstensi file yang di upload
exports.getValidExtension = (filename) => {
  // list ekstensi file
  const formatAllowed = ["jpg", "jpeg", "png"];

  // ambil ekstensi file yang di upload
  const ext = filename
    .substr(filename.lastIndexOf(".") + 1)
    .toLowerCase();

  // jika ekstensi file cocok dengan salah satu list
  if (formatAllowed.indexOf(ext) > -1) {
    // kembalikan string ekstensi file nya
    return ext;
  }
  else {
    return false;
  }
}

// fungsi untuk memindahkan file hasil upload
exports.saveImage = (pathFrom, pathTo) => {
  try {
    // cek apakah direktori yang dituju ada?
    if ( ! fs.existsSync(pathTo)) {
      // jika tidak ada buat dulu foldernya
      const destination = path.dirname(pathTo);
      fs.mkdirSync(destination, { recursive: true });
    }

    // rename file hasil upload dengan nama baru dan simpan di direktori yang dituju
    fs.renameSync(pathFrom, pathTo);
  }
  catch (error) {
    throw (message = error);
  }
};

Buat handler

buat direktori handlers pada root direktori project dan buat file baru uploader.js didalamnya

// handlers/uploader.js

const fs = require('fs');
// import fungsi yang diperlukan dari helper uploader
const {
  getValidExtension,
  randomFilename,
  saveImage
} = require('../helpers/uploader');

exports.single = async (req, res) => {
  try {
    // jika tidak ada file yang diupload beri pesan error
    if ( ! req.file) {
      return res.status(422).json({ message: `File tidak ditemukan.` });
    }

    // cek ekstensi file
    const extension = await getValidExtension(req.file.originalname);
    // jika ekstensi tidak sesuai
    if ( ! extension) {
      // hapus hasil upload
      fs.unlinkSync(req.file.path);
      // kembalikan respon error
      return res.status(422).json({ message: `Format file tidak valid.` });
    }

    // buat nama file baru secara random
    const filename = await randomFilename(16);
    // ambil direktori file yang disimpan oleh multer
    const pathFrom = req.file.path;
    // buat direktori penyimpanan file
    const pathTo = `public/images/${filename}.${extension}`;
    // simpan gambar
    saveImage(pathFrom, pathTo);

    const response = {
      message: 'Upload berhasil.',
      image_path: pathTo
    }

    return res.json(response);
  }
  catch (error) {
      console.log(error);
      return res.status(500).json(error);
  }
}

Jalankan Server

Terakhir kita coba jalankan servernya bisa menggunakan node, pm2 atau nodemon

$ node index.js
The magic happen on port :1337

Jika sudah muncul pesan tersebut, berarti sudah berhasil jalan servernya.

Testing

sudah saya buatkan collection untuk postman supaya bisa memudahkan testing kalian, collection nya bisa diunduh disini.

Untuk repo project ini bisa dicek di github saya.

dahh sementara gitu aja, see yaa~