首先需要注意的是,之前从@nestjs/common导入的HttpService的方式已被废弃而不可用。
新方式是通过安装@nestjs/axios包来导入所需的模块和服务。 所有 HttpService 的方法都返回一个包裹在 Observable 对象内的 AxiosResponse 。例如get post put等。 通过返回 RxJS observable 流,Nest 路由处理程序将更加强大。 Nest 将自动订阅下面的源并获取最后发出的值(在流完成后)。
下面以一个简单地微信小程序服务端code2session接口为范例
app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '@nestjs/mongoose'
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TodoModule } from './todo/todo.module';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [
HttpModule,
TodoModule,
ConfigModule.forRoot(),
MongooseModule.forRoot(`mongodb://${new ConfigService().get('DATABASE_HOST')}`)
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
app.service.ts
import { HttpService } from '@nestjs/axios';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Observable } from 'rxjs';
import { AxiosResponse } from 'axios'
const errorCode: Map<number, string> = new Map([
[-1, '系统繁忙,此时请开发者稍候再试 '],
[0, '请求成功'],
[40029, 'code 无效'],
[45011, '频率限制,每个用户每分钟100次'],
[40226, '高风险等级用户,小程序登录拦截'],
])
@Injectable()
export class AppService {
private readonly wxAppId: string;
private readonly wxAppSecret: string;
constructor(private readonly httpService: HttpService, private readonly configService: ConfigService) {
this.wxAppId = configService.get('WX_APPID')
this.wxAppSecret = configService.get('WX_APPSECRET')
this.httpService.axiosRef.interceptors.response.use(({data}) => {
//设置Axios的拦截器,直接返回 AxiosResponse.data
data.tips = errorCode.get(data.errcode)
return data
})
}
login(): string {
return 'Hello World!';
}
wxLogin(code: string): Observable<AxiosResponse<{
errcode: number,
errmsg: string,
tips: string
}>> {
const api = `https://api.weixin.qq.com/sns/jscode2session?appid=${this.wxAppId}&secret=${this.wxAppSecret}&js_code=${code}&grant_type=authorization_code`
return this.httpService.get(api)//直接返回Observable对象
}
}
app.controller.ts
import { Body, Controller, Get, Post, UsePipes, ValidationPipe } from '@nestjs/common';
import { AxiosResponse } from 'axios';
import { IsNotEmpty, IsString } from 'class-validator';
import { from, map, Observable, of } from 'rxjs';
import { AppService } from './app.service';
class code2sessionDto {
@IsString({
message: 'code 必须为字符串'
})
@IsNotEmpty({
message: 'code 不能为空'
})
code: string
}
@Controller()
export class AppController {
constructor(private readonly appService: AppService) { }
@Post('login')
login() {
return 'login'
}
@Post('wxlogin')
wxLogin(@Body() params: code2sessionDto) {
return this.appService.wxLogin(params.code)//nestjs会自动订阅
}
}
{ "errcode": 40029, "errmsg": "invalid code, rid: 62aa10e4-53bc13f6-17909902", "tips": "code 无效" }