задний план
В этой статье я буду использоватьNest.js
построитьCNode.
Почему эта статья? мне нравитьсяNodeJs
, хотя мойNodeJs
средний уровень. Но я все еще использую его для документирования процесса обучения.
Недавно я обнаружилNest.jsФреймворк, который эффективно решает сложную проблему в проектах Nodejs: архитектуру.Nest
Разработан для предоставления готовых приложений, которые упрощают создание легко тестируемых, расширяемых, слабосвязанных и простых в обслуживании приложений.Nest.js
БудуTypeScript
представлятьNode.js
в и на основеExpress
упаковка. Итак, я хочу использоватьNest.js
попробуй написатьCNode. (ps: в настоящее время CNode принимаетEggпишите) Квикстарта на эту тему не нашел, поэтому приведу свою практику, которую вы легко сможете распространить на свой проект.
Цель этой статьи не в том, чтобы представить Nest.js. Для тех, кто не знаком с Nest.js: это платформа для создания веб-приложений Node.js. Хотя Node.js уже включает множество библиотек для разработки веб-приложений, ни одна из них не затрагивает одну из самых важных тем: архитектуру.
А теперь пристегните ремни, мы идем.
Что такое гнездо
Nest
является мощнымNode web
Рамка. Это поможет вам легко создавать эффективные, масштабируемые приложения. он использует современныеJavaScript
,использоватьTypeScript
строить, комбинироватьOOP
(объектно-ориентированное программирование) иFP
Лучшая концепция (функциональное программирование).
Это не просто еще один фреймворк. Вам не нужно ждать большого сообщества, потому чтоNest
Он использует замечательную, популярную известную библиотеку --Express
а такжеsocket.io
Это означает, что вы можете быстро начать использовать фреймворк, не беспокоясь о сторонних плагинах.
авторKamil MyśliwiecПервоначальное намерение:
JavaScript прекрасен, Node.js дал нам возможность использовать этот язык и на стороне сервера, на этой платформе много замечательных библиотек, хелперов и инструментов, но ни один из них не решает главную проблему — архитектуру. Это почему я решил создать фреймворк Nest.
важный:
Nest
полученоJava Spring
а такжеAngular
вдохновение. если вы использовалиJava Spring
илиAngular
В освоении будет очень легко, я сам постоянно им пользуюсьAngular
.
Основные концепции Nest
Основная концепция Nest — предоставить архитектуру, которая поможет разработчикам достичь максимального разделения уровней и повысить уровень абстракции в приложениях.
Обзор архитектуры
Nest
УсыновленныйES6
а такжеES7
Особенности (decorator
, async/await
). Если вы хотите использовать их, вам нужно использоватьBabel
илиTypeScript
Перевести вes5
.
Nest
По умолчанию используетсяTypeScript, также можно использовать напрямуюJavaScript
, но это не имеет смысла.
если вы использовалиAngular, вы найдете эту статью очень знакомой, потому что большинство из них написаны одинаково. Неважно, использовали ли вы их, я веду вас изучать их вместе.
Модуль Модуль
использоватьNest
, вы можете естественным образом разделить свой код на независимые и повторно используемые модули.Nest
модуль - это@Module()
Класс декоратора. Этот декоратор предоставляет метаданные, которые платформа использует для организации структуры приложения.
каждыйNest
Приложения имеют корневой модуль, обычно называемыйAppModule
. Корневой модуль обеспечивает механизм начальной загрузки, используемый для запуска приложения. Приложение обычно содержит множество функциональных модулей.
картинаJavaScript
Как модули,@Module
Также доступен из др.@Module
импортировать функции в и разрешать экспортировать собственные функции для других@Module
использовать. Например, чтобы использовать в своем приложенииnest
который предоставилmongoose
Для работы функции необходимо импортироватьMongooseModule
.
Организация вашего кода в четкие функциональные модули может помочь в управлении разработкой сложных приложений и обеспечить многократное использование проектов. Кроме того, эта методика позволяет использовать динамическую нагрузку,MongooseModule
заключается в использовании этой технологии.
@Module
Декоратор принимает объект, свойства которого описывают модуль:
Атрибуты | описывать |
---|---|
providers |
Зависит отNest Служба, созданная инжектором, может совместно использоваться этим модулем. |
controllers |
Содержит созданный набор контроллеров. |
imports |
Список модулей, который импортирует поставщиков, необходимых в этом модуле. |
exports |
Экспорт этого модуля может быть использован другими модулямиproviders услуги в. |
@Module
Контекст компиляции объявляется для набора контроллеров, который фокусируется на области приложения, рабочем процессе или тесно связанном наборе возможностей.@Module
Его контроллер может быть связан с набором связанного кода, такого как служба, для формирования функционального блока.
Как организовать схему структуры модуля
Корневой модуль AppModule
- Базовые модули CoreModule (регистрация промежуточного ПО, фильтры, конвейеры, охранники, перехватчики, декораторы и т. д.)
- Общие модули SharedModule (зарегистрированные сервисы, mongodb, redis и т. д.)
- Модуль конфигурации ConfigModule (конфигурация системы)
- FeatureModule Функциональные модули (бизнес-модули, такие как пользовательские модули, модули продукта и т. д.)
существуетNest
, модули по умолчанию являются одноэлементными, поэтому один и тот же экземпляр любого поставщика может совместно использоваться несколькими модулями. Совместное использование модулей не требует усилий.
Общий вид относительно чистый и освежающий, как и я.Angular
Разделение модулей, которое использовалось в проекте.
Если у вас есть лучшие предложения, добро пожаловать, чтобы общаться и совершенствоваться со мной.
Контроллер Контроллер
Контроллер отвечает за обработку параметров запроса, переданных клиентом, и возврат данных ответа клиенту.Популярным моментом является маршрутизация.Router
.
Для создания базового контроллера мы используем@Controller
декоратор. Они связывают классы с базовыми метаданными, поэтомуNest
Знать, как сопоставлять контроллеры с соответствующими маршрутами.
@Controller
Требуется определить базовый контроллер.@Controller('Router Prefix')
является необязательным префиксом для каждого маршрута, зарегистрированного в классе. Использование префикса позволяет избежать повторного использования самого себя, когда все маршруты имеют общий префикс.
@Controller('user') export class UserController { @Get() findAll() { return []; } @Get('/admin') admin() { return {}; } } // findAll访问就是 xxx/user // admin访问就是 xxx/user/admin
Контроллер — это относительно основная функция, вокруг которой строится весь бизнес.Nest
Он также предоставляет множество связанных декораторов.Далее я представлю их один за другим.Это просто краткое описание, а их использование будет представлено позже в реальном бою.
Запрос объекта представляет собой запрос HTTP и запрос с параметром строки запроса, заголовками HTTP, свойства, но в большинстве случаев не нужно их вручную получить их. Мы можем использовать преданныйdecorator
,Например@Body()
или@Query()
, они доступны из коробки. Нижеdecorator
с обычнымExpress
сравнение объектов.
Давайте сначала поговорим о декораторе параметра метода:
имя декоратора | описывать |
---|---|
@Request() |
вести перепискуExpress изreq , также можно сократить@req
|
@Response() |
вести перепискуExpress изres , также можно сократить@res
|
@Next() |
вести перепискуExpress изnext
|
@Session() |
вести перепискуExpress изreq.session
|
@Param(param?: string) |
вести перепискуExpress изreq.params
|
@Body(param?: string) |
вести перепискуExpress изreq.body
|
@Query(param?: string) |
вести перепискуExpress изreq.query
|
@Headers(param?: string) |
вести перепискуExpress изreq.headers
|
Давайте сначала поговорим о декораторе метода:
имя декоратора | описывать |
---|---|
@Post() |
вести перепискуExpress изPost метод |
@Get() |
вести перепискуExpress изGet метод |
@Put() |
вести перепискуExpress изPut метод |
@Delete() |
вести перепискуExpress изDelete метод |
@All() |
вести перепискуExpress изAll метод |
@Patch() |
вести перепискуExpress изPatch метод |
@Options() |
вести перепискуExpress изOptions метод |
@Head() |
вести перепискуExpress изHead метод |
@Render() |
вести перепискуExpress изres.render метод |
@Header() |
вести перепискуExpress изres.header метод |
@HttpCode() |
вести перепискуExpress изres.status метод, который можно комбинировать сHttpStatus перечислить |
Вышеупомянутые в основном декораторы контроллера.Некоторые общие параметры HTTP-запроса необходимо использовать вместе с соответствующими декораторами и параметрами методов.
Что касается возврата данных ответа,Nest
Также доступны 2 решения:
-
непосредственно вернуть
JavaScript
объект или массив, он будет автоматически разрешен кJSON
. Когда мы возвращаем строку,Nest
Просто отправьте строку, не пытаясь ее разобрать. По умолчанию код состояния ответа всегда200
,
ноPOST
за исключением запросов, которые используют201
. можно использовать@HttpCode(HttpStatus.xxxx)
Декораторы могут легко изменить это поведение. -
Мы можем использовать конкретный объект ответа библиотеки, мы можем использовать здесь@res() модификатор внедряет объект в сигнатуру функции,
res.status(HttpStatus.CREATED).send()
илиres.status(HttpStatus.OK).json([])
ЖдатьExpress
изres
метод.
Уведомление: Запрещено использовать эти два метода одновременно, если использовать оба, то этот маршрут работать не будет. Если вы обнаружите, что маршрут не отвечает, когда вы его используете, проверьте, нет ли какого-либо смешанного использования.Если это нормально, рекомендуется вернуться к первому методу.
Контроллер должен быть зарегистрирован в метаданных модуля.
controllers
нормально работать.
Что касается обработки исключений контроллера, фильтр будет объяснен позже.
Внедрение зависимостей от провайдера
Служба — это широкое понятие, которое включает любое значение, функцию или свойство, требуемое приложением. Услуга в узком смысле — это класс с четко определенной целью. Он должен делать что-то конкретное и делать это хорошо.
Nest
Отдельные контроллеры и сервисы для улучшения модульности и возможности повторного использования.
Отделив связанные с логикой функции в контроллере от других типов обработки, вы можете сделать класс контроллера компактнее и эффективнее. В идеале работа контроллера состоит в том, чтобы объявлять декораторы и отвечать данными, и ничего более. Он должен обеспечивать мост запроса и ответа, чтобы действовать как посредник между представлением (отображаемым шаблоном) и логикой приложения (которая обычно содержит некоторое понятие модели).
Контроллеру не нужно определять что-либо вроде получения данных от клиента, проверки ввода пользователя или записи журналов непосредственно в консоль. Вместо этого делегируйте эти задачи различным службам. Определяя различные задачи обработки в внедряемых классах обслуживания, вы можете сделать их доступными для любого контроллера. Вы также можете сделать свое приложение более адаптируемым, внедрив разных поставщиков одной и той же службы в разные среды.
Nest
Эти принципы не соблюдаются. Это просто упрощает разложение логики вашего приложения на сервисы посредством внедрения зависимостей и делает эти сервисы доступными для отдельных контроллеров.
Контроллеры являются потребителями служб, то есть вы можете внедрить службу в контроллер и предоставить классу контроллера доступ к классу службы.
Тогда сервис — это провайдер, в принципе почти все можно рассматривать как провайдер — сервис, репозиторий, фабрику, помощника и т.д. Они могут быть внедрены в зависимости конструктивной функцией, что означает, что они могут создавать различные отношения друг с другом.
существуетNest
, чтобы определить класс как службу, используйте@Injectable
декоратор для предоставления метаданных, чтобыNest
Его можно внедрить в контроллер как зависимость.
Аналогично, также используйте@Injectable
Декоратор, чтобы указать, что контроллер или другой класс (например, другая служба, модуль и т. д.) имеет зависимость. Зависимость не обязательно должна быть службой, это может быть функция или значение и т. д.
Инъекция зависимостей (часто сокращенная ди) вводится вNest
В кадре используется для использования его везде, чтобы обеспечить желаемую услугу или другие вещи для вновь созданного контроллера.
Инжектор является основным механизмом. Вам не нужно создавать его самостоятельноNest
инжектор.Nest
Во время запуска для вас создается полный инжектор уровня приложения.
Инжектор поддерживает контейнер экземпляров зависимостей, которые он создал, и максимально повторно использует их.
Провайдеры — это рецепты для создания зависимостей. Для сервисов это обычно сам класс сервиса. Любой класс, который вы используете в своем приложении, должен зарегистрировать поставщика в инжекторе приложения, чтобы инжектор мог использовать его для создания новых экземпляров.
О внедрении зависимостей, интерфейсном фреймворкеAngular
Наверное, самый известный, вы можете увидетьздесьпредставлять.
// 用户服务 import { Injectable } from '@nestjs/common'; interface User {} @Injectable() export class UserService { private readonly user: User[] = []; create(cat: User) { this.user.push(User); } findAll(): User[] { return this.user; } } // 用户控制器 import { Controller, Get, Post, Body } from '@nestjs/common'; import { UserService } from './user.service'; @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} @Post() async create(@Body() createUserDto: CreateUserDto) { this.userService.create(createUserDto); } @Get() async findAll(): Promise<User[]> { return this.userService.findAll(); } }
индивидуальный сервис
Мы можем не только использовать@Injectable()
Существует три других способа определить услугу:value
,class
,factory
.
Это то же самое, что и Angular, по умолчанию@Injectable()
Чтобы определить услугуclass
.
использоватьvalue
:
const customObject = {}; @Module({ controllers: [ UsersController ], components: [ { provide: UsersService, useValue: customObject } ], })
Уведомление:
useValue
может быть любым значением, в этом модулеNest
положитcustomObject
а такжеUsersService
Соответственно, вы также можете использовать его как тестовый дубль (модульный тест).
использоватьclass
:
import { UserService } from './user.service'; const customObject = {}; @Module({ controllers: [ UsersController ], components: [ { provide: UsersService, useClass: UserService } OR UserService ], })
Уведомление: Только в этом модуле с использованием выбранного, более конкретного класса,
useClass
может быть иprovide
то же самое, если не то же самое, чтоuseClass
заменятьprovide
. Простое понимание изменения методов, без изменения имени метода, обычно используемого для работы с внедрением зависимостей в разных средах.
использоватьfactory
:
@Module({ controllers: [ UsersController ], components: [ ChatService, { provide: UsersService, useFactory: (chatService) => { return Observable.of('customValue'); }, inject: [ ChatService ] } ], })
Уведомление: хочет предоставить значение, которое должно быть вычислено с использованием другого компонента (или пользовательского атрибута пакета) хочет предоставить асинхронные значения (возвращают только наблюдаемые или обещанные значения), такие как соединение с базой данных.
inject
зависимые услуги,provide
зарегистрированное имя,useFactory
способ обработки,useFactory
параметры иinject
Порядок массива инъекций такой же.
если мыprovide
Что делать, если регистрационное имя не служба, а строкаkey
, также очень часто используется.
@Module({ controllers: [ UsersController ], components: [ { provide: 'isProductionMode', useValue: false } ], })
Чтобы использовать выбранную пользовательскую строкуkey
, вы должны сообщить Nest, что вам нужно использовать@Inject()
декоратор, например:
import { Component, Inject } from 'nest.js'; @Component() class SampleComponent { constructor(@Inject('isProductionMode') private isProductionMode: boolean) { console.log(isProductionMode); // false } }
Существует также круглая яма зависимости, и реальный бой покажет, как избежать и решить эту яму.
Служба должна быть зарегистрирована в метаданных модуля.
providers
нормально работать. Если он должен использоваться другими модулями, его необходимо добавить вexports
середина.
ПО промежуточного слоя
Промежуточное ПО — это функции, которые вызываются перед обработчиками маршрутов. Функции промежуточного ПО имеют доступ к объектам запроса и ответа, а также к следующей функции промежуточного ПО в цикле запроса-ответа приложения. Следующая промежуточная функция обычно вызываетсяnext
переменное представление. существуетExpress
Промежуточное ПО очень известно.
по умолчанию,Nest
Эквивалентное представление промежуточного программного обеспеченияExpress
промежуточное ПО. а такжеExpress
Функция промежуточного программного обеспечения аналогична, функция промежуточного программного обеспечения может выполнять следующие задачи.
- выполнить любой код.
- Внесите изменения в объекты запроса и ответа.
- Цикл запрос-ответ заканчивается.
- Вызовите следующую функцию промежуточного программного обеспечения в стеке.
- Если текущая промежуточная функция не завершает цикл запрос-ответ, она должна вызвать
next()
Передать управление следующей промежуточной функции. В противном случае запрос будет приостановлен.
просто понятьNest
промежуточное ПОExpress
Промежуточное ПО упаковано. Преимущество в том, что пока вы хотите использовать промежуточное программное обеспечение, вы можете сразу искатьExpress
Промежуточное ПО готово к использованию. Это очень удобно.
Nest
Промежуточное ПО — это либо функция, либо@Injectable()
Класс декоратора. класс должен реализоватьNestMiddleware
интерфейсы, а функции не предъявляют особых требований.
// 实现一个带有`@Injectable()`装饰器的类打印中间件 import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common'; @Injectable() export class LoggerMiddleware implements NestMiddleware { resolve(...args: any[]): MiddlewareFunction { return (req, res, next) => { console.log('Request...'); next(); }; } }
Как использовать, есть два способа:
- Промежуточное ПО может быть зарегистрировано глобально
async function bootstrap() { // 创建Nest.js实例 const app = await NestFactory.create(AppModule, application, { bodyParser: true, }); // 注册中间件 app.use(LoggerMiddleware()); // 监听3000端口 await app.listen(3000); } bootstrap();
- Промежуточное ПО может быть зарегистрировано локально в модулях
export class CnodeModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(LoggerMiddleware) .with('ApplicationModule') .exclude( { path: 'user', method: RequestMethod.GET }, { path: 'user', method: RequestMethod.POST }, ) .forRoutes(UserController); } } // or export class CnodeModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(LoggerMiddleware) .forRoutes('*'); } } // 1. with是提供数据,resolve里可以获取,exclude指定的路由,forRoutes注册路由, // 2. forRoutes传递'*'表示作用全部路由
Уведомление: Они зарегистрированы в разных местах, и затрагиваемые маршруты тоже разные.Глобальная регистрация влияет на все маршруты, а локальная регистрация влияет только на маршруты под текущим маршрутом.
фильтр Фильтр исключений
Уровень фильтра исключений отвечает за обработку всех выброшенных исключений в приложении. При обнаружении необработанного исключения конечный пользователь получит соответствующий удобный ответ.
Показать ответ по умолчаниюJSON
Информация
{ "statusCode": 500, "message": "Internal server error" }
Используйте низкоуровневый фильтр
@Post() async create(@Body() createCatDto: CreateCatDto) { throw new HttpException('Forbidden', HttpStatus.FORBIDDEN); }
HttpException принимает 2 параметра:
- Содержимое сообщения, которое может быть строковым сообщением об ошибке или объектом.
{status: 状态码,error:错误消息}
- код состояния
Очень хлопотно писать столько каждый раз, тогда фильтр также поддерживает расширение и настройку объекта фильтра ярлыков.
export class ForbiddenException extends HttpException { constructor() { super('Forbidden', HttpStatus.FORBIDDEN); } }
Вы можете использовать его напрямую:
@Post() async create(@Body() createCatDto: CreateCatDto) { throw new ForbiddenException('Forbidden'); }
Не так ли удобнее.
Nest
Дает нам много этих быстрых и распространенных ошибок состояния HTTP:
- BadRequestException 400
- UnauthorizedException 401
- ForbiddenException 403
- NotFoundException 404
- NotAcceptableException 406
- RequestTimeoutException 408
- ConflictException 409
- GoneException 410
- PayloadTooLargeException 413
- UnsupportedMediaTypeException 415
- UnprocessableEntityException 422
- InternalServerErrorException 500
- NotImplementedException 501
- BadGatewayException 502
- ServiceUnavailableException 503
- GatewayTimeoutException 504
Основы обработчика исключений хороши, но иногда вам может понадобиться полный контроль над уровнем исключений, например, добавить ведение журнала или использовать другойJSON
Шаблоны основаны на некоторых выбранных факторах. Я сказал раньше,Nest
Дайте нам встроенный шаблон ответного ответа.Это неприемлемо.Что нам делать с настройкой?Nest
Дайте нам возможность расшириться.
import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common'; import { HttpException } from '@nestjs/common'; @Catch(HttpException) export class HttpExceptionFilter implements ExceptionFilter { catch(exception: HttpException, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse(); const request = ctx.getRequest(); const status = exception.getStatus(); response .status(status) .json({ statusCode: status, timestamp: new Date().toISOString(), path: request.url, }); } }
он возвращаетExpress
Методыresponse
, чтобы настроить собственный формат исключения ответа.
Как использовать, есть четыре способа:
- непосредственный
@UseFilters()
Используется в декораторе для обработки результата ответа текущего маршрута.
@Post() @UseFilters(HttpExceptionFilter | new HttpExceptionFilter()) async create(@Body() createCatDto: CreateCatDto) { throw new ForbiddenException(); }
- непосредственный
@UseFilters()
Используется в декораторе для направления всех результатов ответа на текущий контроллер.
@UseFilters(HttpExceptionFilter | new HttpExceptionFilter()) export class CatsController {}
- Глобальная регистрация с использованием встроенных методов экземпляра
useGlobalFilters
, который действует на весь проект. Этот тип фильтра является более общим и рекомендует глобальную регистрацию.
async function bootstrap() { const app = await NestFactory.create(ApplicationModule); app.useGlobalFilters(new HttpExceptionFilter()); await app.listen(3000); } bootstrap();
трубка
Конвейеры могут проверять тип, структуру объекта или данные сопоставления с параметрами вашего запроса в соответствии с определенными условиями. Конвейер — это чистая функция, и он не должен выбирать или вызывать какие-либо сервисные операции из базы данных.
Определите простой конвейер:
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common'; @Injectable() export class ValidationPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { return value; } }
трубы используются@Injectable()
Класс комментария декоратора. Должен быть реализованPipeTransform
интерфейс, конкретный код находится вtransform
реализовать, это иAngular
Так же, как.
Nest
Обрабатывает проверку данных запроса, создает исключения, когда данные неверны, и использует фильтры для их обнаружения.
Nest
Для нас встроены 2 основных конвейера: проверка данныхValidationPipe
, преобразование данныхParseIntPipe
.
использоватьValidationPipe
нужно сотрудничатьclass-validator class-transformer
, если вы их не устанавливаете, вы используетеValidationPipe
сообщит об ошибке.
намекать:
ValidationPipe
Возможна не только проверка данных запроса, но и преобразование типов данных, что можно увидеть на официальном сайте.
Как использовать, есть четыре способа
- непосредственный
@Body()
Используется в декораторе, используется только текущий параметр body
// 用户控制器 import { Controller, Get, Post, Body } from '@nestjs/common'; import { UserService } from './user.service'; @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} @Post() async create(@Body(ValidationPipe | new ValidationPipe()) createUserDto: CreateUserDto) { this.userService.create(createUserDto); } }
- существует
@UsePipes()
Используется в декораторе для обработки всех параметров запроса текущего маршрута.
// 用户控制器 import { Controller, Get, Post, Body } from '@nestjs/common'; import { UserService } from './user.service'; @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} @Post() @UsePipes(ValidationPipe | new ValidationPipe()) async create(@Body() createUserDto: CreateUserDto) { this.userService.create(createUserDto); } }
- существует
@UsePipes()
Используется в декораторе для маршрутизации всех параметров запроса к текущему контроллеру.
// 用户控制器 import { Controller, Get, Post, Body } from '@nestjs/common'; import { UserService } from './user.service'; @Controller('user') @UsePipes(ValidationPipe | new ValidationPipe()) export class UserController { constructor(private readonly userService: UserService) {} @Post() async create(@Body() createUserDto: CreateUserDto) { this.userService.create(createUserDto); } }
- Глобальная регистрация с использованием встроенных методов экземпляра
useGlobalPipes
, который действует на весь проект. Этот конвейер является более общим и рекомендует глобальную регистрацию.
async function bootstrap() { const app = await NestFactory.create(ApplicationModule); app.useGlobalPipes(new ValidationPipe()); await app.listen(3000); } bootstrap();
ТакcreateUserDto
Как играть, фактический боевой туториал объяснит это позже, здесь он не будет расширяться.
@Get(':id') async findOne(@Param('id', ParseIntPipe | new ParseIntPipe()) id) { return await this.catsService.findOne(id); }
ParseIntPipe
Его также очень просто использовать, то есть преобразовать строку в число. Он также чаще используется, особенно когда ваш идентификатор представляет собой строковое число, используйтеget
,put
,patch
,delete
Ожидание запроса, особенно полезно, когда есть id.
Вы также можете выполнять пейджинговую обработку, которая будет использоваться позже в реальном бою, что будет подробно объяснено.
Сторожить
Охранник может выполнять аутентификацию разрешения. Если у вас нет разрешения, он может отказать вам в доступе к этому маршруту и вернуться по умолчанию.403
ошибка.
Определите простой конвейер:
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; import { Observable } from 'rxjs'; @Injectable() export class AuthGuard implements CanActivate { canActivate( context: ExecutionContext, ): boolean | Promise<boolean> | Observable<boolean> { const request = context.switchToHttp().getRequest(); return validateRequest(request); } }
охрана используется@Injectable()
Класс, аннотированный декоратором. должны быть реализованыCanActivate
интерфейс, конкретный код находится вcanActivate
Метод реализован и возвращает логическое значение, true указывает на разрешение, а false выдает ошибку исключения 403. Это написание иAngular
Так же, как.
Как использовать, есть два способа
- непосредственный
@UseGuards()
Используется в декораторе для маршрутизации всех параметров запроса к текущему контроллеру.
@Controller('cats') @UseGuards(RolesGuard | new RolesGuard()) export class CatsController {}
- Глобальная регистрация с использованием встроенных методов экземпляра
useGlobalGuards
, который действует на весь проект.
const app = await NestFactory.create(ApplicationModule); app.useGlobalGuards(new RolesGuard());
Если вы не выполняете операции аутентификации, связанные с управлением правами, эта функция вам практически не нужна. Еще полезная абстракция. Мы также будем использовать эту функцию в этом реальном боевом проекте.
Перехватчик Перехватчик
Перехватчик — это специальная и мощная функция, похожая на АОП-аспектное программирование, и эта технология также была опробована во внешнем программировании.Например, различные библиотеки HTTP-запросов предоставляют аналогичные функции. знаменитый кадрAngular
HTTP-модуль фреймворка. У известных библиотек есть старыеjquery
и модныйaxios
Ждать.
Определите простой перехватчик:
import { Injectable, NestInterceptor, ExecutionContext } from '@nestjs/common'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; @Injectable() export class LoggingInterceptor implements NestInterceptor { intercept( context: ExecutionContext, call$: Observable<any>, ): Observable<any> { console.log('Before...'); const now = Date.now(); return call$.pipe( tap(() => console.log(`After... ${Date.now() - now}ms`)), ); } }
Используется перехватчик@Injectable()
Класс, аннотированный декоратором. должны быть реализованыNestInterceptor
интерфейс, конкретный код находится вintercept
реализация метода возвращаетObservable
, это письмо иAngular
Так же, как.
Что может перехватчик:
- Привязать дополнительную логику до/после выполнения метода
- Преобразование результата, возвращаемого функцией
- Преобразование исключений, выброшенных из функций
- Расширьте базовое поведение функции
- Полное покрытие функции зависит от выбранных условий (например, кэширование).
Как использовать, есть три способа
- непосредственный
@UseInterceptors()
Она используется в декораторе для работы с текущим маршрутом, а также может передавать параметры, требует специальной обработки, может быть написана как функция высшего порядка, а также может использовать внедрение зависимостей.
@Post('upload') @UseInterceptors(FileFieldsInterceptor | FileFieldsInterceptor([ { name: 'avatar', maxCount: 1 }, { name: 'background', maxCount: 1 }, ])) uploadFile(@UploadedFiles() files) { console.log(files); }
- непосредственный
@UseInterceptors()
Он используется в декораторе и действует на текущую маршрутизацию контроллера, не может передавать параметры, но можно использовать внедрение зависимостей.
@UseInterceptors(LoggingInterceptor | new LoggingInterceptor()) export class CatsController {}
- Глобальная регистрация с использованием встроенных методов экземпляра
useGlobalInterceptors
, который действует на весь проект.
const app = await NestFactory.create(ApplicationModule); app.useGlobalInterceptors(new LoggingInterceptor());
Перехватчики могут выполнять множество функций, таких как обработка кэша, преобразование данных ответа, преобразование захвата исключений, ошибка тайм-аута ответа и журнал ответов на запросы печати. Мы также будем использовать эту функцию в этом реальном боевом проекте.
Суммировать
Модули — это базовые блоки, разделенные бизнес-логикой, включая контроллеры и сервисы. Контроллер — это часть, которая обрабатывает данные запросов и ответов, а служба — это часть, которая обрабатывает фактическую бизнес-логику.
Промежуточное ПО — это уровень обработки данных перед обработчиком обработки маршрутизации. Его можно зарегистрировать только в модуле или глобально. Его можно использовать для промежуточного ПО для обработки журналов, промежуточного ПО для аутентификации пользователей и т. д. Промежуточное ПО такое же, как экспресс-промежуточное ПО, поэтому оно может получить доступ ко всему запросу и ответу.В этом контексте службы с областью действия модуля могут быть внедрены зависимостями. Глобальная регистрация может быть только чистой функцией или функцией более высокого порядка.
Конвейер — это обработка потока данных.Обработка данных выполняется после промежуточного ПО и перед обработкой маршрутизации.Его могут использовать классы,методы,параметры методов и глобальная регистрация в контроллере.Это может быть только чистая функция. Может выполнять проверку данных, преобразование данных и другую обработку данных.
Guard должен решить, может ли запрос достичь соответствующего обработчика маршрута, может ли он знать контекст выполнения текущего маршрута, может ли он использоваться классом, методом и глобальной регистрацией в контроллере, и может ли он использоваться в качестве роль охранника.
Перехватчик должен обрабатывать связанную логику до и после входа в контроллер.Он может знать контекст выполнения текущего маршрута.Он может использоваться классами, методами и глобальной регистрацией в контроллере.Он может вести журнал,обработку транзакций,обработку исключений. и формат данных ответа.
Фильтр предназначен для захвата информации об ошибке и возврата ответа клиенту. Его можно использовать для классов, методов и глобальной регистрации в контроллере, а также для настройки формата исключения ответа.
Промежуточное ПО, фильтры, конвейеры, охранники, перехватчики — вот несколько вещей, которые легко спутать. Что у них общего, так это промежуточный уровень абстракции, который подключен к контроллеру, но их обязанности различны.
Глобальные пайпы, охранники, фильтры и перехватчики слабо связаны с любыми модулями. Они не могут внедрить какие-либо службы, потому что они не принадлежат ни одному модулю. Вы можете использовать область контроллера, область метода или вспомогательную область, поддерживаемую только конвейерами, другие, кроме промежуточного программного обеспечения, которые являются областью модуля, являются областью контроллера и областью метода.
фокус: Они написаны в примере. Обратите внимание, что глобальные каналы, охранники, фильтры и перехватчики могут быть только новыми. Глобальное промежуточное ПО — это чистая функция. Глобальные каналы, охранники, фильтры и перехватчики нельзя использовать для внедрения зависимостей. Регистрация модуля промежуточного ПО также не может использовать new, но можно использовать внедрение зависимостей. Каналы, охранники, фильтры и перехватчики могут быть зарегистрированы локально с использованием новых имен и имен классов, за исключением каналов, в которые можно вводить зависимости. Перехватчики и охранники могут быть написаны как высокоуровневые методы для передачи параметров в целях настройки.
Защитные ограждения труб, фильтров и перехватчиков имеют свои особые обязанности. Интерцепторы и ограждения объединены с модулями, а трубы и фильтры работают вне зоны модуля. Задача конвейера заключается в проверке типа, структуры объекта или сопоставления данных с определенными условиями. Задача фильтра — ловить различные ошибки и возвращать их клиенту. Каналы — неподходящее место для выбора или вызова какой-либо службы из базы данных. Перехватчики, с другой стороны, не должны проверять схемы объектов или украшать данные. Если требуется перезапись, она должна быть вызвана вызовом службы из базы данных. Охранник решает, какие маршруты доступны, и берет на себя вашу ответственность за проверку.
Тогда вас должно больше всего беспокоить, в каком порядке они выполняются:
客户端请求 ---> 中间件 ---> 守卫 ---> 拦截器之前 ---> 管道 ---> 控制器处理并响应 ---> 拦截器之后 ---> 过滤器
Давайте посмотрим на 2 картинки,
Запрос возвращает результат ответа:
Запрос возвращает исключение ответа:
Hello World
Изучение языка и технологии начинается сHello World
В начале мы также идем от нуля кHello World
начать учитьсяNest
путешествие
Подготовьте необходимую среду разработки и инструменты
рекомендоватьnvm
справлятьсяnodejs
Версия, в соответствии с их компьютером, чтобы загрузить соответствующую версию.
- Подготовьте среду:Nodejsv8+ (текущая версия v10+, должна быть 8 или выше, высокая поддержка es2015)
- Подготовьте базу данных:mongodbv3+ (текущая версия v4+)
- Подготовьте базу данных:redisv3+ (текущая версия v3+)
- Редактор подготовки:vs codeПоследняя версия может быть (родная windows v1.26)
-
vs code
Рекомендуемые плагины: (другие плагины не обязательны)- Отладчик для Chrome -- отладка
- ejs -- подсветка файла ejs
- Украсить -- форматирование кода
- DotENV -- подсветка файла .env
- Jest - встроенная поддержка тестовой среды по умолчанию
- TSLint -- проверка синтаксиса ts
- Герой TypeScript — советы ТС
- vscode-icons -- icons
- Рекомендуется использовать несколько полезных инструментов:
- Почтальоны — артефакт тестирования API
- Robomongo — графический инструмент mongodb
- Redis Desktop Manager — графический инструмент Redis
- Cmder — артефакт командной строки Windows
Ресурсы, связанные с Nest
- Официальный сайт:nestjs.com
- Документация:docs.nestjs.com
- Китайский документ:docs.nestjs.cn
- Гитхаб:github.com/nestjs/nest
- Версия: Текущая стабильная версия v5.1.0
- Интерфейс командной строки:GitHub.com/nest JS / Гнездо ...
nest-cli
nest-cli
Являетсяnest
Леса проекта. Предоставляет нам модуль инициализации, который позволяет нам сделать это быстроHello World
Функция.
Установить
npm i -g @nestjs/cli
Общие команды:
новый (аббревиатура: n) для создания нового проекта
$ nest new my-awesome-app OR $ nest n my-awesome-app
generate (аббревиатура: g) для создания файлов
- class (аббревиатура: cl) класс
- контроллер (аббревиатура: со) контроллер
- декоратор (аббревиатура: д) декоратор
- исключение (аббревиатура: e) перехват исключения
- фильтр (аббревиатура: f) фильтр
- шлюз (аббревиатура: га) шлюз
- охрана (аббревиатура: гу) охранять
- перехватчик (аббревиатура: i) перехватчик
- промежуточное ПО (аббревиатура: mi) промежуточное ПО
- модуль (аббревиатура: мо) модуль
- труба (аббревиатура: пи) труба
- провайдер (аббревиатура: пр) поставщик
- сервис (аббревиатура: s) обслуживание
Создайте файл службы пользователей
$ nest generate service users OR $ nest g s users
Уведомление:
-
必须
в проекте根目录
Создано в (по умолчанию создано в src/). (Невозможно создать в текущей папке, иначе xxx/src/xxx будет создано автоматически. Tucao: это неразумно с Angular-cli) - нужно
优先
Создайте новый модуль, в противном случае созданные немодульные службы, контроллеры и т. д. будут автоматически внедрены и обновлены в модуль верхнего уровня.
информация (аббревиатура: i) информация о версии для печати
Распечатайте текущую систему и используйте версию основного модуля гнезда для официальной подачи.issues
| \ | | | | |_ |/ ___|/ __ \| | |_ _|
| \| | ___ ___ | |_ | |\ `--. | / \/| | | |
| . ` | / _ \/ __|| __| | | `--. \| | | | | |
| |\ || __/\__ \| |_ /\__/ //\__/ /| \__/\| |_____| |_
\_| \_/ \___||___/ \__|\____/ \____/ \____/\_____/\___/
[System Information]
OS Version : Windows 10
NodeJS Version : v8.11.1
NPM Version : 5.6.0
[Nest Information]
microservices version : 5.1.0
websockets version : 5.1.0
testing version : 5.1.0
common version : 5.1.0
core version : 5.1.0
Наконец, общая функциональность и
Angular-cli
Аналогичные, относительно простые и практичные функции. Создайте проект, сгенерируйте файлы, распечатайте информацию о версии.
встроенные функции
В настоящее времяNest.js
служба поддержкиexpress
а такжеfastify
, правильноfastify
Незнакомый, эта статья выбираетexpress
.
основной модуль
- @nestjs/common предоставляет множество декораторов, служб журналов и т. д.
- Основной модуль @nestjs/core отвечает за совместимость с базовыми фреймворками.
- @nestjs/microservices Поддержка микросервисов
- @nestjs/тестовый набор тестов
- Поддержка веб-сокетов @nestjs/websockets
дополнительный модуль
- @nestjs/typeorm еще не играл
- @nestjs/graphql еще не играл
- @nestjs/cqrs еще не играл
- Аутентификация @nestjs/passport (поддерживается в версии 5, не имеет обратной совместимости)
- @nestjs/swagger swagger UI API
- @nestjs/mongoose модуль мангуста
Уведомление: другие промежуточные модули, если они поддерживают
express
и то и другое можно использовать.
Построить проект
- Создать проект
nest-cnode
nest new nest-cnode
который представил вашdescription
, инициализированная версияversion
, авторauthor
, иpackage manager
выберитеnode_modules
Способ установкиnpm
илиyarn
.
- Начало проекта
cd nest-cnode // 启动命令 npm run start // 预览 npm run start:dev // 开发 npm run prestart:prod // 编译成js npm run start:prod // 生产 // 测试命令 npm run test // 单元测试 npm run test:cov // 单元测试+覆盖率生成 npm run test:e2e // E2E测试
- Введение в файл проекта
документ | иллюстрировать |
---|---|
node_modules | пакет нпм |
src | исходный код |
logs | журнал |
test | E2E-тестирование |
nodemon.json | конфигурация nodemon (начало запуска npm: запуск dev) |
package.json | управление пакетами npm |
README.md | файл описания |
tsconfig.json | Файл конфигурации Typescript (требуется для Typescript) |
tslint.json | Файл проверки стиля Typescript (требуется для Typescript) |
webpack.config.js | Горячее обновление (запуск запуска npm: запуск hmr) |
.env | конфигурационный файл |
код разработки
src
, сгенерированный код находится вdist
(упаковано и автоматически скомпилировано)
Открываем браузер и заходимhttp://localhost:3000
, вы должны увидеть страницу с надписьюHello World
Слово.
Наша последняя статья подошла к концу, смотрите наш следующий проект в действии--Nest-CNode