很多时候我们会需要去串接第三方的 API,例如:绿界科技的金流服务、Binance 的 API 等,这时候如果第三方没有提供相关的 SDK 让我们使用的话,就必须自己用 HTTP Request 去存取对应的资料,早期的 node.js 开发人员可能会使用 request 来实作,但该函式库现在已经被弃用了,取而代之的是 node-fetch 或 axios,而 Nest 内建了 HTTP Module,它是基於 axios
进行包装的模组,让 Nest 开发人员不必为使用哪个套件烦恼,HTTP Module 即装即用!
HTTP Module 的 class
名称为 HttpModule
,它汇出了一个 HttpService
的 Service,其提供 axios
的方法来处理 HTTP 请求,并且使用 Observable
的形式。
注意:想要知道
axios
具体有哪些方法可以查看官方说明。
以 app.module.ts
为例,将 HttpModule
导入:
import { HttpModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [HttpModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
这里我们借用一下 JSONPlaceholder 做为第三方 API,并使用 todos
的资源,将其资料结构用 interface
的方式存在 src/common/models
资料夹中的 todo.model.ts
:
export interface Todo {
userId: number;
id: number;
title: string;
completed: boolean;
}
调整一下 app.service.ts
的内容,透过 getTodos
方法去取得 todos
的资源:
注意:由於
Agent
的问题,这里我们需要配置httpsAgent
的rejectUnauthorized
为false
以正常使用此 API。
import { HttpService, Injectable } from '@nestjs/common';
import { Agent } from 'https';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Todo } from './common/models/todo.model';
@Injectable()
export class AppService {
constructor(
private readonly http: HttpService
) {}
getTodos(): Observable<Todo> {
const httpsAgent = new Agent({ rejectUnauthorized: false });
return this.http.get('https://jsonplaceholder.typicode.com/todos', { httpsAgent }).pipe(
map((res) => res.data)
);
}
}
调整 app.controller.ts
,在 getTodos
中调用 AppService
的 getTodos
:
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('/todos')
getTodos() {
return this.appService.getTodos();
}
}
透过 Postman 存取 http://localhost:3000/todos,会得到下方结果:
在上述范例中,会发现存取 JSONPlaceholder 的 todos
资源会碰到 Agent
的问题,如果有多个 API 都会碰到此问题,又不希望每次都要重复写一样的东西,这时候就可以运用 HttpModule
的 register
方法来配置预设值,而这个预设值可以配置的项目与 HttpService
各方法中的 options
相同,具体的内容可以参考官方说明。
这里以 app.module.ts
为例,将 Agent
的配置设为预设值:
import { HttpModule, Module } from '@nestjs/common';
import { Agent } from 'https';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [
HttpModule.register({
httpsAgent: new Agent({ rejectUnauthorized: false })
})
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
接着调整 app.service.ts
,将本来配置好的 Agent
配置移除:
import { HttpService, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Todo } from './common/models/todo.model';
@Injectable()
export class AppService {
constructor(
private readonly http: HttpService
) {}
getTodos(): Observable<Todo> {
return this.http.get('https://jsonplaceholder.typicode.com/todos').pipe(
map((res) => res.data)
);
}
}
最後,透过 Postman 存取 http://localhost:3000/todos,会成功获取 todos
的资料:
HttpModule
有提供 registerAsync
方法,透过这个方法可以添加依赖的 Provider,并用工厂函式将其值带入 HttpModule
,运用这样的机制来注入 ConfigService
,进而将要配置的预设值带入。
这边来做个简单的范例,先在专案目录下新增 .env
并添加下方的环境变数:
HTTP_TIMEOUT=3000
修改 app.module.ts
的内容,在 registerAsync
汇入 ConfigModule
并在 injects
带入 ConfigService
,最後在 useFactory
注入 ConfigService
:
import { HttpModule, Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { Agent } from 'https';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true
}),
HttpModule.registerAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
httpsAgent: new Agent({ rejectUnauthorized: false }),
timeout: config.get('HTTP_TIMEOUT')
}),
inject: [
ConfigService
]
})
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
这样就可以顺利将环境变数带入至 HttpModule
来配置预设值了!
Nest 将 Http Request 相关功能直接打包成内建模组实在很方便,不必再花时间去选择要使用哪个套件,也不必花时间将套件包装成 Nest 的模组,直接注入 HttpService
即可使用。这里附上今天的懒人包:
HttpModule
为内建模组,透过注入 HttpService
来使用 axios
的方法。HttpModule
的 register
来配置预设值。HttpModule
的 registerAsync
来取得注入 Provider 的值,进而配置预设值。
<<: Day28- 你都用什麽debug kubectl-debug
前言: 在大致介绍完React的特性後,我们要延伸聊聊用React写网页时,最好用的前後端架构,M...
跨站脚本攻击(XSS) 攻击 XXS就是透过网页没有适当筛选、处理文字造成的漏洞 例如有用户将<...
变数(variable)-Boolean 主要为 true、false,内容为判断式也可以,如 2&...
本来是没打算分成两天的。但第一天放入了程序码让文章看起来比较冗长,所以只好拆两天啦!今天一样也是 嵌...
一. 前言 在如今社群网路蓬勃的时代,从网路充斥着许多文字资料,要如何有效的分析文字让电脑可以知道我...