Skip to content

Commit

Permalink
Merge pull request #1700 from jmcdo29/docs/send-file
Browse files Browse the repository at this point in the history
docs(streams): adds docs for streaming files with `StreamableFiles`
  • Loading branch information
kamilmysliwiec authored Feb 26, 2021
2 parents 943c1da + e26a215 commit 52f8c45
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
46 changes: 46 additions & 0 deletions content/techniques/streaming-files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
### Streaming Files

There won't always be a time where you're sending back JSON or string responses. There may be times where you'd like to send back a file from the server to the client. To do this with Nest, normally you'd do te following:

```ts
@Controller('file')
export class FileController {
@Get()
getFile(@Res() res: Response) {
const file = createReadStream(join(process.cwd(), 'package.json'));
file.pipe(res);
}
}
```

to manage sending the file back. This is still doable in Nest, by injecting `@Res()` in the controller, but in doing so you end up losing access to your post-controller interceptor logic. To handle this, you can return a `StreamableFile` instance and under the hood Nest will take care of piping the response.

#### Streamable File

A `StreamableFile` is as class that holds onto the stream that is to be returned. To create a new `StreamableFile`, you can pass either a `Buffer` or a `Stream` to the `StreamableFile` constructor.

> info **hint** The `StreamableFile` class can be imported from `@nestjs/common`.
#### Cross Platform Support

Fastify, by default, can support sending files without needing to `stream.pipe(res)`, so you don't need to use the `StreamableFile` class. However, Nest supports the use of `StreamableFile` in both platform types, so if you end up switching between Express and Fastify there's no need to worry about compatibility between the two engines.

#### Example

```ts
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);
}
}
```

This is of course a simple example of returning the `package.json` as a file instead of a JSON, but the idea extends out naturally to images, documents, and any other file type.

1 change: 1 addition & 0 deletions src/app/homepage/menu/menu.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export class MenuComponent implements OnInit {
{ title: 'Events', path: '/techniques/events' },
{ title: 'Compression', path: '/techniques/compression' },
{ title: 'File upload', path: '/techniques/file-upload' },
{ title: 'Streaming Files', path: '/techniques/streaming-files' },
{ title: 'HTTP module', path: '/techniques/http-module' },
{ title: 'Session', path: '/techniques/session' },
{ title: 'Model-View-Controller', path: '/techniques/mvc' },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { BasePageComponent } from '../../page/page.component';

@Component({
selector: 'app-streaming-files',
templateUrl: './streaming-files.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class StreamingFilesComponent extends BasePageComponent {}
7 changes: 7 additions & 0 deletions src/app/homepage/pages/techniques/techniques.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { SerializationComponent } from './serialization/serialization.component'
import { ServerSentEventsComponent } from './server-sent-events/server-sent-events.component';
import { SessionComponent } from './sessions/sessions.component';
import { SqlComponent } from './sql/sql.component';
import { StreamingFilesComponent } from './streaming-files/streaming-files.component';
import { TaskSchedulingComponent } from './task-scheduling/task-scheduling.component';
import { ValidationComponent } from './validation/validation.component';

Expand Down Expand Up @@ -65,6 +66,11 @@ const routes: Routes = [
component: FileUploadComponent,
data: { title: 'File upload' },
},
{
path: 'streaming-files',
component: StreamingFilesComponent,
data: { title: 'Streaming Files' },
},
{
path: 'logger',
component: LoggerComponent,
Expand Down Expand Up @@ -151,6 +157,7 @@ const routes: Routes = [
ServerSentEventsComponent,
SessionComponent,
CookiesComponent,
StreamingFilesComponent,
],
})
export class TechniquesModule {}

0 comments on commit 52f8c45

Please sign in to comment.