Streaming binary and base64 files
June 25, 2023Streaming is useful when dealing with big files in web apps. Instead of loading the entire file into memory before sending it to the client, streaming allows you to send it in small chunks, improving memory efficiency and reducing response time.
The code snippet below shows streaming the binary CSV and base64-encoded PDF files with NestJS. Use the same approach for other types of files, like JSON files.
Set content type and filename headers so files are streamed and downloaded correctly. Base64 file is converted to a buffer and streamed afterward. Read files from a file system or by API calls.
import { Controller, Get, Param, Res } from '@nestjs/common';import { Response } from 'express';import { createReadStream } from 'fs';import { readFile } from 'fs/promises';import { join } from 'path';import { Readable } from 'stream';@Controller('templates')export class TemplatesController {@Get('csv')getCsvTemplate(@Res() res: Response): void {const file = createReadStream(join(process.cwd(), 'template.csv'));res.set({'Content-Type': 'text/csv','Content-Disposition': 'attachment; filename="template.csv"'});file.pipe(res);}@Get('pdf/:id')async getPdfTemplate(@Param('id') id: string,@Res() res: Response): Promise<void> {const fileBase64 = await readFile(join(process.cwd(), 'template.pdf'),'base64');// const fileBase64 = await apiCall();const fileBuffer = Buffer.from(fileBase64, 'base64');const fileStream = Readable.from(fileBuffer);res.set({'Content-Type': 'application/pdf','Content-Disposition': `attachment; filename="template_${id}.pdf"`});fileStream.pipe(res);}}
Boilerplate
Here is the link to the boilerplate I use for the development.