Подключитесь к базе данных MySQL с помощью TypeORM, создайте объект и загрузите изображения в приложение Nestjs.

Введение

Многие разработчики презирают загрузку файлов. Это может быть связано с отсутствием знаний о наилучшем подходе или с трудностями при определении того, как настроить приложение Nest.js для обработки загрузки файлов. Многие люди могут захотеть сохранить свои файлы непосредственно в базе данных MySQL или сохранить имена изображений и сохранить изображение на диске: все зависит от их предпочтений и целей, которых они хотят достичь. В этом руководстве вы узнаете, как создать функцию загрузки файлов с помощью Nestjs и MySQL.

Предпосылки

Прежде чем приступить к выполнению этого руководства, убедитесь, что ваша система соответствует следующим требованиям:

Настройка NestJS

Как только вышеупомянутые требования будут выполнены, перейдите к установке интерфейса командной строки Nestjs и создайте новый проект, выполнив следующие команды:

$ npm i -g @nestjs/cli
$ nest new file-upload

Эти команды установят интерфейс командной строки Nestjs и создадут новый проект Nestjs со структурой папок, указанной ниже.

📦file-upload
┣ 📂src
┃ ┣ 📜app.controller.spec.ts
┃ ┣ 📜app.controller.ts
┃ ┣ 📜app.module.ts
┃ ┣ 📜app.service.ts
┃ ┣ 📜image.entity.ts
┃ ┗ 📜main.ts
┣ 📂test
┃ ┣ 📜app.e2e-spec.ts
┃ ┗ 📜jest-e2e.json
┣ 📜.eslintrc.js
┣ 📜.gitignore
┣ 📜.prettierrc
┣ 📜README.md
┣ 📜nest-cli.json
┣ 📜package-lock.json
┣ 📜package.json
┣ 📜tsconfig.build.json
┗ 📜tsconfig.json

После создания проекта Nestjs перейдите к следующему шагу — установите необходимые зависимости для вашего приложения, выполнив следующую команду:

npm install --save @nestjs/typeorm typeorm mysql2

В приведенной выше команде вы установили модули TypeORM и mysql2: они позволят вам подключить ваше приложение к базе данных MySQL и выполнять над ней операции.

Настройте базу данных MySQL

Установив вышеуказанные зависимости, приступайте к настройке и подключению к базе данных MySQL. Для начала добавьте код в файл app.module.ts с приведенным ниже фрагментом кода.

...
import { TypeOrmModule } from '@nestjs/typeorm';
import { Image } from './image.entity';

@Module({
  imports: [TypeOrmModule.forRoot({
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: '1234',
    database: 'blog',
    entities: [Image],
    synchronize: true,
  }),
  TypeOrmModule.forFeature([Image])
  ],
  ...
})
...

В приведенном выше фрагменте кода мы импортировали TypeOrmModule из модуля typeorm, который мы установили ранее. Мы использовали метод forRoot для подключения приложения к базе данных MySQL и передачи учетных данных базы данных. Еще одна вещь, на которую следует обратить внимание, это свойства entities, которые позволили нам указать объекты в нашем модуле и которые дадут нам доступ к объекту Image, который вы вскоре создадите: у нас также есть свойство synchronize, установленное на true для автоматической миграции. базу данных.

Создать объект изображения

Далее давайте создадим объект Image, о котором мы упоминали ранее. Для начала создайте файл image.entity.ts в каталоге src и добавьте приведенный ниже фрагмент кода.

import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';

@Entity()
export class Image {
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    name: string;

    @CreateDateColumn()
    dateCreated: Date;

    @UpdateDateColumn()
    dateUpdated: Date;
}

В приведенном выше фрагменте кода мы импортировали декораторы, необходимые для создания объекта. С помощью этих декораторов мы определили свойства сущности. У нас есть поле id для генерации случайных идентификаторов для каждой записи в базе данных с помощью декоратора @PrimaryGeneratedColumn(), поле name для хранения имен изображений, которые будут загружены с помощью декоратора @Column, поля dateCreated и dateUpdate для сохранения даты записи. был создан и обновлен с использованием @CreateDateColumn() и @UpdateDateColumn().

Создание службы загрузки

Создав объект Image, давайте создадим службу для выполнения операций CRUD для обработки загрузки файлов. В файл app.service.ts добавьте приведенный ниже фрагмент кода.

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Image } from './image.entity';

@Injectable()
export class AppService {
  constructor(
    @InjectRepository(Image)
    private readonly imageRepository: Repository<Image>,
  ) {}

  async getImages(): Promise<Image[]> {
    return this.imageRepository.find();
  }

  async createImage(image: Image): Promise<Image> {
    return this.imageRepository.save(image);
  }

  async getImage(id: number): Promise<Image> {
    return this.imageRepository.findOneBy({ id });
  }

  async deleteImage(id: number): Promise<void> {
    await this.imageRepository.delete(id);
  }
}

В приведенном выше фрагменте кода мы импортировали декоратор injectRepository для внедрения imageRepository в AppService и Repository, который предоставляет вам методы, необходимые для выполнения некоторых операций в вашей базе данных. Итак, для службы изображений createImage мы сохраняем имя загруженного изображения, которое будет передано через контроллер.

Создание контроллера загрузки

Теперь давайте создадим контроллеры для использования сервисов. В файл app.controller.ts добавьте приведенный ниже фрагмент кода.

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Image } from './image.entity';

@Injectable()
export class AppService {
  constructor(
    @InjectRepository(Image)
    private readonly imageRepository: Repository<Image>,
  ) {}

  async getImages(): Promise<Image[]> {
    return this.imageRepository.find();
  }

  async createImage(image: Image): Promise<Image> {
    return this.imageRepository.save(image);
  }

  async getImage(id: number): Promise<Image> {
    return this.imageRepository.findOneBy({ id });
  }

  async deleteImage(id: number): Promise<void> {
    await this.imageRepository.delete(id);
  }
}

В приведенном выше фрагменте кода мы импортировали пару декораторов, таких как FileInterceptor, UploadedFile и UseInterceptors. Перехватчик FileInterceptor() обработчика маршрута извлекает файл из запроса с помощью декоратора @UploadedFile(). Декоратор FileInterceptor() экспортируется из пакета @nestjs/platform-express. Декоратор @UploadedFile() экспортируется из @nestjs/common. Декоратор FileInterceptor() принимает два аргумента: fieldName, представляющий собой строку, предоставляющую имя поля из HTML-формы, содержащей файл, и options, являющийся необязательным объектом типа MulterOptions. Это тот же объект, который используется конструктором multer.

Что касается функции createImage, мы использовали вышеупомянутые декораторы для обработки загрузки файла, используя FileInterceptor(), передавая имя поля для изображения, и мы изменили функцию FileInterceptor() для загрузки изображения на диск, указав свойство storage с помощью функции diskStorage, доступной в multer. . Затем мы указали расположение изображений и сгенерировали случайные имена для изображений. Кроме того, мы добавили свойство filter для ограничения загрузки определенных форматов изображений. Теперь мы получаем файл, извлеченный с помощью декоратора @UploadedFile(), получаем имя и сохраняем его в базе данных. Таким образом, мы можем использовать имя каждого изображения, чтобы получить изображение из места хранения.

Чтобы приведенный выше код работал, вам необходимо установить multer, выполнив следующую команду в своем терминале:

npm i -D @types/multer

Затем нужно прописать модуль мультера в массиве импортов в файле app.module.ts:

...
import { MulterModule } from '@nestjs/platform-express';


@Module({
  ...
  MulterModule.register({
    dest: './files',
  }),],
  ...

Приведенная выше конфигурация указывает multer обрабатывать загрузку файла и место для загрузки файла. И последнее, но не менее важное: мы должны создать папку files в каталоге src для фактического хранения файлов.

Обслуживание файлов

Чтобы на самом деле отображать изображения, загруженные в ваше приложение, пользователю необходимо установить модуль serve-static, выполнив приведенную ниже команду.

npm install --save @nestjs/serve-static

Затем зарегистрируйте ServeStaticModule в массиве импорта в файле app.module.ts с помощью приведенного ниже фрагмента кода.

...
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  ...
  ServeStaticModule.forRoot({
    rootPath: join(__dirname, '..', 'files')
  }),],
  ...

В приведенном выше фрагменте кода вы указали место, где находятся файлы и откуда они могут быть отправлены.

Тестирование API

Теперь откройте Postman и протестируйте приложение, отправив запрос POST на конечную точку localhost:4000/images и передайте полезную нагрузку в теле запроса в виде данных формы.

Если вы сейчас посмотрите на папку с файлами, вы должны увидеть файл, который вы загрузили. Не стесняйтесь идти вперед: тестируйте и экспериментируйте с другими маршрутами.

Заключение

Из этого руководства вы узнали, как обрабатывать загрузку файлов с помощью NestJS и MySQL. Вы узнали, как подключиться к базе данных MySQL с помощью TypeORM, а также создали объект и загрузили изображения в приложение Nestjs.

Вы успешно создали функцию загрузки файлов с помощью NestJS и MySQL: однако для будущего вашей базы данных и приложения имейте в виду, что постоянное наблюдение за вашими приложениями и базами данных включает в себя гораздо больше, чем создание для них функций: SQL клиентов, таких как Arctype, позволит вам писать SQL-запросы и оптимизировать их, а также визуализировать данные, существующие в настоящее время в вашей базе данных, а контент, существующий в блоге Arctype, позволит вам узнать, как оптимизировать все ваши экземпляры MySQL для обеспечения безопасности. , доступность и производительность», а также даст вам много информации о мире баз данных в целом.

Для дальнейшего чтения вы также можете узнать больше о загрузке файлов в Nestjs. В качестве дополнительной задачи попробуйте расширить приложение, защитив маршруты удаления и обновления. Что вы будете строить дальше?