Добавим в модуль продуткта сервис, который будет модифицировать данные в базе
Создадим модель, которая опишет создание нового продукта
Тут так же работают декораторы:
@IsArray - проверяет, является ли значение массивом
@IsOptional - обозначает, что поле опциональное и не обязательное
@ValidateNested - говорит, что нужно проводить сдвоенную проверку (самого поля и вложенного в него объекта)
src > product > dto > create-product.dto.ts
Типизируем модель поиска продукта по категории (категория продукта и лимит выведенных продуктов за раз)
src > product > dto > find-product.dto.ts
Далее модифицируем модель продукта и указываем, что oldPrice является опциональным полем (так как старой цены может и не быть)
src > product > product.model.ts
Далее в сервисе реализуем 4 метода:
create - создание нового продукта
findById - найти продукт по id
deleteById - удаление продукта по id
patchById - обновление продукта по id
findWithReviews - найти продукт с обзорами (тут мы пишем агрегатную функцию для вывода продукта вместе с его обзорами)
Агрегация в Mongo нам нужна для тех целей, чтобы вывести сразу нужные нам продукты и обзоры, которые им принадлежат
Агрегация в Mongo представляет из себя пайплайны, которые содержат в себе наборы последовательных шагов для поиска данных
Функции агрегации:
$addFields - добавляем поля
$count - рассчитываем что-либо
$limit - ограничение поиска агрегации
$lookup - подтягивание из одной коллекции в другую
$match - позволяет ограничить выборку по сравниваемым полям (ищет совпадения)
$group - позволяет сгруппировать поля
$project - позволяет нам перегруппировать данные из одной проекции в другую (когда нам нужно будет поменять все поля)
$replaceWith - замена полей
$skip - позволяет пропустить ненужные данные
$sort - сортировка
$sortByCount - сортировка по числу
$unwind - позволяет разбить массив элементов JSON на отдельные документы
src > product > product.service.ts
Далее в контроллере вызываем функции из сервиса:
get - получение продукта по id
create - создание нового продукта
delete - удаление продукта
patch - обновление продукта
find - поиск продуктов по категориям
src > product > product.controller.ts
Константа сообщения ошибок продуктов
src > product > product.constants.ts
Создаём новый продукт
Обновление продукта
Удаление продукта по id
Обновление продукта с отсутствующим id
Добавление нового обзора
Поиск максимум трёх продуктов по тестовой категории
002 Пишем свой Pipe
Изначально, при отправке запроса на изменение данных (PATCH), мы получаем ошибку сервера, так как он пытается кастануть фейковую строку под реальный тип данных id монги
Для исправления данной ситуации напишем Pipe, который будет экстендится от PipeTransform и возвращать нам значение только тогда, когда оно будет соответствовать Types.ObjectId, который и является типом id монги. В противном случае мы должны будем выкинуть ошибку.
Конкретно id в контроллер попадает в виде @Param (есть ещё @Body, @Query и кастомный тип), поэтому запрос мы обрабатываем только в том случае, если данные пришли к нам в param
id-validation.pipe.ts
Тут будет храниться константа с ошибкой
id-validation.constants.ts
Далее нам остаётся просто передать Pipe вторым аргументом в декораторы, которые оборачивают нужный нам параметр
src > product > product.controller.ts
И так во всех файлах, где есть id, который требуется для передачу в монгу
src > review > review.controller.ts
И теперь на неверный формат записи ObjectId сервер будет возвращать правильную ошибку
003 Функции в Mongo 4.4
Далее нужно реализовать функцию, которая будет сортировать обзоры внутри продукта
Функции работают в монге 4.4+. Проверить версию можно данной командой:
Напишем функцию, которая будет замещать столбец с продуктами новыми данными, которые будут представлять этот же массив, но отсортированный с помощью функции JS
src > product > product.service.ts
005 Сервис страниц
Типизируем модель, по которой мы будем создавать нашу новую страницу с курсом
src > top-page > dto > create-top-page.dto.ts
Типизируем модель, по которой мы будем искать наши курсы (будет использоваться для поиска оглавлений курсов по категориям и выводу в менюшке поиска слева)
src > top-page > dto > find-top-page.dto.ts
Далее создаём сервис, который будет реализовывать логику взаимодействия с данными из базы данных
src > top-page > top-page.service.ts
Тут описываем логику получения данных с клиента и вызываем методы из сервиса
src > top-page > top-page.controller.ts
Константа с ошибкой при не найденной странице
src > top-page > top-page.constants.ts
Тут мы создаём новый курс
Тут мы получаем курс по id
Тут мы получаем курс по его алиасу
Тут мы создаём новый продукт с курсами
При поиске по категории, мы получаем массив с объектами наших страничек (данные для списка меню слева, которые будут вести на страницы с продуктами)
При удалении мы получаем статус ОК
Обычно после теста работы АПИ уже можно будет и добавить гуард (@UseGuards(JwtAuthGuard)) на авторизацию для запросов
И теперь наши запросы на приватные роуты без авторизации недоступны
Поэтому сейчас получаем токен при логине. Далее можно добавить в хедер токен нашего залогиненого пользователя