Разработка веб приложений. #3 - Backend, Nest.
Первая статья — здесь.
Вторая статья — здесь.
:(
1. Надеюсь у всех все хорошо, насколько это возможно.
2. По самым разным причинам, я эту статью писал месяцев 7… Ну как писал… Часть написал еще в феврале и оставил статью пылиться. Я решил закончить давно начатое, надеюсь статья придется вам по вкусу и вы узнаете для себя хоть что-то новое. Погнали.
TypeScript
Конечно увидев Nest, у меня (наверное не только у меня) появились сомненения, ведь TS это как бы JS, но масштаб погружения все таки намного глубже, требуются совсем другого уровня знания. Так думал я перед тем как начать изучать Nest. Я даже вспомнил, что уже давно купил себе этот курс, но так и не начал его изучать (все таки на момент написания статьи, уже начал).
На самом деле, не особо и нужны все эти курсы, их можно покупать максимум для того, чтобы смотреть как кино. Но очень важно их смотреть, если вы выучили хотя бы базу. Это поможет вам критически оценивать то, что говорит в курсе автор. На примере курса по Express я могу сказать, что очень часто автор дает крайне сомнительную информацию, которая иногда может сильно навредить, заложив фундаментельно неправильные знания в голову падавана.
Так как же я изучаю TS? Да просто начинаю что-то делать! TS прекрасно подходит для написания библиотечек на Node. Например сейчас я разрабатываю компоненты на Node, Vue 3, Vite и TS. Это самый современный и крутой подход на сегодняшний день для написания библиотек на Vue. Если вдруг у коммьюнити будет интерес, соберем энную сумму донатов и я напишу подробную статейку по этой теме, выложу исходники бойлерплейта и покажу схему сборки библиотеки от начала, до продакшена на какой-нибудь NPM.
TypeScript типизация
Конечно первое что слышат люди при изучении TS — это то, что он решает ошибки типов данных, которым так страдает, в нашем случае JS. Да, это действительно так. Сейчас на основной работе мы работаем на Vue 2 без TS, так вот там частенько проблемы с типами встречаются. Деклоративность в коде это неплохо, а иногда даже хорошо. Мы говорим коду, что именно должна вернуть функция и код такой — окей не вопрос, но если ты падла такая попробуешь вернуть что-то другое, пойдешь нахер.
Это не так явно бросается в глаза, когда вы просто указываете тип переменных. Ага — это у нас строка, это массив, это объект и т.д… Конечно это помогает, но куда больший профит от типизации появляется в несколько более сложных примерах типизации. В примере ниже, я создал конфигурационную функцию для одной опенсурс библиотеки и указал что функция возвращает промис с типом MailerOptions, однако пытаюсь вернуть строку и TS мне выдает ошибку.

Конечно я могу не указывать тип возвращаемых данных, но зачем тогда использовать TS? Да и почему не привыкать к типизации? Ведь всегда можно открыть дтску и посмотреть какие данные мы должны вернуть в функции… В моем случае, функция должна вернуть эти данные.

Все предельно очевидно, видно что обязательно, а что нет. Виден и тип данных. Но даже если вы ошибетесь, TS вам об этом расскажет. Более того, я использую phpStorm и эта IDE просто не даст мне вернуть что-то, что не описано в интерфейсе библиотеки. Автокомплит с типизацией это очень мощная штука.
TypeScript панацея?
Не думаю что я могу делать какие-то глобальные выводы, ввиду моей пока что еще не очень большой работы на TS, но я считаю, если вы пишите на ноде, то TS сегодня очень и очень мастхев. Backend, библиотеки или SPA на условном Vue — я всегда буду выбирать TS вместо нативного JS.
Nest.js
Ну вот и дошли до Nest… Короче Nest под капотом использует Express… :) Конечно может использовать и Fastify, но блин… Я ушел с Express на Nest, а Nest использует Express. Но не спешите с выводами. Express он использует да, но при этом решает множество проблем, с которыми вы рано или поздно столкнетесь при масштабировании вашего приложения, если бы вы работали на Express.
При этом, Nest не является оберткой или микрофреймворком, это самый настоящий фреймворк. Если кратко, то Nest собрал в себе почти все лучшие практики по организации лучшего на данный момент бекенда на ноде. Nest использует TS (хотя может работать в режиме чистого JS, но смысла в этом нет), почти вся его концепция завязана на DI и декораторах.
Nest.js — Dependency Injection
Это не очень простая техника, в которой один объект или класс, получает другой объект или класс как зависимость и уже не может работать без него. Иными словами, функционал класса теперь требует эту зависимость. Это довольно часто вызывает проблему циклических зависимостей, когда классу пользователей нужен класс заказов, а классу заказов нужен класс пользователей. Вы можете получить в терминале ошибки, на этот случай у Nest из коробки идет решение. На этой технике строится весь backend, вы будете писать модули и внутри этих модулей делать DI, а так же вы почти наверняка будете делать DI модуля, внутрь другого модуля и т.д.
Nest.js — Декораторы
Это такая штука, с помощью которой вы можете добавить классу некий функционал. В Nest зачастую требуется писать свои декораторы. Конечно все зависит от задачи, но написание декораторов не является большой проблемой. Есть документация и гугл, со временем появляется все больше статей где показывают как работают декораторы внутри Nest.
Например в моем приложении я использую декораторы для проверок ролей и пермишенов пользователей.
Nest.js — саммари
Вообще у Nest из коробки идет все что нужно для организации бека. Интерцепторы для обработки разного типа ошибок, пайпы для трансформации и валидации данных, гарды для защиты роутов и т.д. Документация исключительно дружелюбна, а там где ее не хватает, есть гугл. Так же Nest постепенно обживается экосистемой различных модулей. Так например есть свой модуль для работы с почтой, есть модуль для локализации построенный на i18n и т.д. Я эти модули уже применил на своих проектах и подключение их в проект не намного тяжелее установки дополнений из модстора… :) Шутка, но если погрузиться в контекст работы Nest, то не такая уж и шутка. Если бы вы работали на Express, все вышеописанное и многое другое, вам пришлось бы писать самому.
Nest.js — миграция
Хорош поносословить, начну показывать во что в итоге превратился мой модуль для сотрудников. На данный момент он состоит из 8-ми частей — например модуль сотрудников, модуль авторизации, модули ролей и прав сотрудников и т.д… Я покажу лишь кусочек модуля авторизации:
ДИСКЛЕЙМЕР: Часть кода из примеров ниже я либо упростил, либо вырезал для примера.
Для начала главный файл модуля, куда я импортирую коллекции Mongo, а так же другие модули, которые я так или иначе применяю в модуле авторизации. А значит в силу вступает DI. Так же я регистрирую провайдеры, в которых будет описана бизнес логика
Как видите, провайдеров и контроллеров набралось прилично. Дело в том, что я пишу довольно обширную систему аутентификации и авторизации пользователей в свою систему управления сайтом. О ней можно написать отдельную статью, возможно, когда-нибудь это и случится.
Так вот, по поводу большого кол-ва провайдеров и контроллеров — я предпочитаю отделять мух. Писать довольно большую бизнес-логику в одном service-файле, приведет к лапшекоду, в моем случае каждый сервис отвечает за отведенную ему часть бизнес-логики по работе с аутентификацией и авторизацией сотрудников.
Контроллеры разбиты на сущности. В одних описаны епдпоинты по работе сотрудников со своим профилем, в других ендпоинты для работы с другими сотрудниками. Мы ведь не хотим чтобы каждый мог менять каждого? Нужны правила и разбитие на контроллеры помогают эти правила соблюдать. Ну и еще один контроллер содержит в себе общие ендпоинты, для всех сотрудников.
В прошлой статье я выложил код своего модуля авторизации на Express.js. Там в самом начале я писал валидацию. Nest.js предоставляет возможность вынести валидацию в DTO классы. Вот пример моей валидации для аутентификации сотрудника:
@IsNotEmpty — это те самые декораторы, о которых я уже писал ранее. Только это не самописные декораторы, а коробочные из библиотеки class-validator. В объекте message вы видите локали (что-то вроде лексиконов в MODx). В моем бекенде есть мультиязычность, за это отвечает модуль nestjs-i18n.
Опять же, смотрим на код из прошлой статьи, ту часть где я пытаюсь аутентифицировать сотрудника:
Аутентификация и авторизация теперь разбита на две части. Сначала покажу авторизацию.
Сам метод аутентификации теперь находится в сервисе по валидации сотрудника. Все как завещали отцы, описывающие разницу авторизации и аутентификации:
Обратите внимание, я вызываю методы одного сервиса аутентификационного модуля, в другом. Но в последнем коде, вызывается сервис сотрудников — staffService. Это и есть DI. Я покажу кусочек кода этого сервиса:
Вызов этой цепочки методов различных сервисов, избавит нас от необходимости постоянно писать какие-либо проверки. Так что, если возникнут проблемы с аутентификацией сотрудника, это решит либо метод getOneByEmail, либо validateStaff, последний уж точно не пропустит пользователя, если первый не справился с проверкой. Но будьте осторожней с асинхронщиной. К слову, в методе getOneByEmail вызывается модель модуля ролей пользователя. Это тоже DI.
Ну и кусочек контроллера, который создает endpoint для аутентификации:
Для начала — в Nest.js есть swagger. Автодокументация для REST API, в уже в самописном декораторе StaffAuthDecorator я описываю эту документацию для текущего ендпоинта. Затем через декоратор указываю метод, путь ендпоинта и сам метод, в теле которого передается та же DTO и вызывается сервис с бизнес-логикой.
Вот здесь я бы хотел тормознуть. По неведомым мне причинам, почти во всех видеоуроках на ютубе, бизнес-логику пишут в контроллере. Я до сих пор не понял зачем авторы курсов так делают. Может кто-то в комментах мне объяснит?
Ну собственно все. Конечно надо было бы показать как подключается база данных (mongo или postgres), как подключается модуль для работы с JWT или про unit-тесты рассказать… Но это уже такие нишевые темы, что включать их в эту статью, будет не очень правильно.
Стало ли у меня больше кода в сравнении с тем что было в прошлой статье? Да, мой модуль сотрудников сайта вырос значительно. Буквально вот на днях я дописал модуль логов (примерно как в MODx журнал событий). Выведу его в админку, протестирую и сделаю деплой.
Если честно, в холодный пот бросает, когда пытаюсь себе представить как бы выглядел набор модулей для работы с сотрудника на Express.js…
P.S.
Сборки моих проектов работают через микросервисы- бекенд, админка и фронт разделены и лежат в своих репозиториях (сабмодулях), есть отдельный репозиторий с настройками докера. Именно он разруливает через nginx маршрутиризацию. Деплой происходит через релиз новой версии проекта в Github, через Actions — полностью автоматизировано практически все.
В планах разработать большой модуль для работы с контентом сайта (статьи, товары и т.д.) благо есть хороший референс.
Будет ли следующая статья — не знаю. Но цикл статей я могу продолжать еще прилично долго, темы и материал есть. Могу погрузится в Nest.js или написать статью про Vue. Там же будет затронута тема с TS повторно, на реальном примере.
Спасибо что читаете мои статейки. Засим откланиваюсь.
Вторая статья — здесь.
:(
1. Надеюсь у всех все хорошо, насколько это возможно.
2. По самым разным причинам, я эту статью писал месяцев 7… Ну как писал… Часть написал еще в феврале и оставил статью пылиться. Я решил закончить давно начатое, надеюсь статья придется вам по вкусу и вы узнаете для себя хоть что-то новое. Погнали.
TypeScript
Конечно увидев Nest, у меня (наверное не только у меня) появились сомненения, ведь TS это как бы JS, но масштаб погружения все таки намного глубже, требуются совсем другого уровня знания. Так думал я перед тем как начать изучать Nest. Я даже вспомнил, что уже давно купил себе этот курс, но так и не начал его изучать (все таки на момент написания статьи, уже начал).
На самом деле, не особо и нужны все эти курсы, их можно покупать максимум для того, чтобы смотреть как кино. Но очень важно их смотреть, если вы выучили хотя бы базу. Это поможет вам критически оценивать то, что говорит в курсе автор. На примере курса по Express я могу сказать, что очень часто автор дает крайне сомнительную информацию, которая иногда может сильно навредить, заложив фундаментельно неправильные знания в голову падавана.
Так как же я изучаю TS? Да просто начинаю что-то делать! TS прекрасно подходит для написания библиотечек на Node. Например сейчас я разрабатываю компоненты на Node, Vue 3, Vite и TS. Это самый современный и крутой подход на сегодняшний день для написания библиотек на Vue. Если вдруг у коммьюнити будет интерес, соберем энную сумму донатов и я напишу подробную статейку по этой теме, выложу исходники бойлерплейта и покажу схему сборки библиотеки от начала, до продакшена на какой-нибудь NPM.
TypeScript типизация
Конечно первое что слышат люди при изучении TS — это то, что он решает ошибки типов данных, которым так страдает, в нашем случае JS. Да, это действительно так. Сейчас на основной работе мы работаем на Vue 2 без TS, так вот там частенько проблемы с типами встречаются. Деклоративность в коде это неплохо, а иногда даже хорошо. Мы говорим коду, что именно должна вернуть функция и код такой — окей не вопрос, но если ты падла такая попробуешь вернуть что-то другое, пойдешь нахер.
Это не так явно бросается в глаза, когда вы просто указываете тип переменных. Ага — это у нас строка, это массив, это объект и т.д… Конечно это помогает, но куда больший профит от типизации появляется в несколько более сложных примерах типизации. В примере ниже, я создал конфигурационную функцию для одной опенсурс библиотеки и указал что функция возвращает промис с типом MailerOptions, однако пытаюсь вернуть строку и TS мне выдает ошибку.

Конечно я могу не указывать тип возвращаемых данных, но зачем тогда использовать TS? Да и почему не привыкать к типизации? Ведь всегда можно открыть дтску и посмотреть какие данные мы должны вернуть в функции… В моем случае, функция должна вернуть эти данные.

Все предельно очевидно, видно что обязательно, а что нет. Виден и тип данных. Но даже если вы ошибетесь, TS вам об этом расскажет. Более того, я использую phpStorm и эта IDE просто не даст мне вернуть что-то, что не описано в интерфейсе библиотеки. Автокомплит с типизацией это очень мощная штука.
TypeScript панацея?
Не думаю что я могу делать какие-то глобальные выводы, ввиду моей пока что еще не очень большой работы на TS, но я считаю, если вы пишите на ноде, то TS сегодня очень и очень мастхев. Backend, библиотеки или SPA на условном Vue — я всегда буду выбирать TS вместо нативного JS.
Nest.js
Ну вот и дошли до Nest… Короче Nest под капотом использует Express… :) Конечно может использовать и Fastify, но блин… Я ушел с Express на Nest, а Nest использует Express. Но не спешите с выводами. Express он использует да, но при этом решает множество проблем, с которыми вы рано или поздно столкнетесь при масштабировании вашего приложения, если бы вы работали на Express.
При этом, Nest не является оберткой или микрофреймворком, это самый настоящий фреймворк. Если кратко, то Nest собрал в себе почти все лучшие практики по организации лучшего на данный момент бекенда на ноде. Nest использует TS (хотя может работать в режиме чистого JS, но смысла в этом нет), почти вся его концепция завязана на DI и декораторах.
Nest.js — Dependency Injection
Это не очень простая техника, в которой один объект или класс, получает другой объект или класс как зависимость и уже не может работать без него. Иными словами, функционал класса теперь требует эту зависимость. Это довольно часто вызывает проблему циклических зависимостей, когда классу пользователей нужен класс заказов, а классу заказов нужен класс пользователей. Вы можете получить в терминале ошибки, на этот случай у Nest из коробки идет решение. На этой технике строится весь backend, вы будете писать модули и внутри этих модулей делать DI, а так же вы почти наверняка будете делать DI модуля, внутрь другого модуля и т.д.
Nest.js — Декораторы
Это такая штука, с помощью которой вы можете добавить классу некий функционал. В Nest зачастую требуется писать свои декораторы. Конечно все зависит от задачи, но написание декораторов не является большой проблемой. Есть документация и гугл, со временем появляется все больше статей где показывают как работают декораторы внутри Nest.
Например в моем приложении я использую декораторы для проверок ролей и пермишенов пользователей.
Nest.js — саммари
Вообще у Nest из коробки идет все что нужно для организации бека. Интерцепторы для обработки разного типа ошибок, пайпы для трансформации и валидации данных, гарды для защиты роутов и т.д. Документация исключительно дружелюбна, а там где ее не хватает, есть гугл. Так же Nest постепенно обживается экосистемой различных модулей. Так например есть свой модуль для работы с почтой, есть модуль для локализации построенный на i18n и т.д. Я эти модули уже применил на своих проектах и подключение их в проект не намного тяжелее установки дополнений из модстора… :) Шутка, но если погрузиться в контекст работы Nest, то не такая уж и шутка. Если бы вы работали на Express, все вышеописанное и многое другое, вам пришлось бы писать самому.
Nest.js — миграция
Хорош поносословить, начну показывать во что в итоге превратился мой модуль для сотрудников. На данный момент он состоит из 8-ми частей — например модуль сотрудников, модуль авторизации, модули ролей и прав сотрудников и т.д… Я покажу лишь кусочек модуля авторизации:
ДИСКЛЕЙМЕР: Часть кода из примеров ниже я либо упростил, либо вырезал для примера.
Для начала главный файл модуля, куда я импортирую коллекции Mongo, а так же другие модули, которые я так или иначе применяю в модуле авторизации. А значит в силу вступает DI. Так же я регистрирую провайдеры, в которых будет описана бизнес логика
@Module({
imports: [
MongooseModule.forFeature([
{
name: Staff.name,
schema: StaffSchema,
collection: 'staffs',
},
{
name: StaffToken.name,
schema: StaffTokenSchema,
collection: 'staffsTokens',
},
{
name: StaffRoles.name,
schema: StaffRolesSchema,
collection: 'staffsRoles',
},
]),
JwtModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: getJWTConfig,
}),
StaffModule,
StaffRolesModule,
StaffPermissionsModule,
StaffLogsModule,
ConfigModule,
MailModule,
PassportModule,
],
providers: [
StaffAuthValidateService,
StaffAuthPasswordService,
StaffAuthTokenService,
StaffAuthSignUpService,
StaffAuthSignInService,
StaffAuthSignOutService,
StaffAuthEmailService,
StaffJwtStrategy,
],
controllers: [
StaffAuthCommonController,
StaffAuthSelfPasswordController,
StaffAuthSelfEmailController,
StaffAuthOneEmailController,
],
})
export class StaffAuthModule {}Как видите, провайдеров и контроллеров набралось прилично. Дело в том, что я пишу довольно обширную систему аутентификации и авторизации пользователей в свою систему управления сайтом. О ней можно написать отдельную статью, возможно, когда-нибудь это и случится.
Так вот, по поводу большого кол-ва провайдеров и контроллеров — я предпочитаю отделять мух. Писать довольно большую бизнес-логику в одном service-файле, приведет к лапшекоду, в моем случае каждый сервис отвечает за отведенную ему часть бизнес-логики по работе с аутентификацией и авторизацией сотрудников.
Контроллеры разбиты на сущности. В одних описаны епдпоинты по работе сотрудников со своим профилем, в других ендпоинты для работы с другими сотрудниками. Мы ведь не хотим чтобы каждый мог менять каждого? Нужны правила и разбитие на контроллеры помогают эти правила соблюдать. Ну и еще один контроллер содержит в себе общие ендпоинты, для всех сотрудников.
В прошлой статье я выложил код своего модуля авторизации на Express.js. Там в самом начале я писал валидацию. Nest.js предоставляет возможность вынести валидацию в DTO классы. Вот пример моей валидации для аутентификации сотрудника:
export class StaffAuthSignInDto {
@ApiProperty({
example: 'example@example.com',
description: 'Email сотрудника',
})
@IsNotEmpty({ message: 'staff.ERR_EMAIL_IS_EMPTY' })
@IsEmail({}, { message: 'staff.ERR_EMAIL_INVALID' })
email: string;
@ApiProperty({
example: '12346789',
description: 'Пароль сотрудника',
minimum: 8,
})
@IsNotEmpty({ message: 'staff.ERR_PASSWORD_IS_EMPTY' })
@IsString({ message: 'staff.ERR_PASSWORD_IS_STRING' })
@MinLength(8, { message: 'staff.ERR_PASSWORD_MIN_LENGTH' })
password: string;
}@IsNotEmpty — это те самые декораторы, о которых я уже писал ранее. Только это не самописные декораторы, а коробочные из библиотеки class-validator. В объекте message вы видите локали (что-то вроде лексиконов в MODx). В моем бекенде есть мультиязычность, за это отвечает модуль nestjs-i18n.
Опять же, смотрим на код из прошлой статьи, ту часть где я пытаюсь аутентифицировать сотрудника:
// Trying to login
const staff = await Staff.findOne({ email: normalizedEmail });
...и там дальше идут провеки, работа с JWT и т.д.Аутентификация и авторизация теперь разбита на две части. Сначала покажу авторизацию.
@Injectable()
export class StaffAuthSignInService {
constructor(
private readonly staffAuthValidateService: StaffAuthValidateService,
private readonly staffAuthTokenService: StaffAuthTokenService,
) {}
/**
* @description Sign in staff and register JWT token with payloads
* @param staffAuthSignInDto {StaffAuthSignInDto}
*/
async signIn(staffAuthSignInDto: StaffAuthSignInDto): Promise<object> {
const staff = await this.staffAuthValidateService.validateStaff(
staffAuthSignInDto.email,
staffAuthSignInDto.password,
);
const { id, email, username, avatar, role } = staff;
const payload = { id, email, username, avatar, role };
const accessToken = await this.staffAuthTokenService.generateAccessToken(payload);
const refreshToken = await this.staffAuthTokenService.generateRefreshToken(payload);
const foundToken = await this.staffAuthTokenService.findStaffTokenById(payload.id);
if (foundToken) {
await this.staffAuthTokenService.updateRefreshToken(foundToken.id, refreshToken);
return {
accessToken,
refreshToken,
payload,
staff,
};
}
await this.staffAuthTokenService.createRefreshToken(refreshToken, payload.id);
return {
accessToken,
refreshToken,
payload,
staff,
};
}
} Сам метод аутентификации теперь находится в сервисе по валидации сотрудника. Все как завещали отцы, описывающие разницу авторизации и аутентификации:
@Injectable()
export class StaffAuthValidateService {
constructor(
private readonly staffService: StaffService,
@InjectModel(Staff.name) private readonly staffModel: Model<Staff>,
@Inject(forwardRef(() => StaffAuthPasswordService))
private staffAuthPasswordService: StaffAuthPasswordService,
) {}
/**
* @description Validate staff candidate to sign in
* @param email {string}
* @param password {string}
*/
async validateStaff(email: string, password: string): Promise<Staff> {
const staff = await this.staffService.getOneByEmail(email, 'password');
if (
!staff ||
staff.deleted ||
!(await this.staffAuthPasswordService.comparePasswords(password, staff.password))
) {
throw new HttpException(
{ key: 'auth.ERR_INCORRECT_EMAIL_OR_PASSWORD' },
HttpStatus.UNAUTHORIZED,
);
}
if (!staff.active) {
throw new HttpException({ key: 'staff.ERR_NOT_ACTIVATED' }, HttpStatus.UNAUTHORIZED);
}
if (staff.blocked) {
throw new HttpException({ key: 'staff.ERR_IS_BLOCKED' }, HttpStatus.UNAUTHORIZED);
}
return staff;
}
}Обратите внимание, я вызываю методы одного сервиса аутентификационного модуля, в другом. Но в последнем коде, вызывается сервис сотрудников — staffService. Это и есть DI. Я покажу кусочек кода этого сервиса:
async getOneByEmail(email: string, select?: string): Promise<Staff> {
const staff = await this.staffModel
.findOne({ email: email })
.select(`+${select}`)
.populate({ path: 'role', select: '', model: this.staffRoleModel })
.exec();
if (!staff) {
throw new HttpException(
{ key: 'auth.ERR_INCORRECT_EMAIL_OR_PASSWORD' },
HttpStatus.UNAUTHORIZED,
);
}
return staff;
}Вызов этой цепочки методов различных сервисов, избавит нас от необходимости постоянно писать какие-либо проверки. Так что, если возникнут проблемы с аутентификацией сотрудника, это решит либо метод getOneByEmail, либо validateStaff, последний уж точно не пропустит пользователя, если первый не справился с проверкой. Но будьте осторожней с асинхронщиной. К слову, в методе getOneByEmail вызывается модель модуля ролей пользователя. Это тоже DI.
Ну и кусочек контроллера, который создает endpoint для аутентификации:
@StaffAuthDecorator(
{
apiOperation: {
summary: 'Аутентификация сотрудника.',
description: 'Endpoint для аутентификация сотрудника.',
},
apiResponse: {
status: HttpStatus.OK,
},
},
{ statusCode: HttpStatus.OK },
)
@Post('signIn')
async signIn(@Body() staffAuthSignInDto: StaffAuthSignInDto): Promise<object> {
return this.staffAuthSignInService.signIn(staffAuthSignInDto);
}Для начала — в Nest.js есть swagger. Автодокументация для REST API, в уже в самописном декораторе StaffAuthDecorator я описываю эту документацию для текущего ендпоинта. Затем через декоратор указываю метод, путь ендпоинта и сам метод, в теле которого передается та же DTO и вызывается сервис с бизнес-логикой.
Вот здесь я бы хотел тормознуть. По неведомым мне причинам, почти во всех видеоуроках на ютубе, бизнес-логику пишут в контроллере. Я до сих пор не понял зачем авторы курсов так делают. Может кто-то в комментах мне объяснит?
Ну собственно все. Конечно надо было бы показать как подключается база данных (mongo или postgres), как подключается модуль для работы с JWT или про unit-тесты рассказать… Но это уже такие нишевые темы, что включать их в эту статью, будет не очень правильно.
Стало ли у меня больше кода в сравнении с тем что было в прошлой статье? Да, мой модуль сотрудников сайта вырос значительно. Буквально вот на днях я дописал модуль логов (примерно как в MODx журнал событий). Выведу его в админку, протестирую и сделаю деплой.
Если честно, в холодный пот бросает, когда пытаюсь себе представить как бы выглядел набор модулей для работы с сотрудника на Express.js…
P.S.
Сборки моих проектов работают через микросервисы- бекенд, админка и фронт разделены и лежат в своих репозиториях (сабмодулях), есть отдельный репозиторий с настройками докера. Именно он разруливает через nginx маршрутиризацию. Деплой происходит через релиз новой версии проекта в Github, через Actions — полностью автоматизировано практически все.
В планах разработать большой модуль для работы с контентом сайта (статьи, товары и т.д.) благо есть хороший референс.
Будет ли следующая статья — не знаю. Но цикл статей я могу продолжать еще прилично долго, темы и материал есть. Могу погрузится в Nest.js или написать статью про Vue. Там же будет затронута тема с TS повторно, на реальном примере.
Спасибо что читаете мои статейки. Засим откланиваюсь.
Комментарии: 55
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Nest и правда очень крут и приятен в использовании. Документация покрывает все основные вопросы с запасом, а чего нет, всегда можно нагуглить.
Рад, что люди из сообщества растут, набираются новых знаний и делятся своими впечатлениями. Жаль @Fi1osof давно перестал заметки оставлять.
Я недавно решил попробовать go (никак не связанно с заметками про modx на go), заметку писать не буду, но пока все очень круто.
Fi1osofНу и если кто следил и кому интересно, к чему привел уход от MODX: теперь я работаю в сберлабе виртуальной и дополненной реальности. Очень интересно! И по деньгам сильно лучше. И да, там MODX нет и не планируют.
Дисклейм: я не хочу сказать, что мне не было раньше интересно с MODX. Было. Но мир меняется. До MODX я работал с другими технологиями. Потом пришел он, мне он понравился. Потом появилось новое и более интересно. Будут еще новые технологии. А вы уже сами решайте что и как для себя выбирать.
И если кто считает, что я переобулся, будет совершенно не прав. Кто был в теме в 2009 году, наверняка видел, как я говорил «Мир не держится на одном MODX Evolution, посмотрите и MODX Revolution для расширения кругозора». Тогда староверы были сильно против этого и топили за Эво. Но по сути, это все же разные технологии. Прошли года, опять технологии сменились. И опять я говорю: смотрите шире.
Аудитория в большинстве своем вряд ли поймет о чем тут речь и зачем это использовать.
Да и аудитории тут в общем то почти не осталось.
А что случилось с аудиторией? Переехали на другой ресурс?
Ну потому что в первых двух публикациях ты все таки вокруг MODX крутился, хотя бы в сравнительной части. Там были посылы о том, что существуют и другие технологии.
Эта статья резко отличается. Она MODX никак не затрагивает, Много кода, с которым знаком не каждый.
Ну и я бы еще отметил то, что мне не понятна центральная мысль этой публикации. В первых двух была понятна.
Лично я против того, чтобы на портале посвященному MODX писали о том, что с MODX не связано. Сравнительные обзоры и отсылки к технологиям да, а вот погружение с головой во что-то другое, это мне не нравится.
Заметь, пишу свое личное мнение, не как админ.
Я так понял тут сменились владельцы проекта. На самом деле всю архитектуру сотрудников в своей системе я делал вокруг пользователей из MODx. Как референс лучше чем MODx опенсурс проектов просто нет, тот же OctoberCMS, пару месяцев назад рассматривал его админку, не очень удобная и понятная конечно, имхо.
Мой посыл статей статей связан с моим уходом от MODx, и опытом, которым я делюсь в этих статьях. Во второй части я почти ничего про MODx не говорю, так что уже там можно было этот вопрос задать.
Но намек мне понятен, в городе новый шериф… ) На самом деле, думаю что все таки эта статья будет последней. Следующие буду писать на своем сайте, уже более предметные с технической стороны, без воды и историй из жизни. Так что, оставлю эти статьи на откуп новому шерифу, захочет — удалит. Хотелось закончить начатое, плюс обещал некоторым людям и со своей стороны я это сделал.
Я ведь могу сказать что мне что-то не нравится, если мне что-то не нравится верно?
Ты можешь смотреть и учитывать мой комментарий в общей массе.
Я бы предложил создать отдельные тематические ветки, но все это сейчас не имеет смысла. Даже обсуждение не имеет смысла. Тут аудитория 20 человек. А пишущих что-то осталось человек 5.
В чате ситуация не лучше. Статистика показывает что там всего 70 человек в принципе что-то читает. А пишущих, отвечающих — может человек 15 осталось.
Это очень печально (
И посмотри на аналогичное участие на последних 10-20 публикациях.
Просто надо так же понимать, что те кто раньше писал статьи, тоже уходят в другой стек.
Но насчет стека ты не до конца прав.
Очень много украинцев просто принципиально ушли, многие ушли скажем так, не по своей воле.
Я знаю ребят, постоянных и активных авторов, которые теперь по Европе скитаются, и им не до MODX. Денег бы на жилье заработать.
Из Белоруссии тоже проблемные новости в течение года приходили. Как минимум у одного из наших были проблемы политические.
Ну и смена стека конечно тоже дает о себе знать. Вон @Сергей Шлоков например практически покинул нас (
P.S.
Я если что, не про бытовые проблемы говорю. Конечно когда денег нет и жить негде, тут уже не до MODx.
Если верить ей, то посещаемость за 9 месяцев 22 года уже равна 21 году целиком. В день аудитория 600-800 уникальных посетителей.
Что я вижу — до конца лета 2018 года посещаемость с поиска стабильно росла (с Гугла трафика в 2 раза больше по причине популярности этого поисковика в IT сфере).
Потом трафик стал проседать, и уменьшился примерно в 2 раза. В большинстве случаев это указывает на то, что на сайте что-то было такое сделано, что негативно повлияло на индексацию и ранжирование в поиске.
Смотрим ленту и вижу
Обновление modx.pro 10 июля 2018 г.
Упс…
Вот посещаемость за весь 2018 год, я не вижу тут падения после обновления.
Вот трафик из поисковиков за 2018
А вот потом, когда народ устал ждать MODX 3 — и пошёл спад. В следующие 3 года это чётко видно
А после 2018-го сайтов по modx развелось много. modx.pro не в первых строчках. Может трафик просто на них ушел?
Гугл тренды
Переиспользование:
В Nest.js CLI есть Libraries. Это переиспользование модулей, что-то вроде того, как переиспользуются библиотеки на Vue или React из проекта в проект. Конечно, если вы пишите большое кол-во сайтов, стоит разбивать приложение на модули, а эти модули уже подключать к тому или иному приложению.
Это то, чем мне не нравился MODx. Я писал об этом несколько раз — админка слишком сложная и перегруженная. Есть такие вещи как кастомизация форм, расписание сайта, журнал системы управления, различные импорты ресурсов и т.д. Все это должно быть расширениями. Примерно как есть MiniShop2 и разработчики написали огромное кол-во компонентов, которые расширяют этот eCommerce компонент.
В Nest.js вы как раз можете дробить модули на npm пакеты и переиспользовать их в проектах, примерно как компоненты из магазина Modstore.
CMS:
CMS я уже можно сказать написал, во всяком случае пилотную версию, одного из своих клиентов на нее перевел. Но это не eCommerce, а обычный информационный сайт. Как я уже написал в статье, в планах, в следующем году реализовать большую систему для управления контентом сайта (как статьями, так и товарами). Но это будет мой внутренний продукт, выкладывать его в публичный доступ не буду.
Вась у тебя же новый курс примерно про это?
А Next.js — это для React
Совсем никакого креатива в названиях у людей.
Может превратим тематический сайт в помойку, типа: установка WINDOWS, Centos, настройка VPS и всякие другое про IT!?
Заведи свой блог, кому будет интересно тот подпишется на тебя!
Про это написал не я.
Пост на твой совести (я бы удалил) и админы не причем, ты реально путаешь тематики, оффотпер!
Ты не критикуешь, ты предъявляешь и указываешь мне что делать, но на вопрос не отвечаешь. Еще раз — твой совет что мне делать, я не спрашивал, зачем ты мне его даешь?
Скажем так… с одной стороны не было ответов на многие вопросы.
С другой стороны есть такой портал DigitalOcean — там я нашел подробные, пошаговые инструкции для реализации практически каждого вопроса, который у меня был.
Резюмирую. У меня есть некоторая квалификация и понимание основ в данном направлении, но сколько бы я не задумывался нужны ли статьи в данном направлении — я понимаю что не нужны. Они уже есть. По Базовой настройке и конфигурации, по защите, по оптимизации, по Highload
MODX особо ничем не отличается от других систем, нет каких-то специфических требований и писать именно с оглядкой на нашу CMF по сути не получится.
Но у меня если честно, в голове на эту тему какой-то сумбур… Помимо миграций, там еще нужно запускать скрипты автоустановки и автонастройки компонентов. Базу файлов тоже поддерживать в актуальном состоянии. Но не думаю что в контексте MODx люди часто разворачивают VPS. В основном многие сидят на шейрингах, а там это как-бы, мало актуально, наверное.
Пишу об этом, т.к. вести разработку через контейнирезацию и Git (для системы версий и деплоя на продакшн), это очень удобно. Особенно когда хорошо умеешь в девопсе.
Твои посты про Nest на портале про MODX равносильны как, ты приехал на BMW M5 в лес на соревнования по бездорожью!
Про пост — я тебя давно понял. Статью не удалю. Буду в лесу стоять на бмв на бездорожье.
modx.pro/hosting/23448
Просто небо и земля