Files
The generic file storage concept in NestJS aims to simplify file management by providing a flexible and reusable solution for associating files with various entities. It offers custom decorators and services to handle file uploads, retrieval, and storage, reducing the need for repetitive code. This approach enhances maintainability and scalability while enabling developers to efficiently manage file associations. By implementing this concept, you can easily upload, retrieve, and store files for different entities in your application, thereby improving its overall functionality and user experience.
Cheat Sheet
Options
FileField
multi
: A boolean option to indicate whether the field should hold multiple files (true) or a single file (false). Default isfalse
.
Methods
FilesController
uploadFile(file, attachmentType, attachmentId, fieldName)
: Uploads a file and associates it with a specified entity and field.
FilesService
createOrUpdate(file, attachmentType, attachmentId, fieldName)
: Handles the creation or updating of file records in the database based on themulti
option of theFileField
decorator.
FileFieldsInterceptor
Automatically resolves file fields marked with the
FileField
decorator and adds them to the response object when fetching an entity with associated files.
Usage
Add the
FileField
decorator to the desired properties in your entity and set themulti
option as needed.Use the
FileFieldsInterceptor
in the controller responsible for fetching the entity with the associated files.Upload files using the
FilesController
by sending aPOST
request with the file, attachment type, attachment ID, and field name as parameters.Fetch the entity with associated files using the
GET
request, and the response will include the respective files in the response object.
By leveraging these options and methods, you can efficiently manage file associations with various entities and handle file uploads and retrieval for your application.
How to Use Generic File Storage with NestJS
This how-to guide will walk you through using the generic file storage concept with NestJS. The components FileEntity
, FileField
, FilesController
, and FilesService
are assumed to be already implemented and available for use as if they were part of a library.
Prerequisites
Basic understanding of NestJS
Installed
@nestjs/platform-express
packageFileEntity
,FileField
,FilesController
, andFilesService
implemented and imported
Steps
Step 1: Import the necessary modules
In your module file, import the necessary modules and add them to the imports
, controllers
, and providers
arrays as appropriate:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { MulterModule } from '@nestjs/platform-express';
import { FilesController } from './files.controller';
import { FilesService } from './files.service';
import { FileEntity } from './file.entity';
@Module({
imports: [
TypeOrmModule.forFeature([FileEntity]),
MulterModule.register({
// multer configuration
}),
],
controllers: [FilesController],
providers: [FilesService],
})
export class YourModule {}
Step 2: Add FileField
decorator to the entity
In the entity that you want to associate files with, import the FileField
decorator and use it on the property that should hold the file(s). You can also pass an optional multi
parameter to the decorator to indicate if the field should hold multiple files.
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
import { FileEntity } from './file.entity';
import { FileField } from './FileField';
@Entity()
export class YourEntity {
@PrimaryGeneratedColumn()
id: number;
// other properties...
@FileField({ multi: true }) // For multiple files
files?: FileEntity[];
@FileField() // For a single file
profile_picture?: FileEntity;
}
Step 3: Use the FileFieldsInterceptor
In the controller responsible for fetching the entity with the associated files, import and use the FileFieldsInterceptor
:
import {
Controller,
Get,
Param,
UseInterceptors,
} from '@nestjs/common';
import { YourEntity } from './your.entity';
import { YourService } from './your.service';
import { FileFieldsInterceptor } from './FileFieldsInterceptor';
@Controller('yourentity')
export class YourController {
constructor(private readonly yourService: YourService) {}
@Get(':id')
@UseInterceptors(FileFieldsInterceptor)
findOne(@Param('id') id: number): Promise<YourEntity> {
return this.yourService.findOne(id);
}
// other methods...
}
Step 4: Upload files using the FilesController
To upload a file, send a POST
request to the FilesController
with the file, the attachment type, the attachment ID, and the field name as parameters.
POST /files/:attachmentType/:attachmentId/:fieldName
Replace :attachmentType
with the name of the entity (e.g., User
), :attachmentId
with the ID of the entity you want to associate the file with, and :fieldName
with the name of the property in the entity that holds the file(s).
Step 5: Retrieve files using the FileFieldsInterceptor
When you fetch an entity with the associated files, the FileFieldsInterceptor
will automatically resolve the file fields marked with the FileField
decorator and include them in the response. The files will be added to the respective properties in the entity.
For example, if you send a GET
request to fetch a user:
GET /users/:id
The response will include the user's details along with the associated files:
{
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com",
"profile_picture": {
"id": 1,
"path": "path/to/profile-picture.jpg",
"attachment_id": 1,
"attachment_type": "User",
"sort_order": 0
},
"header_pictures": [
{
"id": 2,
"path": "path/to/header-picture1.jpg",
"attachment_id": 1,
"attachment_type": "User",
"sort_order": 0
},
{
"id": 3,
"path": "path/to/header-picture2.jpg",
"attachment_id": 1,
"attachment_type": "User",
"sort_order": 1
}
]
}
To retrieve a single file or multiple files, you can access the respective properties in the entity, which will be automatically populated with the associated files.
Conclusion
By following the steps in this guide, you can implement and use generic file storage with NestJS. The FileEntity
, FileField
, FilesController
, and FilesService
components help manage file associations with various entities, allowing you to easily upload and retrieve files for your application.