Usullar2 min read

Fayllarni stream qilish

Ba'zida REST APIingizdan klientga fayl qaytarishni xohlashingiz mumkin. Nestda buni odatda quyidagicha qilasiz:

Note

Bu bob HTTP ilovangizdan fayllarni stream qilishni ko'rsatadi. Quyida keltirilgan misollar GraphQL yoki Microservice ilovalariga tegishli emas.

Ba'zida REST APIingizdan klientga fayl qaytarishni xohlashingiz mumkin. Nestda buni odatda quyidagicha qilasiz:

TypeScript
1@Controller('file')
2export class FileController {
3  @Get()
4  getFile(@Res() res: Response) {
5    const file = createReadStream(join(process.cwd(), 'package.json'));
6    file.pipe(res);
7  }
8}

Lekin buni qilganingizda, post-controller interceptor mantiqiga kirish imkonini yo'qotasiz. Buni hal qilish uchun StreamableFile instansiyasini qaytarishingiz mumkin va framework ichkarida javobni pipe qilishni o'zi bajaradi.

StreamableFile klassi

StreamableFile qaytarilishi kerak bo'lgan streamni ushlab turadigan klassdir. Yangi StreamableFile yaratish uchun StreamableFile konstruktoriga Buffer yoki Stream uzatishingiz mumkin.

Hint

StreamableFile klassi @nestjs/common dan import qilinadi.

Kross-platforma qo'llab-quvvatlash

Fastify default holatda stream.pipe(res) ni chaqirmasdan ham fayl yuborishni qo'llab-quvvatlaydi, shuning uchun StreamableFile klassidan umuman foydalanishingiz shart emas. Biroq Nest StreamableFile dan ikkala platforma turida ham foydalanishni qo'llab-quvvatlaydi, shuning uchun Express va Fastify o'rtasida almashsangiz ham bu ikki dvigatel orasidagi moslik haqida qayg'urishingiz shart emas.

Misol

Quyida package.json faylini JSON o'rniga fayl sifatida qaytarishning oddiy misoli keltirilgan, ammo g'oya tabiiy ravishda rasm, hujjat va boshqa turdagi fayllarga ham tatbiq etiladi.

TypeScript
1import { Controller, Get, StreamableFile } from '@nestjs/common';
2import { createReadStream } from 'node:fs';
3import { join } from 'node:path';
4
5@Controller('file')
6export class FileController {
7  @Get()
8  getFile(): StreamableFile {
9    const file = createReadStream(join(process.cwd(), 'package.json'));
10    return new StreamableFile(file);
11  }
12}

Default content type (Content-Type HTTP response header qiymati) application/octet-stream. Agar bu qiymatni sozlash kerak bo'lsa, StreamableFile dagi type opsiyasidan foydalanishingiz yoki res.set metodidan yoxud @Header() dekoratoridan foydalanishingiz mumkin, masalan:

TypeScript
1import { Controller, Get, StreamableFile, Res } from '@nestjs/common';
2import { createReadStream } from 'node:fs';
3import { join } from 'node:path';
4import type { Response } from 'express'; // Assuming that we are using the ExpressJS HTTP Adapter
5
6@Controller('file')
7export class FileController {
8  @Get()
9  getFile(): StreamableFile {
10    const file = createReadStream(join(process.cwd(), 'package.json'));
11    return new StreamableFile(file, {
12      type: 'application/json',
13      disposition: 'attachment; filename="package.json"',
14      // If you want to define the Content-Length value to another value instead of file's length:
15      // length: 123,
16    });
17  }
18
19  // Or even:
20  @Get()
21  getFileChangingResponseObjDirectly(@Res({ passthrough: true }) res: Response): StreamableFile {
22    const file = createReadStream(join(process.cwd(), 'package.json'));
23    res.set({
24      'Content-Type': 'application/json',
25      'Content-Disposition': 'attachment; filename="package.json"',
26    });
27    return new StreamableFile(file);
28  }
29
30  // Or even:
31  @Get()
32  @Header('Content-Type', 'application/json')
33  @Header('Content-Disposition', 'attachment; filename="package.json"')
34  getFileUsingStaticValues(): StreamableFile {
35    const file = createReadStream(join(process.cwd(), 'package.json'));
36    return new StreamableFile(file);
37  }  
38}