DEV Community

Cover image for Day 59 of Learning MERN Stack
Ali Hamza
Ali Hamza

Posted on

Day 59 of Learning MERN Stack

Hello Dev Community! πŸ‘‹

It is officially Day 59 of my non-stop run toward mastering full-stack MERN engineering! Yesterday, I configured Multer to manage custom image uploads. Today, I expanded my backend resource engine into document generation and distribution inside Prashant Sir's backend masterclass track: Handling PDF Uploads and Streaming Data Downloads Securely!

When working on enterprise applications (like e-commerce checkouts, rental bookings, or profile management systems), your server must be capable of generating or serving PDF assets without overloading server memory buffers. Today, I unlocked that exact asset streaming pipeline!


🧠 Key Learnings From Day 59 (PDF Buffers & Network Streaming)

Serving documents efficiently requires absolute control over HTTP response headers and chunked data streaming variables:

1. Expanding Multer for Document Encodings

I expanded my file filtering logic to accept application document streams alongside regular image buffers. Configured the multi-part request pipeline to safely capture and store .pdf assets into a structured document vault on the disk.

2. Tuning HTTP Response Headers for Downloads

I learned that to deliver a file cleanly to a client browser, you must manually explicitly configure the response headers. This instructs the user's browser exactly how to process the binary stream payload:

  • Content-Type: Set explicitly to application/pdf so the client framework doesn't treat it as a generic text file.
  • Content-Disposition: Configured with either inline (to preview the PDF right inside the browser viewport layout) or attachment; filename="invoice.pdf" (to force an instant automated file download).

3. Memory-Safe Chunked Streaming via fs.createReadStream

Instead of using fs.readFile()β€”which loads the entire heavy document into server memory at once and can crash the engine under high trafficβ€”I mastered Node's native file streams. By hooking up a Read Stream and piping it straight into the response network, the data is broken down into small chunks and delivered smoothly:


javascript
const fs = require('fs');
const path = require('path');

exports.getInvoice = (req, res, next) => {
    const invoiceName = 'invoice-' + req.params.orderId + '.pdf';
    const invoicePath = path.join('data', 'invoices', invoiceName);

    // Setting explicit headers to dictate client-side download parameters
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'attachment; filename="' + invoiceName + '"');

    // Instantiating a memory-efficient chunked read stream pipeline
    const fileStream = fs.createReadStream(invoicePath);

    // Piping the binary stream straight into the response wire
    fileStream.pipe(res);
};
Enter fullscreen mode Exit fullscreen mode

Top comments (0)