В последнее время я использую Nestjs, и это дает людям ощущение весны Java. Nestjs может использовать все промежуточное программное обеспечение Express. Кроме того, он отлично поддерживает машинописный текст. Его можно использовать в сочетании с типом реляционного сопоставления базы данных для быстрого написать интерфейсный шлюз. В этой статье будут представлены функции и преимущества инфраструктуры узлов корпоративного уровня.
- Начните с внедрения зависимостей (DI)
- Декораторы и аннотации
- «Луковая модель» вnesjs
- Краткое изложение характеристик нестджей
Оригинальный текст в моем блоге:GitHub.com/fort и все…
Добро пожаловать в звезду и форк
1. Начиная с внедрения зависимостей (DI)
(1), внедрение зависимостей в angular
Начиная с angular1.x реализован режим внедрения зависимостей или инверсии управления.В angular1.x есть controller (контроллер), service (сервис) и module (модуль). Автор написал angular1.3 в течение некоторого периода времени в первые годы.Для иллюстрации приведены следующие примеры:
var myapp=angular.module('myapp',['ui.router']);
myapp.controller('test1',function($scope,$timeout){}
myapp.controller('test2',function($scope,$state){}
Выше приведен пример внедрения зависимостей в angular 1.3. Сначала определяется модуль с именем «myapp», а затем в модуле myapp определяется контроллер контроллера. Передайте управление модулем myapp функции myapp.controller. Конкретная схема внедрения зависимостей выглядит следующим образом:
То, как определяется модуль myapp, определяется двумя его контроллерами, и, кроме того, это зависит от таких служб, как область действия и тайм-аут в контроллере. Это обеспечивает внедрение зависимостей или инверсию управления.
(2), что такое внедрение зависимостей
Используйте пример, чтобы рассказать о том, что такое внедрение зависимостей.
class Cat{
}
class Tiger{
}
class Zoo{
constructor(){
this.tiger = new Tiger();
this.cat = new Cat();
}
}
В приведенном выше примере мы определяем Zoo и создаем экземпляры Cat и Tiger в его методе конструктора.В настоящее время, если мы хотим добавить переменную экземпляра в Zoo, например, для изменения самого класса Zoo, например, мы теперь хотим создайте класс Zoo Добавьте переменную экземпляра класса Fish:
class Fish{}
class Zoo{
constructor(){
this.tiger = new Tiger();
this.cat = new Cat();
this.fish = new Fish();
}
}
Кроме того, если мы хотим изменить переменные, переданные в классы Tiger и Cat при создании экземпляра в Zoo, мы также должны изменить их в классе Zoo. Эта повторяющаяся модификация сделает класс Zoo не универсальным, так что функции класса Zoo необходимо многократно тестировать.
Мы представляем передачу процедуры инстанцирования в качестве параметра классу Zoo:
class Zoo{
constructor(options){
this.options = options;
}
}
var zoo = new Zoo({
tiger: new Tiger(),
cat: new Cat(),
fish: new Fish()
})
Мы помещаем процесс усиления в параметр и передаем его конструктору Zoo, чтобы нам не приходилось многократно изменять код в классе Zoo. Это простой пример внедрения внедрения зависимостей. Более полно используя внедрение зависимостей, вы можете добавлять статические методы и статические свойства в класс Zoo:
class Zoo{
static animals = [];
constructor(options){
this.options = options;
this.init();
}
init(){
let _this = this;
animals.forEach(function(item){
item.call(_this,options);
})
}
static use(module){
animals.push([...module])
}
}
Zoo.use[Cat,Tiger,Fish];
var zoo = new Zoo(options);
Выше мы используем статический метод Zoo для внедрения модулей Cat, Tiger и Fish в класс Zoo и передаем конкретную реализацию Zoo модулям Cat, Tiger и Fish, а также параметр options, переданный в конструкторе. .
(3), внедрение зависимостей вnesjs
также относится к идее внедрения зависимостей в angular вnesjs, а также использует модуль, контроллер и сервис.
@Module({
imports:[otherModule],
providers:[SaveService],
controllers:[SaveController,SaveExtroController]
})
export class SaveModule {}
Выше описано, как определить модуль в nestjs.Вы можете внедрить другие модули в атрибут импорта, внедрить соответствующую службу, которую необходимо использовать в контроллере, в приватах и внедрить требуемый контроллер в контроллере.
2. Декораторы и аннотации
В nestjs отлично реализован машинописный текст, особенно широкое использование декораторов и аннотаций. Чтобы понять, что такое декораторы и аннотации, обратитесь к этой моей статье:Декораторы и аннотации в Typescript. Давайте посмотрим, насколько лаконичным будет написание бизнес-кода вnesjs после использования декораторов и аннотаций:
import { Controller, Get, Req, Res } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get()
findAll(@Req() req,@Res() res) {
return 'This action returns all cats';
}
}
В приведенном выше примере определены два контроллера, которые обрабатывают URL-адрес как "/cats". Для метода get этого маршрута определена функция findAll. Когда метод get используется для запроса /cats, функция findAll будет активно запущена.
Кроме того, в функции findAll, через параметры req и res запрос запрос и ответ на запрос можно использовать и непосредственно в теме. Например, мы получаем параметры запроса через req, а результат запроса возвращаем через res.send.
В-третьих, «луковичная модель» вnesjs
Вот краткий рассказ о том, как слои наслаиваются вnesjs, то есть как запрос обрабатывается слой за слоем после того, как он достигает сервера, пока на запрос не будет получен ответ и результат не будет возвращен клиенту.
На базе сервиса вnesjs, промежуточное ПО, фильтры исключений, пайпы, гвардии и перехватчики дополняются по уровню обработки, функции обработки обрабатываются послойно.
Логика на приведенном выше рисунке - это процесс многоуровневой обработки.Только после запросов многоуровневой обработки может быть достигнута функция обработки на стороне сервера, давайте представим конкретную роль послойной модели вnesjs.
(1), промежуточное ПО
Промежуточное ПО в nestjs точно такое же, как промежуточное ПО в express. Мало того, мы также можем напрямую использовать промежуточное программное обеспечение в экспрессе, например, в моем приложении мне нужно иметь дело с основным междоменным:
import * as cors from 'cors';
async function bootstrap() {
onst app = await NestFactory.create(/* 创建app的业务逻辑*/)
app.use(cors({
origin:'http://localhost:8080',
credentials:true
}));
await app.listen(3000)
}
bootstrap();
В приведенном выше коде мы можем использовать промежуточное ПО в ядре экспресс напрямую через app.use. Чтобы серверная часть поддерживала междоменное ядро и так далее.
Вдобавок к этому миддлвар сnesjs так же полностью сохраняет характеристики мидлвара в экспрессе:
- Принимать ответ и запрос в качестве параметров в промежуточном программном обеспечении и может изменять запрос объекта запроса и ответ объекта возврата результата.
- Можно закончить обработку запроса и напрямую вернуть результат запроса, то есть можно напрямую рес.отправить и так далее в middleware.
- После обработки промежуточного программного обеспечения, если результат запроса не возвращается, можно использовать следующий метод для передачи промежуточного программного обеспечения следующему промежуточному программному обеспечению для обработки.
В nestjs middleware точно такое же, как и в express.Помимо переиспользования express middleware, так же очень удобно использовать middleware для конкретного маршрута вnesjs:
class ApplicationModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('cats');
}
}
Вышеупомянутое предназначено для использования промежуточного программного обеспечения LoggerMiddleware, когда конкретный URL-адрес маршрута — /cats.
(2), Фильтры исключенийФильтры исключений
Фильтры исключений Фильтры исключений могут захватывать исключения, возникающие на любом этапе внутренней обработки, и после перехвата исключений возвращать обработанные результаты исключений клиенту (например, коды ошибок, сообщения об ошибках и т. д.).
Мы можем настроить фильтр исключений, и в этом фильтре исключений мы можем указать, какие исключения необходимо перехватывать и какие результаты должны быть возвращены для этих исключений, например, пример пользовательского фильтра, используемого для захвата исключений HttpException.
@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,
});
}
}
Мы видим, что хост реализует интерфейс ArgumentsHost, и информация в среде выполнения может быть получена в хосте, если это в http-запросе, то запрос и ответ могут быть получены, а также информация о клиенте и данных. получить в розетке.
Точно так же для фильтров исключений мы можем указать, чтобы они использовались в модуле или чтобы они использовались глобально и т. д.
(3), Трубопровод
Обычные пользователи каналов проверяют, соответствуют ли параметры в запросе требованиям, и выполняют функцию проверки параметров.
Например, для некоторых параметров в запросе нам нужно проверить или преобразовать тип параметра:
@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {
transform(value: string, metadata: ArgumentMetadata): number {
const val = parseInt(value, 10);
if (isNaN(val)) {
throw new BadRequestException('Validation failed');
}
return val;
}
}
ParseIntPipe с указанными выше параметрами может быть преобразован в десятичное целое число. Мы можем использовать:
@Get(':id')
async findOne(@Param('id', new ParseIntPipe()) id) {
return await this.catsService.findOne(id);
}
Для идентификатора параметра в запросе на получение вызовите новый метод ParseIntPipe, чтобы преобразовать параметр идентификатора в десятичное целое число.
(4), гвардейский караул
Охранники Охранники, роль которых заключается в том, чтобы определить, должен ли запрос быть принят и обработан функцией обработчика.Конечно, мы также можем обработать принятие запроса или нет в промежуточном программном обеспечении.По сравнению с промежуточным программным обеспечением, гвардейцы могут получить более подробную информацию о информация о контексте выполнения запроса.
Обычно защитный слой Guards располагается после промежуточного программного обеспечения, до того, как запрос будет официально обработан функцией обработчика.
Вот пример гвардейцев:
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return validateRequest(request);
}
}
Контекст здесь реализует интерфейс ExecutionContext, который содержит обширную информацию о контексте выполнения.
export interface ArgumentsHost {
getArgs<T extends Array<any> = any[]>(): T;
getArgByIndex<T = any>(index: number): T;
switchToRpc(): RpcArgumentsHost;
switchToHttp(): HttpArgumentsHost;
switchToWs(): WsArgumentsHost;
}
export interface ExecutionContext extends ArgumentsHost {
getClass<T = any>(): Type<T>;
getHandler(): Function;
}
В дополнение к информации в ArgumentsHost ExecutionContext также содержит пользователя getClass для получения контроллера для обработки маршрута. А getClass используется для получения и возврата функции обработки для фоновой обработки указанного маршрута.
Для обработчика Guards, если он возвращает true, запрос будет обработан нормально, если он возвращает false, то запрос выдает исключение.
(5), перехватчик перехватчик
Перехватчик может быть привязан к каждой функции, которую необходимо выполнить, и перехватчик будет запускаться до или после выполнения функции. Вы можете преобразовать результат, возвращаемый после выполнения функции, и т. д.
в целом; вкратце:
Перехватчики могут запускаться до или после выполнения функции, если они запускаются после выполнения функции, они могут перехватывать возвращаемый результат выполнения функции, изменять параметры и т. д.
Возьмем другой пример обработки тайм-аута:
@Injectable()
export class TimeoutInterceptor implements NestInterceptor{
intercept(
context:ExecutionContext,
call$:Observable<any>
):Observable<any>{
return call$.pipe(timeout(5000));
}
}
Этот перехватчик может быть определен на контроллере и может обрабатывать запросы на тайм-аут.
В-четвертых, характеристики сводки о нестежях
Наконец, подведите итог преимуществам и недостаткамnesjs.
Преимущества нестджей:
-
Идеальная поддержка машинописного текста, поэтому вы можете использовать все более процветающие экологические инструменты ts.
-
Совместимость с промежуточным программным обеспечением Express, поскольку Express является самой ранней облегченной серверной структурой узла, Nestjs может использовать все промежуточное ПО Express, чтобы сделать его экологию идеальной.
-
Послойная обработка может в определенной степени ограничивать код, например, когда использовать промежуточное ПО, когда использовать средства защиты и т. д.
-
Идея внедрения зависимостей и модульности обеспечивает полную связь MVC, делая структуру кода понятной и простой в обслуживании.М здесь заключается в том, что уровень данных может быть введен в виде модулей.Например, модули могут быть введены в модуль через сущность typeorm.
-
Идеальная поддержка rxjs