[IPFS Tutorial #2] - Build a NodeJS app for IPFS

in #utopian-io7 years ago (edited)

ipfs

source

What Will I Learn?

  • Build and deploy a NodeJS app for IPFS file uploads.
  • Allow videos, gifs or custom file types.
  • Prevent not allowed files from being uploaded.
  • Set max file size for uploads.

Requirements

  • Laptop or Desktop Computer (Windows, Linux or Mac)
  • NodeJS and NPM
  • Several different files to upload (gif, mp4, .png etc.)

Difficulty

  • Advanced

Tutorial Contents

Project Structure

image.png

Find repository on GitHub

  • Build a Node App and Download IPFS NPM Package

Let's start by creating an application with NodeJS starter pack.
Once you have created a NodeJS application, create index.js for the homepage and upload.js for the file uploads in the routes folder. Meanwhile, create a folder named uploads under the routes folder to keep files.

Create a function in index.js for incoming GET requests to homepage.

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;
  • Start writing upload.js by installing the IPFS NPM library.
npm install ipfs-api --save

Once you have installed the IPFS library, start writing upload.js.
Import ipfs-api to connect IPFS node and import fs, multer and path libraries to upload files to IPFS node.

const ipfsAPI = require('ipfs-api');
const multer = require('multer');
const path = require('path');
const fs = require('fs');

var express = require('express');
var router = express.Router();

  • You can set max file size for IPFS uploads.
    You must write max size in byte type.
    I set it to 52428800. 52428800 byte is 50MB
const MAX_SIZE = 52428800;

  • Set the multer library to keep the files in the folder named uploads.
const storage = multer.diskStorage({
  destination(req, file, cb) {
    cb(null, path.join(__dirname, 'uploads'));
  },
  filename(req, file, cb) {
    cb(null, `${Date.now()}.${file.mimetype.split('/')[1]}`);
  },
});

const upload = multer({ storage });

  • Define the IPFS server address to which you want to upload files. I will run it on localhost. You can also start an IPFS node on localhost or create a node on the cloud.
const ipfsAPI = require('ipfs-api');

const ipfs = ipfsAPI({
  host: '127.0.0.1',
  port: 5001,
  protocol: 'http'
});

  • Create a function in upload.js for incoming GET requests to upload page.
/*  upload GET endpoint. */
router.get('/', function(req, res, next) {
  res.send('Upload endpoint!');
});

  • Create another function in upload.js for incoming POST requests to upload page.
    This function allows the user to upload a file to IPFS node and it's prevent uploading if the max file size is exceeded. Also this function checks the file type and ensures that the uploaded file is successfully uploaded to the IPFS node.
/*  upload POST endpoint */
router.post('/', upload.single('file'), (req, res) => {
  if (!req.file) {
    return res.status(422).json({
      error: 'File needs to be provided.',
    });
  }

  const mime = req.file.mimetype;
  if (mime.split('/')[0] !== 'image') {
    fs.unlink(req.file.path);

    return res.status(422).json({
      error: 'File needs to be an image.',
    });
  }

  const fileSize = req.file.size;
  if (fileSize > MAX_SIZE) {
    fs.unlink(req.file.path);

    return res.status(422).json({
      error: `Image needs to be smaller than ${MAX_SIZE} bytes.`,
    });
  }

  const data = fs.readFileSync(req.file.path);
  return ipfs.add(data, (err, files) => {
    fs.unlink(req.file.path);
    if (files) {
      return res.json({
        hash: files[0].hash,
      });
    }

    return res.status(500).json({
      error: err,
    });
  });
});
  • Statement to warn the user if the file does not exist in POST request.
  if (!req.file) {
    return res.status(422).json({
      error: 'File needs to be provided.',
    });
  }
  • Statement to check filetype in POST request.
    I only allowed image files. You can also allow video files.
  const mime = req.file.mimetype;
  if (mime.split('/')[0] !== 'image') {
    fs.unlink(req.file.path);

    return res.status(422).json({
      error: 'File needs to be an image.',
    });
  }
  • Statement to allow images and videos
  const mime = req.file.mimetype;
  if (mime.split('/')[0] !== 'image' || mime.split('/')[0] !== 'video') {
    fs.unlink(req.file.path);

    return res.status(422).json({
      error: 'File needs to be an image or video.',
    });
  }
  • Statement to check size of file. If the file size exceeds the max size you specify, upload will be prevented.
  const fileSize = req.file.size;
  if (fileSize > MAX_SIZE) {
    fs.unlink(req.file.path);

    return res.status(422).json({
      error: `Image needs to be smaller than ${MAX_SIZE} bytes.`,
    });
  }

  • This function allows the uploaded file to be sent to the IPFS node. The function will return the HASH code after the file has been successfully uploaded.
  const data = fs.readFileSync(req.file.path);
  return ipfs.add(data, (err, files) => {
    fs.unlink(req.file.path);
    if (files) {
      return res.json({
        hash: files[0].hash,
      });
    }

    return res.status(500).json({
      error: err,
    });
  });

With the HASH returned from the function, you can access your file via the IPFS gateway.

https://gateway.ipfs.io/ipfs/ {HASH}
https://gateway.ipfs.io/ipfs/QmaJVawuxkDnKxE6tFDT1V6xVjag3wDCG2BVBDjfwEwkLJ

Curriculum



Posted on Utopian.io - Rewarding Open Source Contributors

Sort:  

Hey @hsynterkr

We're already looking forward to your next contribution!

Decentralised Rewards

Share your expertise and knowledge by rating contributions made by others on Utopian.io to help us reward the best contributions together.

Utopian Witness!

Vote for Utopian Witness! We are made of developers, system administrators, entrepreneurs, artists, content creators, thinkers. We embrace every nationality, mindset and belief.

Want to chat? Join us on Discord https://discord.me/utopian-io

You just received a Tier 0 upvote! Looking for bigger rewards? Click here and learn how to get them or visit us on Discord

Thank you for the contribution It has been approved.


Need help? Write a ticket on https://support.utopian.io.
Chat with us on Discord.

[utopian-moderator]

Coin Marketplace

STEEM 0.19
TRX 0.19
JST 0.033
BTC 90237.77
ETH 3102.10
USDT 1.00
SBD 2.81