Skip to main content
Skip table of contents

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 is false.

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 the multi option of the FileField 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

  1. Add the FileField decorator to the desired properties in your entity and set the multi option as needed.

  2. Use the FileFieldsInterceptor in the controller responsible for fetching the entity with the associated files.

  3. Upload files using the FilesController by sending a POST request with the file, attachment type, attachment ID, and field name as parameters.

  4. 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 package

  • FileEntity, FileField, FilesController, and FilesService 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:

TYPESCRIPT
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.

TYPESCRIPT
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:

TYPESCRIPT
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.

CODE
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:

CODE
GET /users/:id

The response will include the user's details along with the associated files:

JSON
{
  "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.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.