Appearance
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:
Install the required dependencies for
BinaryFilesModule
:Create an
binary-files
folder in your project'ssrc/modules
directory.Inside the
binary-files
folder, create abinary-file.entity.ts
file and extendsBaseBinaryFile
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 {}
Inside the
binary-files
folder, create abinary-files.service.ts
file and extendsBaseBinaryFilesService
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> {}
Inside the
binary-files
folder, create abinary-files.resolver.ts
file and extendsBaseBinaryFilesResolver
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) {}
Inside the
binary-files
folder, create abinary-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 {}
Finally, import the
BinaryFilesModule
into your mainAppModule
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 theimports
array of ourAppModule
.
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:
First, define your entity (Post for example) with the
@OneToOne()
decorator to specify the relation to theBinaryFile
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; }
Ensure that the
attachmentId
field is defined as a foreign key in yourPost
entity:ts@Entity() export class Post { // ... @OneToOne(() => BinaryFile, { eager: true, cascade: true, onDelete: 'SET NULL', }) @JoinColumn() attachment: BinaryFile; @Column() attachmentId: string; }
Use the
save()
method on your Post entity to persist it along with the relatedBinaryFile
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 attachBinaryFile
entity with aone-to-one
relation.Now, you can fetch an file for a post using relation:
tsconst 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);