Node.js - Cache image to file system and pipe image for response

My goal is to create a simple file system caching system to reduce the number of calls that we need to make to the thumbnail API. The process is to check if the image exists in the file system fs.statand if not the requestimage from the API endpoint, while writing the image to the file system. I was hoping that I could pass the request to both the file system and the answer at the same time, but I do not think it is possible, so I first transmit the response to the file system and then create a stream to connect the image from the file system to the object response.

It works well, but I should assume that this is a more efficient / optimized way to accomplish this task in node.js. Any thoughts?

    function (req, res, next) {

        // Check to see if the image exists on the filesystem
        // TODO - stats will provide information on file creation date for cache checking
        fs.stat(pathToFile, function (err, stats) {
            if (err) {

                // If the image does not exist on the file system
                // Pipe the image to a file and then to the response object
                var req = request.get({
                    "uri": "http://www.example.com/image.png",
                    "headers": {
                        "Content-Type": "image/png"
                    }
                });

                // Create a write stream to the file system
                var stream = fs.createWriteStream(pathToFile);
                req.pipe(stream);
                stream.on('finish', function () {
                    fs.createReadStream(pathToFile)
                        .pipe(res);
                })
            }
            else {

                // If the image does exist on the file system, then stream the image to the response object
                fs.createReadStream(pathToFile)
                    .pipe(res);
            }
        })
    }
+4
source share
1 answer

You can use ThroughStream to do this without waiting for the entire file to be written to your file system. This works because ThroughStream internally buffers the data passed to it.

var stream = require('stream')
function (req, res, next) {

    // Check to see if the image exists on the filesystem
    // TODO - stats will provide information on file creation date for cache checking
    fs.stat(pathToFile, function (err, stats) {
        if (err) {

            // If the image does not exist on the file system
            // Pipe the image to a file and the response object
            var req = request.get({
                "uri": "http://www.example.com/image.png",
                "headers": {
                    "Content-Type": "image/png"
                }
            });

            // Create a write stream to the file system
            req.pipe(
              new stream.PassThrough().pipe(
                fs.createWriteStream(pathToFile)
              )
            )

            // pipe to the response at the same time
            req.pipe(res)
        }
        else {

            // If the image does exist on the file system, then stream the image to the response object
            fs.createReadStream(pathToFile)
                .pipe(res);
        }
    })
}
+4
source

Source: https://habr.com/ru/post/1653021/


All Articles