当前位置: 首页 > Web前端 > JavaScript

Nest.js快速启动API项目

时间:2023-03-27 10:32:17 JavaScript

最近开始了一个新项目。这个客户管理着一个庞大的任务和团队集群,不同流程适用的系统也不一样,比如salesforce,hubspots之类的。这次的新项目需要在其他两个平台之间做一些事情。目前只需要先封装其中一个API,所以我们选择使用NodeJS框架Nest.js来实现这组API。快速启动有3种方便的方式启动nestjs项目。使用nest自带的命令行工具npmi-g@nestjs/clinestnewproject-name。即使不使用这种方式,也推荐在node中全局安装命令行工具,这样可以方便的生成各种nestjs模块,比如controller和service之类的。直接使用starter工程这里还有一个启动的sampleproject,可以直接使用。gitclonehttps://github.com/nestjs/typescript-starter.gitmy-appcdmy-appnpminstallnpmrunstart而这个项目也自带Typescript。但是记得删除之前的git信息。使用npm安装需要的包npmi--save@nestjs/core@nestjs/commonrxjsreflect-metadata直接安装nestjs的core和common,rxjs和reflex-metadata也是需要的。这种方法比较干净,需要自己创建目录。不过也可以使用命令行创建控制器之类的,目录会自动创建。总的来说,nestjs与其他语言的API框架类似。很多东西可以自动生成或者不需要写,所以约定俗成的习惯很重要。尽量不要创建一些“独特”的结构,以免将来出现陷阱。创建控制器创建项目后,我创建了一个控制器。nest.js中的controller可以直接通过装饰器提供路由,所以没有路由文件进行配置。nestgcontroller项目nest.js的目录约定是按业务模块划分的,因为src目录下会出现一个projects目录,在这个目录下会生成一个projects.controller和伴随的单元测试。创建服务再创建服务,用于封装目标任务管理平台关于Projects的API。nestg服务项目创建的控制器和服务会自动添加到模块中。在每一代之后,您可以使用gitdiff来检查生成了哪些代码。很高兴知道。从'@nestjs/common'导入{Controller,Get,Req};从'express'导入{Request};从'src/interfaces/project.interface'导入{Project};从'./projects.import{ProjectsService}。service';@Controller('projects')exportclassProjectsController{constructor(privateprojectsService:ProjectsService){}@Get()findAll(@Req()request:Request):Project[]{returnthis.projectsService.findAll();}}从'@nestjs/common'导入{可注入};从'src/interfaces/project.interface'导入{项目};@Injectable()导出类ProjectsService{findAll():项目[]{返回[];}}结构和命名另外,我特别想说明的是,虽然我对controller和service使用了相同的名称,但并不代表它们是一一对应的。很多项目只是为了分层而划分,控制器和服务是一一对应的,其实是不正确的。分层是因为它们具有不同的含义。只有语义明确了,才能在思考的过程中更好的把握代码,才能更好的复用。层次在认知转变中发挥作用。如果你只是映射底层对象而不做任何改变,那么这个过程就没有意义。这里的service其实就是nestjs中的一种provider,provider的意思就是从各个地方提供数据或者其他的东西。我用的ProjectsService的意思是封装另外一个API,所以这个projects来自于目标任务管理平台的API名称。而controller的名字projects指的是我创建的API提供的数据是project,不过这里确实是同一个东西,所以名字也是一样的。假设当前业务逻辑需要从目标任务管理平台获取项目,然后筛选出两个不同特征的项目,一个叫task任务,需要分配给人员;另一种叫做笔记记录,只需标记即可。它们具有不同的属性。然后我将创建2个控制器,taskController和noteController,但它们都调用ProjectsService来获取具有不同过滤条件的数据。HTTP请求可以使用nest.js官方的Http模块HttpModule向其他API发送请求。这个模块其实就是封装了axios,所以使用起来非常方便。先安装相关模块。npmi--save@nestjs/axiosaxios并在app.module中导入。import{HttpModule}from'@nestjs/axios';...@Module({imports:[HttpModule],//importHttpmodulecontrollers:[ProjectsController],providers:[ProjectsService],})exportclassAppModule{}处理Axios对象在服务中可以通过这种方式处理http请求的返回值。从'@nestjs/axios'导入{HttpService};从'@nestjs/common'导入{Injectable};从'rxjs'导入{map,Observable};从'src/interfaces/project.interface'导入{Project};import{AxiosResponse}from'axios';@Injectable()exportclassProjectsService{constructor(privatereadonlyhttpService:HttpService){}findAll():Observable{returnthis.httpService.get('http://localhost:3000/api-json').pipe(map((axiosResponse:AxiosResponse)=>{returnaxiosResponse.data;}));}}因为axios会包裹一层,用data作为统一的key,所以需要map出来。这里的pipe和map方法都来自rxjs。rxjs的核心是Observable,它使用响应式编程封装回调和异步代码。所以你在这里看不到像promise或await/async这样的关键字。配置上面的请求,我只是用了一个本地的json接口来测试。要真正调用目标平台的API,还需要配置项,因为一些值包括APItoken等重要字符串需要放在环境变量中,不能直接放在git提交的代码中.所以需要添加config配置,安装nest.js的config包,其实就是封装了dotenv包。如果你经常使用nodejs,你应该熟悉这个包。npmi--save@nestjs/config在app.module中也引入了config模块。import{ConfigModule}from'@nestjs/config';importconfigurationfrom'./config/configuration';...imports:[HttpModule,ConfigModule.forRoot({load:[configuration],})],...这里使用forRoot因为模块是单例的。传入参数load可以加载config对象。导入的配置/配置文件是新创建的配置对象。exportdefault()=>({port:parseInt(process.env.PORT,10)||3000,runn:{url:process.env.RUNN_API_URL,token:process.env.RUNN_API_TOKEN}});我配置了端口、APIURL和令牌。那么你可能需要使用Typescript接口,你可以使用nest来生成文件。nestginterfacerunn-configexportinterfaceRunnConfig{url:stringtoken:string}这些配置项可以在服务中获取。从'@nestjs/config'导入{ConfigService};从'src/interfaces/runn-config.interface'导入{RunnConfig};...构造函数(私有只读httpService:HttpService,私有configService:ConfigService){}...constconfig=this.configService.get('runn');不要忘记在根目录中创建一个.env文件来填写配置值。另外,根据习惯,可以创建一个.env.sample文件,该文件只包含key,没有value。它类似于模板,由git提交管理。.env文件是gitignore。只保存在本地。需要在服务器上生成另一个副本。全局添加headersURL,但headers中需要添加Token。使用app.module中HttpModule的register方法配置其中封装的axios。但是由于token来自config,所以需要使用麻烦的registerAsync,注入config,在useFactory中使用。...导入:[HttpModule.registerAsync({导入:[ConfigModule],注入:[ConfigService],useFactory:(configService:ConfigService)=>({headers:{'Content-Type':'application/json',授权:'Bearer'+configService.get('runn.token')}})}),...],...所以我创建了一个基本的API框架,并请求了一个简单的目标任务管理系统API来获取数据。API文档另外,因为客户需要了解和测试我们的API,所以需要一个postmanAPI合集。我将使用Swagger,它是API文档的自动生成工具。它会根据框架中定义的API和参数自动生成一个页面,包括所有的API和参数说明,可以直接请求API。当然,这需要装饰师的协助。首先安装nestjs的swagger包。npmi--save@nestjs/swagger然后在main.ts中引入配置。从'@nestjs/core'导入{NestFactory};从'@nestjs/swagger'导入{SwaggerModule,DocumentBuilder};从'./app.module'导入{AppModule};异步函数bootstrap(){constapp=awaitNestFactory.create(AppModule);//swaggerconstconfig=newDocumentBuilder().setTitle('MyAPIs').setDescription('MyAPIsdocuments').setVersion('1.0').build();const文档=SwaggerModule.创建文件(应用程序,配置);SwaggerModule.setup('api',app,document);//swaggerendawaitapp.listen(3000);}bootstrap();那么你可以通过http://localhost:3000/api访问API文档页面。但是,目前所有API都将显示在defaultdefault标签下。官方例子中使用的addTag方法虽然可以添加标签,但是不能指定特定的API来放置标签。我需要通过装饰器来实现。只需在控制器方法上使用@ApiTags('Project'),该方法将被放置在Project标签下。除了API文档的页面形式。http://localhost:3000/api-json的JSON格式是最重要的,你可以直接在Postman中使用它来导入。原博客链接

猜你喜欢