Streaming de fichiers
Il peut arriver que vous souhaitiez renvoyer un fichier depuis votre API REST au client. Pour ce faire avec Nest, vous feriez normalement ce qui suit :
@Controller('file')export class FileController { @Get() getFile(@Res() res: Response) { const file = createReadStream(join(process.cwd(), 'package.json')); file.pipe(res); }}
Mais ce faisant, vous finissez par perdre accès à votre logique d’intercepteur de post-contrôleur. Pour y remédier, vous pouvez retourner une instance de StreamableFile
et, en arrière-plan, le framework s’occupera de pipeliner la réponse.
Classe de fichier streamable
Une classe StreamableFile
est une classe qui conserve le flux qui doit être retourné. Pour créer un nouveau StreamableFile
, vous pouvez passer soit un Buffer
soit un Stream
au constructeur de StreamableFile
.
Support multiplateforme
Fastify, par défaut, peut prendre en charge l’envoi de fichiers sans avoir besoin d’appeler stream.pipe(res)
, donc vous n’avez pas besoin d’utiliser la classe StreamableFile
. Cependant, Nest prend en charge l’utilisation de StreamableFile
dans les deux types de plateformes, donc si vous finissez par passer de Express à Fastify, il n’est pas nécessaire de s’inquiéter de la compatibilité entre les deux moteurs.
Exemple
Vous pouvez trouver un exemple simple de retour de package.json
en tant que fichier au lieu d’un JSON ci-dessous, mais l’idée s’étend naturellement aux images, documents et tout autre type de fichier.
import { Controller, Get, StreamableFile } from '@nestjs/common';import { createReadStream } from 'fs';import { join } from 'path';
@Controller('file')export class FileController { @Get() getFile(): StreamableFile { const file = createReadStream(join(process.cwd(), 'package.json')); return new StreamableFile(file); }}
Le type de contenu par défaut (la valeur pour l’en-tête de réponse HTTP Content-Type
) est application/octet-stream
. Si vous devez personnaliser cette valeur, vous pouvez utiliser l’option type
de StreamableFile
, ou utiliser la méthode res.set
ou le décorateur @Header()
, comme ceci :
import { Controller, Get, StreamableFile, Res } from '@nestjs/common';import { createReadStream } from 'fs';import { join } from 'path';
@Controller('file')export class FileController { @Get() getFile(@Res() res: Response): StreamableFile { const file = createReadStream(join(process.cwd(), 'package.json')); res.set({ 'Content-Type': 'application/json', 'Content-Disposition': 'attachment; filename="package.json"', }); return new StreamableFile(file); }}