前言
作为一名程序员,离不来英语,软件官方文档,顶会期刊和论文,基本都是英语。 而且英语是一门形式化语言,比如被动,现在、过去、将来等即就是时态语态可以从 英语表达的形式上体现出来。比较容易能看出来描述的主体的逻辑关系,这对于学习 程序概念学习是有益处。恰好最近正在学,也是探索和尝试一种学习英语的方式。
Nest.js Overview
We'll take an overview of Nest.js
and
look at
the core concepts
- that you'll need to build a Nest.js application.
知识点
- take an overview
- 在这个语境下,
take
本身没有拿取的意思,而是与后面的名词组合来形成一个特定的意思 - 意思是:对某事或某物进行一个总体的、概括性的查看或审视
- 近似于
- have a general look
- get a broad perspective
- 近似于
take
可与多种名词搭配,形成各种意思- take a look: 看一下
- take a break: 休息一下
- take a shower: 洗个脸
- take a chance: 冒个险
- 在这个语境下,
- build a Nest.js application
- 构建一个...应用
Controllers
-
Controllers in Nest
- are responsible for
- handling
incoming requests
- and
returning responses
to the client.
-
Nest will route
incoming requests
tohandler functions
- in controller classes.
-
We use the
@Controller decorator
- to create a controller class.
翻译
Nest中的Controller
负责(resposible for)处理传入请求(incoming requests)并向客户端返回响应(returning responses)
Nest会将**传入请求(incoming request)**路由(route)到控制器类(Controller)中的处理函数(handler function)
我们使用@Controller()
装饰器(decorotor)来创建一个控制器类
示例
import { Controller, Get } from '@nestjs/common'
@Controller
export class EnteryController {
@Get
index(): Entry[] {
const entries: Entry[] = this.entriesService.findAll()
return entries
}
}
知识点
- Controllers in Nest
- 在...的...
-
responsible for
- phrasal verb
- 描述某事或某物的职责或功能
- handling incoming request and returning response
- 处理传入请求和返回响应
- route incoming requests
- 路由传入的请求
- 描述如何处理(route)请求
- handler function
- 处理函数
- controller classes
- 控制器类
@Controller
decorator- 控制器装饰器
Provider
Providers in Nest
are used tocreate
- services
- factories
- helper
- and more
- that can be injected into controllers
- and other providers
- using Nest's built-in dependency injection
The @Injectable() decorator
is used to create a provider class.
翻译
Nest中的provider
用于创建services
、factories
、helpers
这些services
、factories
、helpers
可以使用Nest内置的依赖注入到控制器和其他provider
中。
@Injectable()
装饰器用于创建a provider class
示例
我们博客应用中的AuthenticationService
事一个注入并使用UsersService
组件的提供程序
@Injectable
export class AuthenticationService {
constructor(private readonly userService: UserService) {}
async validateUser(payload: { email: string; password: string;}): Promise<boolean> {
const user = await this.userService.findOne({where: {email: payload.email }})
return !!user
}
}
知识点
-
are(be) used to
- 被用于...
- Providers in Nest
- 在...的...
-
used to create
- 表示用于创建或制造 某物
- used to create a provider class
- service, factories, helpers, and more
- 列举...
-
can be injected into
- 表示某物可以被注入到其他物体中
- Nest's built-in dependency injection
- built-in: ...内置...
- dependency injection: 依赖注入
Modules
A Nest.js application is organized into modules
.
Every Nest.js application will have a root module
-
In a small application
- this may be the only module.
-
In a larger application
- it makes sense to organize your application into multiple modules
- that split up your code into features and related capabilities
- it makes sense to organize your application into multiple modules
-
A module in Nest.js
-
is a class
- with a @Module() decorator.
-
is a class
-
The @Module() decorator
- takes a single object
- that describes module using the following properties.
- components
- controllers
- imports
- exports
- that describes module using the following properties.
- takes a single object
-
components
- The components to be instantiated
- that may be shared across this module
- and exported to be available to other modules
- The components to be instantiated
-
controllers
- The controllers that are created by this module
-
imports
- The list of modules to import that export components
- that are requires in this module
- The list of modules to import that export components
-
exports
- The list of components from this module
- to be made available to other modules
- The list of components from this module
-
The AppModule imports the modules
- that are needed for the application.
-
The root module in our application
- doesn't need to have any
exports
- since no other modulers import it
- doesn't need to have any
-
The root module also doesn't need to have any
exports
- since no other modules import it
-
The root module doesn't have any
conponents
orcontrollers
- as these are all organized within the sub-modules they are related to
-
Modules in Nest.js are singletons by default.
- This means that you can share the same instance of an exported component
翻译
每个Nest.js应用被组织成模块。
每个Nest.js都有一个根模块
在小型应用中,根模块可能是唯一的模块
在大型应用程序中,应用程序被组织成多个模块,这些模块将代码分割成不同的功能和相关能力
Nest.js中的模块是带有@Module()
装饰器的类。
-
@Module()
装饰器采用一个使用以下属性描述模块的对象components
:- 要实例化的组件可以跨 该模块共享并导出以供其他模块使用
controllers
:- 该模块创建的控制器(controllers)
imports
:- 要导入的模块列表,该模块中所需的组件
exports
:- 该模块可供其他模块使用的组件列表
-
The AppModule(the root module)
- 导入应用程序所需的模块(modules)
- 根模块不需要任何导出,因为没有其它模块导入它
- 也没有任何组件(
components
)或(controllers
),因为它们都组织在与其相关的子模块(sub-modules)中
示例
在根模块AppModule
中包含多个模块处理认证、评论、数据库访问、博客条目和用户
@Module({
components: [],
controllders: [],
imports: [
DatabaseModule,
AuthenticationModule.forRoot('jwt'),
UserModule,
EntryModule,
CommentModule,
UserGatewayModule,
CommentGatewayModule
],
exports: [],
})
export class AppModule implements NestModule {}
The EntryModule
@Module({
components: [entryProvider, EntryService],
controllers: [EnteryController],
imports: [],
exports: [EntryService]
})
export class EntryModule implements NestModule {}
知识点
-
is organized into
- 被动语态的动词短语
- 某物或某事被安排活组织成某种形式或结构
- 整体 be organized into 部分
-
to organize ... into ...
- to organize 整体 into 部分
-
split up
- phrasal verb
- 分割或分离成若干部分
- 将一群人、物品、任务分成几个小组或部分
- to split up 整体 into 部分
- The teacher decided to split up the students into small groups for the project
-
features and related capabilities
- 应用程序的功能和相关能力
-
module in Nest.js
- 在...的...
-
@Module
decorator -
take a single object
- 描述接受一个对象的动作
-
components to be instantiated
- 需要实例化的组件
-
available to other modulers
- 对其他模块可用
-
controller that are created by this module
- 控制器被模块创建
-
list of modules to import
- 需要导入的模块列表
-
list of components from this module
- 来自模块的组件列表
-
components that are required in this module
- 在此模块中所需的组件
-
since ...
- 因为
-
as ...
- 因为
Bootstrapping(自举)
- Every Nest.js application**
- needs to be bootstrapped.
- This is done by byusing the NestFactory
- to create the root module and calling the listen() method.
翻译
每个Nest.js应用都需要引导(bootstrapped),这是通过使用NestFactory
创建根模块并调用listen()
method.
示例代码
应用程序的入口是main.ts
,使用async/await
模式来创建AppModule
并调用listen()
import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
async function bootstrap() {
const app = await NestFactory.create(AppModule)
await app.listen(3000)
}
Middleware
-
Nest.js middleware is
- either a function
- or a class decorated
- with the
@Injectable decorator
- that implements
the NestMiddleware interface
- that implements
- with the
-
Middleware
- is called before route handlers
- These functions have access to the request and response object
- and they can make changes to the request and response object
-
One or more middleware function
- can be configured for a route
- and a middleware function
- can choose to pass the execution
- to the
next
middleware function - on the stack or to end the request-response cycle
- to the
- can choose to pass the execution
-
If a middleware function does not end the request-response cycle
- it must call
next()
- to pass control to the
next
middleware function- or to the request handler
- if it is the last function on the stack.
- or to the request handler
- to pass control to the
- Failing to do so will leave the request hanging
- it must call
-
Middleware is configured
- on routes
- in the
configure()
function of a Nest.js module.
翻译
Nest.js中间件是一个函数或一个使用@Injectable
装饰的类,它实现了NestMiddleware
接口。
中间件在路由处理程序之前被调用。
这些函数可以访问请求和响应对象,并对请求和响应对象进行更改
可以为路由配置一个或多个中间件函数,
并且中间件函数可以选择将执行传递给栈上的下一个中间件函数或结束请求-响应周期
如果中间件函数没有结束请求-响应周期
则它必须调用next()
将控制权传递给下一个中间件函数或请求处理程序(栈上最后一个中间件函数)
如果不是按照上面的方式执行,请求会被挂起。
中间件是在Nest.js
模块的configure()
函数中的路由上配置的。
示例
博客应用程序中的AuthenticationMiddleware
负责对访问博客的用户进行身份验证。
import { MiddlewareFunction } from '@nestjs/common'
import { HttpState } from '@nestjs/common'
import { Injectable } from '@nestjs/common'
import { NestMiddleware } from '@nestjs/common'
import * as passport from 'passport'
import { UserService } from '../../modules/user/user.service'
@Injectable
export class AuthenticationMiddleware implements NestMiddleware {
constructor(private userService: UserService) {}
async resolve(strategy: string): Promise<MiddlewareFunction> {
return async (req, res, next) => {
return passport.authenticate(strategy, async (...args: any[]) => {
const [, payploy, err] = args
if (err) {
return res
.status(HttpState.BAD_REQUEST)
.send('Unable to authenticate the user.')
}
const user = await this.userService.findOne({
where: { email: payload.email }
})
req.user = user
return next()
})(req, res, next)
}
}
}
-
如果身份验证失败
- 则会将400响应发送回客户端。
-
如果身份验证成功
- 则调用
next()
,请求将继续沿着中间件栈 向下传输 ,直到到达请求处理程序
- 则调用
AuthenticationMiddle
在AppModule
中配置,如下:
@Module({
imports: [
DatabaseModule,
AuthenticationMiddle.forRoot('jwt'),
UserModule,
EntryModule,
CommentModule,
UserGatewayModule,
CommentGatewayModule,
KeywordModule,
],
controllders: [],
providers: []
})
export class AppModule implements NestModule{
public configure(consumer: MiddlewareConsumer) {
//
const userControllerAuthenticateRoutes = [
{ path: '/user', method: RequestMethod.GET },
{ path: '/user/:id', method: RequestMethod.GET },
{ path: '/user/:id', method: RequestMethod.PUT },
{ path: '/user/:id', method: RequestMethod.DELETE },
]
//
consumer
.apply(AuthenticationMiddle)
.with(strategy)
.forRoutes(
...userControllerAuthenticateRoutes,
EnteryController, //
CommentModule //
)
}
}
- 可以将中间件应用于控制器上的所有路由
- 就像对
EntryController
和CommentController
所做的那样。
- 就像对
- 还可以按路径将中间件应用于特定路由
- 就像对
UserController
中的路由子集所做的那样
- 就像对
知识点
-
Nest.js middleware
- Nest中间件
-
decorated with
- phasal verb
- 使用装饰器装饰或标记某物
-
implements
- 实现某个接口
-
called befor
- phasal verb
- 在...之前被调用
-
route handlers
- 处理路由的函数
-
have access to
- phasal verb
- 能够访问或使用某物
-
request and response object
- 请求和响应对象
-
make change to
- phasal verb
- 对...做出更改
-
configured for a route
- phasal verb
- 配置路由
-
pass the execution to
- 将执行权传递给...
-
request-response cycle
- 请求和响应的过程或周期
-
call next()
- 调用next()函数
-
leave the request hanging
- 使请求悬挂或未完成
-
responsible for authenticating
- 负责验证
-
accessing the blog
- 访问博客
Guards
-
Guards
- are classes
- that are decorated with the
@Injectable()
decorator - and implements the
CanActivate interface
- that are decorated with the
- are classes
-
A guard
- is responsible for determining
- if a request should be handled by a route handler or route.
- is responsible for determining
-
Guards
- are executed
- after every middleware
- but before pipes
- are executed
-
Unlike middleware
- guards have access to the
ExecutionContext
object - so they know exectly what is going to evaluated
- guards have access to the
-
The
@UseGuards
decorator- is used to apply a guard to a route
- This decorator can be used on a controller class
- to apply the guard to all routes in that controller
翻译
Guard(守护程序)是使用@Injectable()
装饰器装饰并实现CanActivate
接口的类。
Guards负责确定请求应有程序处理器还是路由来处理。
Guards在每个中间件之后,但在管道之前执行。
-
与中间件不同的是
- Guards可以访问
ExecutionContext
对象 - 因此它们能准确知道将要求值的内容
- Guards可以访问
-
@UseGuards
装饰器- 被用于对路由(route)应用保护(guard)
- 以便将防护措施应用与该控制器中的所有路由
- 可以再控制器中的单个路由处理程序,如
UserController
所示
示例
在博客程序中,我们在UserController
中使用CheckLoggedInUserGuard
来只允许某个用户访问和访问自己的用户信息。
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'
import { Observable } from 'rxjs'
@Injectable()
export class CheckLoggedInUserGuard implements CanActivate {
canActivate(
context: ExecutionContext
): boolean | Promise<boolean> | Observable<boolean> {
const req = context.switchToHttp().getRequest()
return Number(req.params.userId) === req.user.id
}
}
@Controller('users')
export class UserController {
constructor(private readonly userService: UserSevice) {}
@Get(':userId')
@UseGuards(CheckLoggedInUserGuard)
show(@Param('userId') userId: number) {
const user: User = this.userService.findById(userId)
return user
}
}
知识点
-
decorated with
- 使用某种装饰器来装饰或标记
-
implement the CanActivate interface
- 实现...接口
-
responsible for determing
- 负责确定某事
-
handled by a route handler or route
- 由...处理
-
executed after every middleware
- 在...后执行
-
but before pipes
- 但在...之前
-
Unlike middleware
- 与...不同
-
have access to
- 可以访问或使用
-
know exactly what
- 确切地知道某事
-
is going to evaluated
- 即将被评估或执行
-
used to apply
- 用于应用或实施某物
-
a guard to a route
- 用于到路由的守卫
-
used on a controller class
- 用于...
-
apply the guard
- 应用或使用守卫
-
all routes in that controller
- 一个控制器中的所有路由
-
individual route handlers
- 单个路由处理函数
-
in a controller
- 在一个...内部
-
as seen in the UserController
- ...中看到的方式或示例
总结
-
Nest.js application
- one or more modules
-
Modules
- is organized into modules
- have a root module
- split up your code into feature and related capabilities
-
is a class
- decorated with
@Module
decorator
- decorated with
- describes module using properties
- components
- controllers
- imports
- exports
-
Controllers
-
are responsible for
- handing incoming requests
- and returning responses to client
- route
- incoming request to handler functions
-
are responsible for
-
Providers
-
are used to create
- services
- factories
- helpers
- can be injected into controllers
- other providers
- using DI
-
to create a provider class
- using
@Injectable()
decorator
- using
-
are used to create
-
Middleware
- is
- either a function
- or a class
- decorated with
Injectable()
- implements the
NestMiddleware
interface
- decorated with
- have access to
- request object
- and response object
- makes changes to
- request object
- and response object
- can be configured for a route
- in the
configure()
function - a middleware function
- choose to pass the execution
- to the next middleware function on stack
- call
next()
to pass control
- call
- or to end the request-response cycle
- to the next middleware function on stack
-
Guards
- are classes that
- are decorated with the
@Injectable
decorator - and implements the
CanActivate
interface - responsible for determining handled by
- a route handler
- or route
- ere executed
- after every middleware
- but before pips
|----------------| |------------| |-------| |-------| |---------------|
| | | | | | | | | |
| Client Request |---> | Middleware |---> | Guard |---> | Pipes | ---> | Route Handler |
| | | | | | | | | |
|----------------| |------------| |-------| |-------| |---------------|
| ^
| |
|------------------------------|