Skip to content

BinaryFilesModule

The Binary Files API provides a convenient way to store and manage information about uploaded files in your application's database.

Key Components

The module provides a set of reusable components, including resolvers, services, and data access layers, that can be easily integrated into a NestJS project.

With the Binary Files API, you can easily track and manage uploaded files, retrieve their URLs for display or download, and perform actions like updates and soft-deletions. This API simplifies file handling tasks and enhances your application's file management capabilities.

Entity Inheritance

NestKit provide base classes that can be inherited and customized with your needs. For entities we use TypeORM TableInheritance.

BinaryFile Entity

The BinaryFile entity includes important properties such as the file's location (which can be a Google Cloud Storage bucket or a custom URL), metadata, creation date, last update date, and soft-deletion date. The API also supports different file object locations, such as GCS and custom locations, making it flexible for various storage solutions.

Binary Files Service

The BinaryFilesService is a core component of the Binary Files API that provides an efficient and streamlined way to manage file information within your application. This service offers methods for creating, updating, retrieving, and deleting file records, as well as handling metadata associated with each file.

Binary Files Resolver

The GraphQL BinaryFilesResolver is a Key Components of the Binary Files API that enables client applications to interact with file information using GraphQL queries and mutations. This resolver provides a convenient and flexible interface for creating, updating, retrieving, and deleting file records,

How to install BinaryFilesModule to my app

To create a BinaryFilesModule in NestJS, you can follow these steps:

  1. Install the required dependencies for BinaryFilesModule:

  2. Create an binary-files folder in your project's src/modules directory.

  3. Inside the binary-files folder, create a binary-file.entity.ts file and extends BaseBinaryFile from NestKit with the following code:

    ts
    // src/modules/binary-files/binary-file.entity.ts
    
    import { ObjectType } from '@nestjs/graphql';
    import { BaseBinaryFile } from '@deeepvision/nest-kit/dist/modules/binary-files';
    import { ChildEntity } from 'typeorm';
    
    @ObjectType()
    @ChildEntity()
    export class BinaryFile extends BaseBinaryFile {}
  4. Inside the binary-files folder, create a binary-files.service.ts file and extends BaseBinaryFilesService from NestKit with the following code:

    ts
    // src/modules/binary-files/binary-files.service.ts
    
    import { BaseBinaryFilesService } from '@deeepvision/nest-kit/dist/modules/binary-files';
    
    import { BinaryFile } from './binary-file.entity';
    
    export class BinaryFilesService extends BaseBinaryFilesService<BinaryFile> {}
  5. Inside the binary-files folder, create a binary-files.resolver.ts file and extends BaseBinaryFilesResolver from NestKit with the following code:

    ts
    // src/modules/binary-files/binary-files.resolver.ts
    
    import { Resolver } from '@nestjs/graphql';
    import { BaseBinaryFilesResolver } from '@deeepvision/nest-kit/dist/modules/binary-files';
    
    import { BinaryFile } from './binary-file.entity';
    
    @Resolver(() => BinaryFile)
    export class BinaryFilesResolver extends BaseBinaryFilesResolver(BinaryFile) {}
  6. Inside the binary-files folder, create a binary-files.module.ts file with the following code:

    ts
    // src/modules/binary-files/binary-files.module.ts
    
    import { Module } from '@nestjs/common';
    import { TypeOrmModule } from '@nestjs/typeorm';
    
    import { BinaryFilesService } from './binary-files.service';
    import { BinaryFilesResolver } from './binary-files.resolver';
    import { BinaryFile } from './binary-file.entity';
    import { BINARY_FILES_SERVICE_TOKEN } from '@deeepvision/nest-kit/dist/modules/binary-files';
    
    @Module({
      imports: [
        TypeOrmModule.forFeature([BinaryFile]),
      ],
      providers: [
        BinaryFilesService,
        {
          provide: BINARY_FILES_SERVICE_TOKEN,
          useExisting: BinaryFilesService,
        },
        BinaryFilesResolver,
      ],
      exports: [
        BinaryFilesService,
        {
          provide: BINARY_FILES_SERVICE_TOKEN,
          useExisting: BinaryFilesService,
        },
        BinaryFilesResolver,
      ],
    })
    export class BinaryFilesModule {}
  7. Finally, import the BinaryFilesModule into your main AppModule or another module:

    ts
    // src/modules/app.module.ts
    
    import { Module } from '@nestjs/common';
    import { BinaryFilesModule } from './modules/binary-files/binary-files.module.ts';
    
    @Module({
      imports: [BinaryFilesModule],
    })
    export class AppModule {}

    In this code, we are importing the BinaryFilesModule and adding it to the imports array of our AppModule.

How to create new file

Call the create of BinaryFilesService and pass in an object of CreateBinaryFileOptions:

ts
const binaryFile = await this.binaryFilesService.create({
  meta: {
    size: 203452,
    mimeType: 'application/pdf',
    name: 'my-file.pdf',
  },
  url: 'https://example.com/my-file.pdf',
});

The create method returns a Promise that resolves to the newly created file object.

Create new file with GraphQL

Here's an example GraphQL mutation to create a new file.

How to attach file to my entity

Firstly, you need to create an one-to-one relation between your entity and BinaryFile entity using TypeORM:

  1. First, define your entity (Post for example) with the @OneToOne() decorator to specify the relation to the BinaryFile entity:

    ts
    @Entity()
    export class Post {
      // ...
    
      @OneToOne(() => BinaryFile, {
        eager: true, // optional, will load the related file entity along with the post
        cascade: true, // optional, will automatically persist the related file entity when the post is saved
        onDelete: 'RESTRICT', // optional, throw an error if the related file will be attempted to delete
      })
      @JoinColumn() // use post.atttachment_id column
      attachment: BinaryFile;
    }
  2. Ensure that the attachmentId field is defined as a foreign key in your Post entity:

    ts
    @Entity()
    export class Post {
      // ...
    
      @OneToOne(() => BinaryFile, {
        eager: true,
        cascade: true,
        onDelete: 'SET NULL',
      })
      @JoinColumn()
      attachment: BinaryFile;
    
      @Column()
      attachmentId: string;
    }
  3. Use the save() method on your Post entity to persist it along with the related BinaryFile entity:

    ts
    // src/modules/posts/posts.service.ts
    
    interface CreatePostOptions {
      title: string;
      attachmentId: string; // binary file has already been created on frontend and only attachment Id passed
    }
    
    class PostsService {
      ...
    
      async create(opts: CreatePostOptions, ctx: ServiceMethodContext) {
        const post = this.postRepository.create(opts);
    
        try {
          return await this.postRepository.save(opts);
          ...
      }
    }

    This will create a new Post entity and attach BinaryFile entity with a one-to-one relation.

    Now, you can fetch an file for a post using relation:

    ts
    const post = await this.getOneOrFail(postId, ctx);
    
    // post.attachment => BinaryFile

How to get binary file by ID

Use the getOne() method from your BinaryFilesService to get a file by id in other parts of your application.

ts
const file = await this.binaryFilesService.getOne('hcbin:xxxxxxxxxxx');

Use the getOneOrFail() method to retrieve a file by id or throw an error if the file is not found.

ts
const file = await this.binaryfilesService.getOneOrFail('hcbin:xxxxxxxxxxx', ctx);

Fetch file by id with GraphQL

Here's an example GraphQL query to fetch file by id.

Created by DeepVision Software.