You are currently viewing Efficient File Upload in Node.js and Express using Multer: A Step-by-Step Rest API Guide

Efficient File Upload in Node.js and Express using Multer: A Step-by-Step Rest API Guide

Our Node.js Application will provide APIs for:

  • uploading File to a static folder in the Server (restrict file size: 2MB)
  • downloading File from server with the link
  • getting list of Files’ information (file name & url)
  • deleting File from server by file name

  1. Install required packages:

First, make sure you have Node.js and npm installed on your machine. Then create a new directory for your project and run the following command to initialize a new Node.js project and install the required packages.

npm init -y
npm install express multer fs path
  1. Create the server file (app.js):

Create a file named app.js and paste the following code:

const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');

const app = express();
const PORT = process.env.PORT || 3000;

// Multer configuration
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads/');
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + '-' + file.originalname);
  },
});

const upload = multer({
  storage: storage,
  limits: { fileSize: 2 * 1024 * 1024 }, // Limit file size to 2MB
});

// API endpoint for file upload
app.post('/upload', upload.single('file'), (req, res) => {
  res.status(200).json({ message: 'File uploaded successfully' });
});

// API endpoint for file download
app.get('/download/:filename', (req, res) => {
  const fileName = req.params.filename;
  const filePath = path.join(__dirname, 'uploads', fileName);

  if (fs.existsSync(filePath)) {
    res.download(filePath);
  } else {
    res.status(404).json({ message: 'File not found' });
  }
});

// API endpoint for getting list of files' information
app.get('/files', (req, res) => {
  fs.readdir('./uploads', (err, files) => {
    if (err) {
      res.status(500).json({ message: 'Error reading files' });
    } else {
      const fileInformation = files.map((file) => ({
        name: file,
        url: `/download/${file}`,
      }));
      res.json(fileInformation);
    }
  });
});

// API endpoint for deleting file by name
app.delete('/delete/:filename', (req, res) => {
  const fileName = req.params.filename;
  const filePath = path.join(__dirname, 'uploads', fileName);

  if (fs.existsSync(filePath)) {
    fs.unlink(filePath, (err) => {
      if (err) {
        res.status(500).json({ message: 'Error deleting file' });
      } else {
        res.json({ message: 'File deleted successfully' });
      }
    });
  } else {
    res.status(404).json({ message: 'File not found' });
  }
});

app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});
  1. Create a folder for uploads:

Create a folder named uploads in the same directory as the app.js file. This is where the uploaded files will be stored.

  1. Run the server:

Run the following command in the terminal:

node app.js

Now, your server is running and listening on http://localhost:3000.

API Endpoints:

  1. To upload a file, send a POST request to http://localhost:3000/upload with a file attached to the file field.
  2. To download a file, send a GET request to http://localhost:3000/download/filename, where filename is the name of the file you want to download.
  3. To get a list of files’ information, send a GET request to http://localhost:3000/files.
  4. To delete a file, send a DELETE request to http://localhost:3000/delete/filename, where filename is the name of the file you want to delete.

Upload and store images in MySQL using Node.js, Express, Multer, and Sequelize ORM

To upload and store images in MySQL using Node.js, Express, Multer, and Sequelize ORM, follow the steps below:

  1. Set up the project and install the required packages:

First, create a new directory for your project and run the following commands in the terminal:

npm init -y
npm install express multer sequelize sequelize-cli mysql2
  1. Create the necessary project files:

Create the following files in your project directory:

  • app.js (main server file)
  • models/image.js (Image model)
  • config/config.json (Sequelize configuration)
  1. Configure Sequelize:

In the config/config.json file, set up the database connection configuration. Replace the <db_username>, <db_password>, and <db_name> placeholders with your actual MySQL credentials:

{
  "development": {
    "username": "<db_username>",
    "password": "<db_password>",
    "database": "<db_name>",
    "host": "localhost",
    "dialect": "mysql"
  }
}
  1. Set up the Sequelize Image model:

In the models/image.js file, define the Image model to store image data in the database:

const { DataTypes } = require('sequelize');
const db = require('../config/config.json')['development'];

const sequelize = new Sequelize(db.database, db.username, db.password, db);

const Image = sequelize.define('Image', {
  name: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  mimetype: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  data: {
    type: DataTypes.BLOB('long'),
    allowNull: false,
  },
});

module.exports = Image;
  1. Set up the Express server (app.js):

In the app.js file, set up the Express server, Multer middleware, and the routes to handle image upload and retrieval:

const express = require('express');
const multer = require('multer');
const { Sequelize } = require('sequelize');
const Image = require('./models/image');

const app = express();
const PORT = process.env.PORT || 3000;

// Multer configuration for file upload
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

// Set up database connection
const db = require('./config/config.json')['development'];
const sequelize = new Sequelize(db.database, db.username, db.password, db);

// Test database connection
(async () => {
  try {
    await sequelize.authenticate();
    console.log('Database connection established successfully.');
  } catch (error) {
    console.error('Unable to connect to the database:', error);
  }
})();

// Create Image table if it doesn't exist
(async () => {
  try {
    await Image.sync();
    console.log('Image table created successfully.');
  } catch (error) {
    console.error('Error creating Image table:', error);
  }
})();

// API endpoint for image upload
app.post('/upload', upload.single('image'), async (req, res) => {
  try {
    const { originalname, mimetype, buffer } = req.file;

    const image = await Image.create({
      name: originalname,
      mimetype: mimetype,
      data: buffer,
    });

    res.status(201).json({ message: 'Image uploaded successfully', image });
  } catch (error) {
    console.error('Error uploading image:', error);
    res.status(500).json({ message: 'Error uploading image' });
  }
});

// API endpoint for retrieving image by ID
app.get('/image/:id', async (req, res) => {
  try {
    const id = req.params.id;
    const image = await Image.findByPk(id);

    if (image) {
      res.setHeader('Content-Type', image.mimetype);
      res.send(image.data);
    } else {
      res.status(404).json({ message: 'Image not found' });
    }
  } catch (error) {
    console.error('Error retrieving image:', error);
    res.status(500).json({ message: 'Error retrieving image' });
  }
});

app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});
  1. Run the server:

Run the following command in the terminal:

node app.js

Now, your server is running and listening on http://localhost:3000.

API Endpoints:

  1. To upload an image, send a POST request to http://localhost:3000/upload with a file attached to the image field.
  2. To retrieve an image, send a GET request to http://localhost:3000/image/:id, where :id is the ID of the image you want to retrieve. The image will be sent in the response with the appropriate Content-Type header.

Note: Storing images directly in the database can have performance implications, especially for large-scale applications. Consider using a CDN or file storage service for better performance and scalability.

Upload/store images in GCP Bucket using Node.js, Express & Multer

To upload and store images in a Google Cloud Storage (GCS) bucket using Node.js, Express, and Multer, you’ll need to set up the Google Cloud Storage client library and use it in conjunction with Multer to handle image uploads. Below is a code example that demonstrates how to achieve this:

  1. Set up the project and install the required packages:

Create a new directory for your project and run the following commands in the terminal:

npm init -y
npm install express multer @google-cloud/storage
  1. Create the necessary project files:

Create a file named app.js and paste the following code:

const express = require('express');
const multer = require('multer');
const { Storage } = require('@google-cloud/storage');
const path = require('path');
const { v4: uuidv4 } = require('uuid');

const app = express();
const PORT = process.env.PORT || 3000;

// Multer configuration for file upload
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

// Google Cloud Storage configuration
const storageClient = new Storage();
const bucketName = '<YOUR_BUCKET_NAME>'; // Replace with your GCS bucket name

// API endpoint for image upload
app.post('/upload', upload.single('image'), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ message: 'No file uploaded' });
    }

    const { originalname, mimetype, buffer } = req.file;
    const filename = `${uuidv4()}-${path.basename(originalname)}`;
    const bucket = storageClient.bucket(bucketName);
    const file = bucket.file(filename);

    await file.save(buffer, {
      metadata: { contentType: mimetype },
      resumable: false,
    });

    const imageUrl = `https://storage.googleapis.com/${bucketName}/${filename}`;
    res.status(201).json({ message: 'Image uploaded successfully', imageUrl });
  } catch (error) {
    console.error('Error uploading image:', error);
    res.status(500).json({ message: 'Error uploading image' });
  }
});

app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});
  1. Authenticate the Google Cloud Storage client:

Ensure that you have set up the authentication for the Google Cloud Storage client library. You can use Application Default Credentials (ADC), Service Account JSON key, or provide environment variables. Make sure the method you choose provides the necessary authentication details to interact with your GCS bucket.

  1. Run the server:

Run the following command in the terminal:

node app.js

Now, your server is running and listening on http://localhost:3000.

API Endpoint:

To upload an image, send a POST request to http://localhost:3000/upload with a file attached to the image field.

The server will save the image in the specified GCS bucket and return the public URL of the uploaded image in the response.

Make sure to replace <YOUR_BUCKET_NAME> with the name of your Google Cloud Storage bucket in the bucketName variable.

Note: Before deploying this code to a production environment, make sure to handle authentication securely and consider adding error handling and validation to improve the code’s robustness.

Upload & resize multiple images in Node.js using Express, Multer, Sharp

To upload and resize multiple images in Node.js using Express, Multer, and Sharp, follow the steps below:

  1. Set up the project and install the required packages:

Create a new directory for your project and run the following commands in the terminal:

npm init -y
npm install express multer sharp
  1. Create the necessary project files:

Create a file named app.js and paste the following code:

const express = require('express');
const multer = require('multer');
const sharp = require('sharp');
const path = require('path');

const app = express();
const PORT = process.env.PORT || 3000;

// Multer configuration for file upload
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

// API endpoint for image upload and resizing
app.post('/upload', upload.array('images', 5), async (req, res) => {
  try {
    const { files } = req;

    if (!files || files.length === 0) {
      return res.status(400).json({ message: 'No files uploaded' });
    }

    const resizedImages = await Promise.all(
      files.map(async (file) => {
        const { originalname, buffer } = file;
        const filename = `${Date.now()}-${path.basename(originalname)}`;
        const resizedImage = await sharp(buffer)
          .resize(300, 300) // Resize to 300x300 pixels
          .toBuffer();

        return { filename, buffer: resizedImage };
      })
    );

    res.status(201).json({ message: 'Images uploaded and resized successfully', resizedImages });
  } catch (error) {
    console.error('Error uploading and resizing images:', error);
    res.status(500).json({ message: 'Error uploading and resizing images' });
  }
});

app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});
  1. Run the server:

Run the following command in the terminal:

node app.js

Now, your server is running and listening on http://localhost:3000.

API Endpoint:

To upload and resize images, send a POST request to http://localhost:3000/upload with the images attached to the images field. You can attach multiple images in the same request.

The server will resize each uploaded image to 300×300 pixels and return an array of resized images’ filenames and buffers in the response.

Note: The example uses in-memory storage for simplicity. In a production environment, consider using a file storage service like Google Cloud Storage or Amazon S3 to store and serve the images efficiently. Additionally, you may want to implement error handling and validation to make the code more robust.

How to upload/store images in MongoDB using Node.js, Express & Multer

To upload and store images in MongoDB using Node.js, Express, and Multer, follow the steps below:

  1. Set up the project and install the required packages:

Create a new directory for your project and run the following commands in the terminal:

npm init -y
npm install express multer mongoose
  1. Create the necessary project files:

Create a file named app.js and paste the following code:

const express = require('express');
const multer = require('multer');
const mongoose = require('mongoose');
const path = require('path');

const app = express();
const PORT = process.env.PORT || 3000;

// Connect to MongoDB (replace "mongodb://localhost/image_db" with your MongoDB connection string)
mongoose.connect('mongodb://localhost/image_db', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
db.once('open', () => {
  console.log('Connected to MongoDB successfully.');
});

// Multer configuration for file upload
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads/');
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + '-' + file.originalname);
  },
});

const upload = multer({ storage: storage });

// MongoDB Image model
const imageSchema = new mongoose.Schema({
  filename: String,
  mimetype: String,
  path: String,
});

const Image = mongoose.model('Image', imageSchema);

// API endpoint for image upload
app.post('/upload', upload.single('image'), async (req, res) => {
  try {
    const { originalname, mimetype, path } = req.file;

    const image = new Image({
      filename: originalname,
      mimetype: mimetype,
      path: path,
    });

    await image.save();

    res.status(201).json({ message: 'Image uploaded successfully', image });
  } catch (error) {
    console.error('Error uploading image:', error);
    res.status(500).json({ message: 'Error uploading image' });
  }
});

app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});
  1. Create a folder for uploads:

Create a folder named uploads in the same directory as the app.js file. This is where the uploaded images will be stored temporarily before saving to the database.

  1. Run the server:

Run the following command in the terminal:

node app.js

Now, your server is running and listening on http://localhost:3000.

API Endpoint:

To upload an image, send a POST request to http://localhost:3000/upload with an image attached to the image field.

The server will save the image’s metadata (filename, mimetype, and temporary path) to MongoDB.

Note: Storing images directly in the MongoDB database can have performance implications, especially for large-scale applications. Consider using a dedicated file storage service like Amazon S3, Google Cloud Storage, or a CDN for better performance and scalability. Additionally, you may want to add error handling and validation to make the code more robust.

Leave a Reply