[IPFS Tutorial #2] - Build a NodeJS app for 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
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
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
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]