30分钟入门NestJS,带你掌握大前端全栈开发。
NestJS介绍
NestJS
是一个基于 TypeScript 的服务器端应用程序框架。
它提供了一组丰富的工具和模块来帮助开发人员构建高效、可扩展的服务器端应用程序。
NestJS
的核心思想是使用模块化的方法来构建应用程序。
应用程序可以由多个模块组成,每个模块都可以包含控制器、服务、管道、拦截器和其他类型的元素。
这些元素可以通过依赖注入系统自动注册,并可以在整个应用程序中共享。
NestJS
还提供了一组丰富的工具和模块,可用于构建各种类型的服务器端应用程序,包括 RESTful API、GraphQL API、WebSocket 服务器等。
它还提供了对主流数据库和身份验证系统的集成,可以帮助开发人员快速构建应用程序。
总的来说,NestJS
是一个功能丰富、易于使用的服务器端应用程序框架,可帮助开发人员快速构建高效、可扩展的服务器端应用程序。
NestJS的优势
NestJS
是一个基于 TypeScript 的服务器端应用程序框架。
它提供了一组丰富的工具和模块来帮助开发人员构建高效、可扩展的服务器端应用程序。
NestJS
的一些优势包括:
- 构建在现代 JavaScript 栈之上,因此使用了最新的 JavaScript 技术。
- 基于 Angular 的架构和语法,提供了强大的模块化系统和依赖注入功能。
- 基于 TypeScript,提供了强类型和静态类型检查。
- 提供了丰富的工具和模块,可用于构建各种类型的服务器端应用程序,包括 RESTful API、GraphQL API、WebSocket 服务器等。
- 提供了一组可扩展的构建块,可用于快速构建应用程序。
- 提供了与主流数据库和身份验证系统的集成。
NestJS的目录结构说明
名称 | 路径 | 描述 |
---|---|---|
dist[目录] | dist/ | 编译后的目录,用于预览项目 |
node_modules[目录] | node_modules/ | 项目使用的包目录,开发使用和上线使用的都在里边 |
src[目录] | src/ | 源文件/代码,程序员主要编写的目录 |
src/app.controller.spec.ts | 对于基本控制器的单元测试样例 | |
src/app.controller.ts | 控制器文件,可以简单理解为路由文件 | |
src/app.module.ts | 模块文件,在NestJS世界里主要操作的就是模块 | |
src/app.service.ts | 服务文件,提供的服务文件,业务逻辑编写在这里 | |
src/app.main.ts | 项目的入口文件,里边包括项目的主模块和监听端口号 | |
test[目录] | test/ | 测试文件目录,对项目测试时使用的目录 |
test/app.e2e-spec.ts | e2e测试,端对端测试文件,测试流程和功能使用 | |
test/jest-e2e.json | jest测试文件,jset是一款简介的JavaScript测试框架 | |
.eslintrc.js | ./ | ESlint的配置文件 |
.gitignore | ./ | git的配置文件,用于控制哪些文件不受Git管理 |
.prettierrc | ./ | prettier配置文件,用于美化/格式化代码的 |
nest-cli.json | ./ | 整个项目的配置文件,这个需要根据项目进行不同的配置 |
package-lock.json | ./ | 防止由于包不同,导致项目无法启动的配置文件,固定包版本 |
package.json | ./ | 项目依赖包管理文件和Script文件,比如如何启动项目的命令 |
README.md | ./ | 对项目的描述文件,markdown语法 |
tsconfig.build.json | ./ | TypeScript语法构建时的配置文件 |
tsconfig.json | ./ | TypeScript的配置文件,控制TypeScript编译器的一些行为 |
NestJS的约束
解释
- [filename]指在使用框架时创建的模块名称,NestJS允许命令行创建
nest g controller article --no-spec
。
框架的文件约束
- 每个模块最少有三种文件组合:module、server、controller。
[filename].controller.ts 文件
[filename].controller.ts 文件定义了控制器。控制器是一种特殊的组件,它负责处理 HTTP 请求并返回响应。 在控制器中,你可以使用 @Controller 装饰器来声明控制器,并指定一个路径前缀。例如:
@Controller('/users')
export class UsersController {
// ...
};
在这里,UsersController 控制器的路径前缀是 '/users'。这意味着所有在 UsersController 中定义的路由都将以 '/users' 为前缀。
在控制器中,你可以使用 @Get、@Post、@Put 等装饰器来声明路由处理程序。 例如:
@Get('/')
findAll(): string {
return 'This action returns all users';
}
@Get('/:id')
findOne(@Param('id') id: string): string {
return `This action returns a #${id} user`;
}
在这里,findAll 和 findOne 函数分别声明了两个路由处理程序。 findAll 函数处理的是 GET 请求 '/users',findOne 函数处理的是 GET 请求 '/users/:id'。
总的来说,controller.ts
文件用于定义控制器,控制器负责处理 HTTP 请求并返回响应。
[filename].module.ts 文件
[filename].module.ts 文件定义了一个模块,该模块是用于组织应用程序中的许多功能的。模块可以包含控制器、服务和其他模块,以及与其他模块一起使用的公共组件。
在模块中,你可以使用@Module装饰器来声明模块,并指定该模块中应包含哪些元素。 例如:
@Module({
controllers: [AppController],
providers: [AppService],
imports: [AnotherModule]
});
export class AppModule {};
在这里,AppModule 模块包含 AppController 控制器、AppService 服务和 AnotherModule 模块。控制器和服务将被注册到该模块,并可以在模块中使用。 AnotherModule 会被导入到 AppModule 中,并可以在 AppModule 中使用它所提供的功能。
[filename].server.ts 文件
[filename].server.ts 文件定义了服务。 服务是一种特殊的组件,它负责封装与业务逻辑相关的代码。
你可以使用 @Injectable 装饰器来声明服务,并使用 @Inject 装饰器来注入其他服务或依赖。 例如:
@Injectable();
export class UsersService {
private readonly users: User[] = [];
constructor(@Inject(CACHE_MANAGER) private cacheManager: CacheManager) {}
findAll(): User[] {
return this.users;
}
create(user: User) {
this.users.push(user);
}
};
在这里,UsersService 服务使用 @Injectable 装饰器声明,并使用 @Inject 装饰器注入了一个名为 CACHE_MANAGER 的依赖。 UsersService 中的 findAll 和 create 函数分别实现了查找所有用户和创建新用户的功能。 [filename].service.ts 文件用于定义服务,服务负责封装与业务逻辑相关的代码。
路由的控制
RESTful API
RESTful API 是一种常用的 API 设计风格,它遵循 REST(Representational State Transfer)设计原则。在 Nest.js 中,你可以使用以下方法来实现 RESTful API:
- HTTP GET 请求:用于查询资源。例如:'/users' 用于查询所有用户。
- HTTP POST 请求:用于创建新资源。例如:'/users' 用于创建新用户。
- HTTP PUT 请求:用于更新已有资源。例如:'/users/1' 用于更新 id 为 1 的用户。
- HTTP DELETE 请求:用于删除已有资源。例如:'/users/1' 用于删除 id 为 1 的用户。
在 Nest.js 中,你可以使用 @Get、@Post、@Put、@Delete 等装饰器来声明路由处理程序,并使用 app.route().get()、app.route().post() 等方法来实现 RESTful API。 例如:
import { Controller, Get, Post, Put, Delete } from '@nestjs/common';
@Controller('/users')
export class UsersController {
@Get()
findAll(): string {
return 'This action returns all users';
}
@Get(':id')
findOne(@Param('id') id: string): string {
return `This action returns a #${id} user`;
}
@Post()
create(): string {
return 'This action addsa new user';
}
@Put(':id')
update(@Param('id') id: string): string {
return `This action updates a #${id} user`;
}
@Delete(':id') remove(@Param('id') id: string): string {
return `This action removes a #${id} user`; }
}
}
UsersController 控制器使用 @Get、@Post、@Put、@Delete 装饰器声明了若干个路由处理程序。
分别对应了 HTTP GET、POST、PUT 和 DELETE 请求。
你也可以使用 app.route().get()、app.route().post() 等方法来实现 RESTful API。
在 NestJS
中,你可以使用 @Get、@Post、@Put、@Delete 装饰器或 app.route().get()、app.route().post() 等方法来实现 RESTful API。
如何在NestJS中如何增加一个顶层路由?
你可以使用 @Controller 装饰器来声明控制器,并指定一个路径前缀。 这个路径前缀就是你要增加的顶层路由。
例如,假设你想在应用程序中增加一个名为 '/api'
的顶层路由。
你可以在 controller.ts 文件中声明一个 UsersController 控制器,并指定 '/api' 为路径前缀:
@Controller('/api')
export class UsersController {
// ...
}
在这里,UsersController 控制器的路径前缀是 '/api'
。
这意味着所有在 UsersController 中定义的路由都将以 '/api'
为前缀。
例如,如果你在 UsersController 中定义了一个名为 '/'
的路由处理程序,那么实际上处理的路由就是 '/api'
。
除了使用 @Controller 装饰器声明控制器之外,你还可以使用 app.route() 方法来增加顶层路由。 例如:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.route('/api').get((req, res) => res.send('Hello World!'));
await app.listen(3000);
}
bootstrap();
这段代码会为 '/api'
路由增加一个路由处理程序,处理来自 GET 请求的请求并返回 "Hello World!"。
app.route('/api').get((req, res) => res.send('Hello World!'));
你也可以使用 app.route().post() 等方法来为路由增加处理其他 HTTP 方法的路由处理程序。 例如:
app.route('/api').post((req, res) => res.send('POST request received'));
这段代码会为 '/api'
路由增加一个路由处理程序,处理来自 POST 请求的请求并返回 "POST request received"。
你可以使用 @Controller 装饰器声明控制器或使用 app.route() 方法来增加顶层路由。 一旦增加了路由,你就可以使用 app.route().get()、app.route().post() 等方法来为路由增加路由处理程序。
数据库操作
GraphQL API
GraphQL API 是一种常用的 API 设计风格,它允许客户端自定义要查询的数据,而服务器端则根据客户端的查询来返回数据。
在 NestJS
中,你可以使用以下方法来实现 GraphQL API:
- GraphQL 请求:使用 GraphQL 语言描述要查询的数据。例如:
query { users { name } }
用于查询所有用户的名字。 - GraphQL 查询:使用 @Query 装饰器声明查询处理程序。例如:
@Query(() => [User])
users(): User[] {
return this.usersService.findAll();
}
在这里,users 查询处理程序使用 @Query 装饰器声明,并返回所有用户的信息。
- GraphQL 变更:使用 @Mutation 装饰器声明变更处理程序。例如:
@Mutation(() => User)
createUser(@Args('createUserInput') args: CreateUserInput): User {
return this.usersService.create(args);
}
在这里,createUser 变更处理程序使用 @Mutation 装饰器声明,并创建新用户。
总的来说,在 Nest.js 中,你可以使用 GraphQL 请求、@Query 装饰器声明的查询处理程序和 @Mutation 装饰器声明的变更处理程序来实现 GraphQL API。
你还可以使用 GraphQL 语言定义数据类型,并使用 @ObjectType 装饰器声明数据类型。 例如:
@ObjectType()
export class User {
@Field()
id: string;
@Field()
name: string;
@Field()
email: string;
}
在这里,User 类型使用 @ObjectType 装饰器声明,并使用 @Field 装饰器声明 id、name 和 email 字段。
你还可以使用 @InputType 装饰器声明输入类型,用于传递变更处理程序的参数。例如:
@InputType()
export class CreateUserInput {
@Field()
name: string;
@Field()
email: string;
}
在这里,CreateUserInput 输入类型使用 @InputType 装饰器声明,并使用 @Field 装饰器声明 name 和 email 字段。
你还可以使用 @FieldResolver 装饰器声明字段解析器,用于提供动态计算字段的值。例如:
@FieldResolver()
fullName(@Root() user: User): string {
return `${user.firstName} ${user.lastName}`;
}
在这里,fullName 字段解析器使用 @FieldResolver 装饰器声明,并根据 user 对象的 firstName 和 lastName 字段动态计算出完整的名字。
总的来说,在 Nest.js 中,你可以使用 GraphQL 请求、@Query 装饰器声明的查询处理程序、@Mutation 装饰器声明的变更处理程序、@ObjectType 装饰器声明的数据类型、@InputType 装饰器声明的输入类型和 @FieldResolver 装饰器声明的字段解析器来实现 GraphQL API。
需要注意的是,你需要在模块中配置 GraphQL API,并使用 GraphQL 模块提供的方法注册数据类型、查询处理程序、变更处理程序和字段解析器。例如:
@Module({
imports: [GraphQLModule.forRoot({
typePaths: ['./**/*.graphql'],
resolvers: {
User: {
fullName: (user: User) => `${user.firstName} ${user.lastName}`,
},
},
})],
})
export class AppModule {}
在这里,GraphQLModule.forRoot() 方法用于配置 GraphQL API,并使用 typePaths 参数指定 GraphQL 语言文件的路径,使用 resolvers 参数注册字段解析器。
你还可以使用 @Module 装饰器声明模块,并在模块中使用 GraphQLModule.forFeature() 方法注册数据类型、查询处理程序和变更处理程序。
@Module({
imports: [GraphQLModule.forFeature([UsersResolver])],
})
export class UsersModule {};
在这里,UsersModule 模块使用 GraphQLModule.forFeature() 方法注册 UsersResolver 查询处理程序和变更处理程序。
总的来说,在 Nest.js 中,你可以使用 GraphQLModule.forRoot() 方法配置 GraphQL API,并使用 GraphQLModule.forFeature() 方法在模块中注册数据类型、查询处理程序和变更处理程序,来实现 GraphQL API。
在 Nest.js 中,你还可以使用 GraphQL 模块提供的 GraphQLFactory 类来创建 GraphQL 服务器。
const app = await NestFactory.create(AppModule);
const graphQLFactory = app.get(GraphQLFactory);
const schema = await graphQLFactory.createSchema();
app.use('/graphql', graphqlHTTP({ schema }));
在这里,GraphQLFactory 类的 createSchema() 方法用于创建 GraphQL 模式,然后使用 app.use() 方法在应用中注册 GraphQL 路由。
总的来说,在 NestJS
中,你可以使用 GraphQLModule 模块、GraphQL 语言、@Query、@Mutation、@ObjectType、@InputType 和 @FieldResolver 装饰器以及 GraphQLFactory 类来实现 GraphQL API。
需要注意的是,你需要在 Nest.js 应用的根模块中配置 GraphQLModule 模块,并在模块中注册数据类型、查询处理程序、变更处理程序和字段解析器。 你还可以在模块中使用 GraphQLFactory 类来创建 GraphQL 服务器,并使用 app.use() 方法在应用中注册 GraphQL 路由。
你还可以使用 GraphQL 语言定义数据类型和查询处理程序、变更处理程序和字段解析器。
type Query {
users: [User]
}
type Mutation {
createUser(name: String, email: String): User
}
type User {
id: ID!
name: String!
email: String!
fullName: String
}
type User {
id: ID!
firstName: String!
lastName: String!
fullName: String
}
type Query {
user(id: ID!): User
}
type Mutation {
updateUser(id: ID!, name: String, email: String): User
deleteUser(id: ID!): User
}
在这里,我们定义了 Query 和 Mutation 数据类型,分别用于查询处理程序和变更处理程序。 我们还定义了 User 数据类型,并使用 @ObjectType 装饰器声明。
在 Nest.js 中,你可以使用 GraphQLModule 模块、GraphQL 语言、@Query、@Mutation、@ObjectType、@InputType 和 @FieldResolver 装饰器以及 GraphQLFactory 类来实现 GraphQL API。 你需要在应用的根模块中配置 GraphQLModule 模块,并在模块中注册数据类型、查询处理程序、变更处理程序和字段解析器。你还可以使用 GraphQL 语言定义数据类型和处理程序,并使用 @ObjectType 装饰器声明数据类型。
需要注意的是,在使用 GraphQL API 时,你需要注意数据类型、查询处理程序和变更处理程序之间的关系,以及数据类型的字段、输入类型和字段解析器之间的关系。 你还需要注意 GraphQL 请求的格式和参数,以及 GraphQL 响应的格式和内容。
在 NestJS
中使用 GraphQL API 需要注意数据类型、处理程序、字段、输入类型和字段解析器之间的关系,以及 GraphQL 请求和响应的格式和参数。
总结
NestJS
是一个基于TypeScript的后端框架,它自身有很多的优势。
- 基于模块化设计,使代码更加组织清晰。
- 基于TypeScript,具有强类型检查和类型安全。
- 可以使用装饰器来定义控制器和服务,使代码更加简洁。
- 应用程序调试更容易。
- 拥有良好的文档和社区支持。
学习文档
转载自:https://juejin.cn/post/7183999735236132925