likes
comments
collection
share

30分钟入门NestJS,带你掌握大前端全栈开发。

作者站长头像
站长
· 阅读数 13

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.tse2e测试,端对端测试文件,测试流程和功能使用
test/jest-e2e.jsonjest测试文件,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,具有强类型检查和类型安全。
  • 可以使用装饰器来定义控制器和服务,使代码更加简洁。
  • 应用程序调试更容易。
  • 拥有良好的文档和社区支持。

学习文档

Nest官网

转载自:https://juejin.cn/post/7183999735236132925
评论
请登录