Вопросы по Nest.js

Как реализовать «мягкое» удаление в NestJS с использованием TypeORM и почему «мягкое» удаление может быть предпочтительнее «жесткого»?

Что такое «мягкое» и «жесткое» удаление?

  • Жесткое удаление (hard delete) подразумевает полное удаление записи из базы данных. После выполнения этой операции вы не можете восстановить удаленные данные.
  • Мягкое удаление (soft delete) при этом сохраняет запись в базе данных, но отмечает её как удалённую, например, с помощью флага (колонки), что позволяет скрыть её от обычных запросов. Это обеспечивает возможность восстановления данных.

Как реализовать «мягкое» удаление в NestJS с помощью TypeORM?

Для упрощенной демонстрации давайте создадим простой сервис с использованием Router и TypeORM.

  1. Создаем сущность с флагом для «мягкого» удаления:
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';

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

  @Column()
  name: string;

  @Column({ default: false })
  isDeleted: boolean;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}
  1. Создаем репозиторий и сервис для работы с пользователями:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
  ) {}

  async findAll(): Promise<User[]> {
    // Мы выбираем только тех пользователей, которые не удалены
    return this.userRepository.find({ where: { isDeleted: false } });
  }

  async softDelete(id: number): Promise<void> {
    // Отметка пользователя как удаленного
    await this.userRepository.update(id, { isDeleted: true });
  }

  async restore(id: number): Promise<void> {
    // Восстановление пользователя
    await this.userRepository.update(id, { isDeleted: false });
  }
}
  1. Создаем контроллер для обработки запросов:
import { Controller, Get, Param, Post, Delete } from '@nestjs/common';
import { UserService } from './user.service';

@Controller('users')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get()
  async findAll() {
    return this.userService.findAll();
  }

  @Post('soft-delete/:id')
  async softDelete(@Param('id') id: number) {
    await this.userService.softDelete(id);
  }

  @Post('restore/:id')
  async restore(@Param('id') id: number) {
    await this.userService.restore(id);
  }
}

Почему «мягкое» удаление может быть предпочтительнее?

  1. Восстановление данных: Легкость восстановления удаленных данных.
  2. Логирование и аудит: Сохранение истории изменений и состояние данных.
  3. Отладка: Возможность работы с тестовыми данными без потери содержимого.
  4. Безопасность: Устранение риска случайного полного удаления важных данных.

Таким образом, мягкое удаление является полезной стратегией, особенно в приложениях, где сохранение целостности данных и возможность восстановления информации имеют критическое значение.