npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@rpocaznoi/multer-azure-storage

v0.2.2

Published

Custom multer storage with Azure Storage

Downloads

279

Readme

Introduction

The original idea came from trying to have either an API or a web application to accept a file upload (one or many files) to take the file from the browser to Azure Storage directly.

Typically, the web applications will take the file from the browser, store it in a temporary file in the server, and from there reach the final storage destination.

Although this in general works very well, it obviously had many disadvantages:

  1. The application will download to a temporary location, copy the file to the final destination, and then it has to delete the temp file. Even though this normally works fine, errors can happen, and you could end up with many orphaned temp files taking space in your server hard drive.
  2. In order to execute this process, there are many sub-steps that are executed and actually make it very inefficient:
  • T1 upload the file to the server
  • T2 store in temp folder
  • T3 read the temp file
  • T4 send to the final destination
  • T5 delete the temp file
  • Total = Time the user has to wait for the file(s) to upload and to receive a response that the files were indeed uploaded.

The idea behind this is to try to reduce the most time, while also taking much less memory and CPU.

So in order to do that, we are creating a multer custom storage (following this documentation) that connects directly to Azure Storage. Thus, reducing the footprint in the server and also reducing the time that would take the file to reach its final destination.

So the above list of steps would be reduced to:

  • T1 upload the file to the server
  • T4 send to the final destination

How to install

To install this package, you can run this command (which also includes multer)

npm i @juntoz/multer-azure-storage multer

How to use it

First, go to @koa/multer and multer repos to grasp what they are, and how they are used. They are quite simple and well designed. But it is a prerequisite to understand how this solution works.

Following, a complete example but divided in sections for better explanation.

This first part shows how to create the custom storage. The getDestination delegate needs to return the Azure Storage container and the final path.

const { MulterAzureStorage } = require('@rpocaznoi/multer-azure-storage');

const azs = new MulterAzureStorage({
    getDestination: (r, f) => {
        // use this delegate to change the final path for the file
        return {
            conectionString: 'your_conection_string',
            containerName: 'your_container_name',
            blobPath: 'myfolder/' + f.originalname
        };
    }
});

Then you need to create the multer middleware.

NOTE: The examples here are using koa, however, since this library is a multer custom storage, it can be used with any other web framework where multer can run.

The first line is the important one. @koa/multer will create the middleware for multer and takes in the multer options as its parameter. You use the storage field to assign the custom storage instance.

Then, as usual, multer middleware should be injected into a route which we know will be used to upload files along with its corresponding configuration as needed.

In below case, the middleware will run for the multipart form field called 'infiles' and it will allow max 2 files. You can check multer documentation for more options.

const multer = require('@koa/multer')({ storage: azs });

const app = new Koa();
const Router = require('@koa/router');

const router = new Router();
router.post(
    '/upload',
    multer.fields([{
        name: 'infiles',
        maxCount: 2
    }]),
    async ctx => { ctx.body = 'done'; }
);
app.use(router.routes());
app.use(router.allowedMethods());

And that is all we need. multer will take care of parsing the multipart form and use busboy in the background to obtain the file streams in order to read them.

It is at this point where the custom storage will take in the file stream and send it to Azure Storage directly (using the method uploadStream). Therefore the stream is never expanded within the application code and is read and written to Azure Storage immediately.

To test

First, set your testing Azure Storage Container credentials and then run

npm test

I tried using Azurite as the test container, but couldn't make it work (perhaps it was just a matter of more time to research).

To improve

As of 2020 July, this library is still evolving. Some of the things that we need to work on:

  1. More resilience and better callback and error handling (or at least throwing).
  2. Implement backpressure to improve and regulate the flow of bytes from the web to Azure Storage.

Also one more thing, multer does not export some interfaces that we need for more transparency and code insights. So for now, we are "re-exporting" them. For now is ok, but at some point it might break (although I don't expect this to happen neither soon, or perhaps ever).