javapedia.net
javapedia.net

Reputation: 2731

Difference between response.write vs stream.pipe(response) in NodeJS

As I understand "response.write" gives more control over the chunk of data I am writing to, while pipe doesn't have any control over the chunks.

I am trying to stream files and I don't need any control on the chunk of data, so is it recommended to go with stream.pipe(response) ? is there any advantage such as performance over response.write?

 downloadStream = readBucket.openDownloadStream(trackID)
 downloadStream.on('data', chunk => {
      console.log('chunk');
      res.write(chunk);
    });

    downloadStream.on('error', error => {
      console.log('error occured', error)
      res.sendStatus(500);
    });

    downloadStream.on('end', () => {
      res.end();
    });

For my scenario, both codes do the same. I prefer pipe because of less code. Is there any performance benefits, memory/io efficiency advantages with pipe() over response.write?

downloadStream= readBucket.openDownloadStream(trackID)
      downloadStream.pipe(res);

Upvotes: 3

Views: 3164

Answers (1)

jfriend00
jfriend00

Reputation: 708126

.pipe() is just a ready made way to send a readstream to a writestream. You can certainly code it manually if you want, but .pipe() handle a number of things for you.

I'd suggest it's kind of like fs.readFile(). If what you want to do is read a whole file into memory, fs.readFile() does the work of opening the file for reading, reading all the data into a buffer, closing the target file and giving you all the data at the end. If there are any errors, it makes sure the file you were reading gets closed.

The same is true of .pipe(). It hooks up to the data, finish and error events for you and just handles all those, while streaming the data out to our write stream. Depending on the type of writestream, it also takes care of "finishing" or "closing" both the readstream and the writestream, even if there are errors.

And, .pipe() has backflow handling, something your code does not. When you call res.write() it returns a boolean. If that boolean is true, then the write buffer is full and you should not be calling res.write() again until the drain event occurs. Note, your code does not do that. So, .pipe() is more complete than what many people will typically write themselves.

The only situations I've seen where you're generally doing a pipe-like operation, but you can't use .pipe() is when you have very custom behavior during error conditions and you want to do something significantly differently than the default error handling. For just streaming the data and finishing both input and output streams, terminating both on error, it does exactly what you want so there's really no reason to code it yourself when the desired behavior is already built-in.

For my scenario, both codes do the same. I prefer pipe because of less code.

Same here.

Is there any performance benefits, memory/io efficiency advantages with pipe() over response.write?

Yes, sort of. It probably has fewer bugs than the code you write yourself (like forgetting backflow detection in your example that might only show up in some circumstances, large data, slow connection).

Upvotes: 5

Related Questions