近上了一个新项目,这个客户管理一个庞大的任务和团队集群,而不同流程所适用的系统也不太一样,比如salesforce,hubspots之类的。这次的新项目需要在另外两个平台之间做一些事情。目前只需要先封装其中之一的API,因此我们选定使用NodeJS的框架Nest.js来实现这套API。
开启nestjs项目有3种便捷的方式。
使用nest自带的命令行工具
npm i -g @nestjs/cli
nest new project-name
即使不使用这种方式,也建议在node全局安装命令行工具,这样可以方便的生成各种nestjs的模块,比如controller和service之类的。
直接使用starter项目
这里还有一个用于启动的样例项目,可以直接使用。
git clone https://github.com/nestjs/typescript-starter.git my-app
cd my-app
npm install
npm run start
而且这个项目还附带了Typescript。不过要记得把之前的git信息删掉。
用npm安装所需的包
npm i --save @nestjs/core @nestjs/common rxjs reflect-metadata
直接安装nestjs的core和common就可以,rxjs和reflext-metadata也是必需的。这种方式比较干净,目录什么的需要自己创建。不过也可以使用命令行创建controller之类的,目录会自动创建好。
总的来说,nestjs和其他语言API框架类似,很多东西可以自动生成或者无需编写,所以约定的习惯非常重要,尽量不要创建一些“独特”的结构,避免以后踩坑。
创建好项目之后,我创建了一个controller,nest.js中controller可以通过修饰器直接提供路由,因此没有一个route之类的文件用于配置。
nest g controller projects
nest.js的目录约定是按业务模块划分,因为src目录中会出现一个projects的目录,该目录下会生成一个projects.controller,以及附带的单元测试。
接着创建service,用于封装目标任务管理平台关于Projects的API。
nest g service projects
创建controller和service都会自动加入到module里,可以在每次生成后用git diff查看一下生成了哪些代码,也好心理有数。
import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';
import { Project } from 'src/interfaces/project.interface';
import { ProjectsService } from './projects.service';
@Controller('projects')
export class ProjectsController {
constructor(private projectsService: ProjectsService) {}
@Get()
findAll(@Req() request: Request): Project[] {
return this.projectsService.findAll();
}
}
import { Injectable } from '@nestjs/common';
import { Project } from 'src/interfaces/project.interface';
@Injectable()
export class ProjectsService {
findAll(): Project[] {
return [];
}
}
另外我特别想说明一下的是,虽然我为controller和service都使用了相同的名称,但并不是说他们是一一对应的。很多项目只是为了分层而分,controller和service都是一一对应的,其实并不正确。分层是因为它们拥有不同的意义,只有明确语义,才能在思维的过程中更好的掌握代码,也可以更好的复用,层次起到的是一种认知转换的作用。如果只是把底层的对象毫无变化的映射出来,那这个过程是毫无意义的。
这里的service在nestjs中其实是provider的一种,而provider的意义则是从各种不同的地方提供数据或其他东西。我使用的ProjectsService意义在于封装另一个API,所以这个projects来源于目标任务管理平台的API名称。而controller的名称projects指的是我创建的API所要提供的数据是project,只不过它们在这里确实是同一个东西,所以名称也一样。
假设,现在的业务逻辑是需要从目标任务管理平台获取projects,之后过滤出两种不同特性的projects,一种叫task任务,需要分配给人员;另一种叫note记录,只是标记一下。它们拥有不同的特性。那么我就会创建2个controller,taskController和noteController,但是它们都调用ProjectsService去使用不同的过滤条件获取数据。
使用nest.js官方的Http模块HttpModule就可以向其他API发出请求。该模块其实也是封装的Axios,所以用起来很方便。先安装相关模块。
npm i --save @nestjs/axios axios
然后在app.module中引入。
import { HttpModule } from '@nestjs/axios';
...
@Module({
imports: [HttpModule], // 引入Http模块
controllers: [ProjectsController],
providers: [ProjectsService],
})
export class AppModule {}
处理Axios对象
在service中可以这样处理http请求的返回值。
import { HttpService } from '@nestjs/axios';
import { Injectable } from '@nestjs/common';
import { map, Observable } from 'rxjs';
import { Project } from 'src/interfaces/project.interface';
import { AxiosResponse } from 'axios';
@Injectable()
export class ProjectsService {
constructor(
private readonly httpService: HttpService
) {}
findAll(): Observable<Project[]> {
return this.httpService.get('http://localhost:3000/api-json').pipe(
map((axiosResponse: AxiosResponse) => {
return axiosResponse.data;
})
);
}
}
因为Axios会包裹一层,用data作为统一的key,所以需要map出来。这里的pipe和map方法都是来自rxjs。rxjs的核心就是Observable,使用响应式编程的方式,封装了回调和异步方式的代码。因此这里你看不到promise或者await/async之类的关键字。
上面的请求,我只是使用了一个本地的json接口用于测试。要真正的调用目标平台的API,还需要配置项,因为包括API token这种重要字符串的一些值,需要放在环境变量中,不能直接放在代码被git提交。
所以我需要加上config的配置,安装nest.js的config包,它封装的其实是dotenv包,经常使用nodejs的话,应该会很熟悉这个包。
npm i --save @nestjs/config
同样在app.module中引入config模块。
import { ConfigModule } from '@nestjs/config';
import configuration from './config/configuration';
...
imports: [
HttpModule,
ConfigModule.forRoot({
load: [configuration],
})
],
...
这里使用forRoot是因为该模块是单例模式的。而传入的参数load可以把config对象载入。
引入的config/configuration文件是新创建的配置对象。
export default () => ({
port: parseInt(process.env.PORT, 10) || 3000,
runn: {
url: process.env.RUNN_API_URL,
token: process.env.RUNN_API_TOKEN
}
});
我配置了端口,以及API的URL和Token。
然后可能需要用到Typescript的接口,可以使用nest生成文件。
nest g interface runn-config
export interface RunnConfig {
url: string
token: string
}
在service中就可以获取这些配置项。
import { ConfigService } from '@nestjs/config';
import { RunnConfig } from 'src/interfaces/runn-config.interface';
...
constructor(
private readonly httpService: HttpService,
private configService: ConfigService
) {}
...
const config = this.configService.get<RunnConfig>('runn');
不要忘记在根目录下创建.env文件填入配置的值。另外按习惯,可以创建.env.sample文件,只包含key,没有值,类似模板,被git提交管理。而.env文件则被gitignore。只在本地保留。在服务器上需要另外生成一份。
URL使用了,但Token需要在headers中添加。在app.module中使用HttpModule的register方法就可以配置其中封装的Axios。不过由于token来自config,所以需要用比较麻烦的registerAsync,注入config后,在useFactory中使用。
...
imports: [
HttpModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + configService.get('runn.token')
}
})
}),
...
],
...
这样我就创建了一个基本API框架,并请求了一个简单的目标任务管理系统的API获取数据。
另外,由于客户需要了解和测试我们的API,所以需要一个postman的api集合。我准备使用Swagger,这是一个API文档的自动生成工具,它会根据框架中定义的API和参数,自动生成一个页面,包含所有的API和参数说明,以及可以直接请求该API。当然这需要修饰器的辅助。先安装nestjs的swagger包。
npm i --save @nestjs/swagger
然后在main.ts中引入并配置。
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// swagger
const config = new DocumentBuilder()
.setTitle('My APIs')
.setDescription('My APIs documents')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
// swagger end
await app.listen(3000);
}
bootstrap();
然后就可以通过http://localhost:3000/api访问该API文档页面。不过目前所有API都会出现在default默认标签下。官方示例中使用的addTag方法虽然可以添加一个标签,但并不能指定某些API放入该标签。我需要通过修饰器实现。
在controller的方法上使用@ApiTags('Project')即可,该方法会被放置在Project标签下。
除了API文档的页面形式。http://localhost:3000/api-json的JSON格式才是最重要的,可以使用它在Postman中直接导入。
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/JjDmwive2jC_W6g2OmfDQA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。