NestJS读取本地JSON文件报httpService.get is not a function错误
报错原因
this.httpService.get is not a function是依赖注入写错导致的:你给HttpService类型的属性错误添加了@InjectModel('Resources')装饰器,这个装饰器是用来注入Mongoose数据库模型的,最终注入到httpService属性里的是Mongoose模型实例,根本不存在get方法,自然触发报错。
另外你要读取的是项目根目录下的本地db.json文件,完全没必要走HTTP请求拉取,直接读本地磁盘文件更稳定、性能更好,也不会出现路径、端口、服务未启动之类的请求错误。
修复方法
方法一:修正HttpService注入(适配你现有HTTP请求的写法)
- 先在所属业务模块中导入
HttpModule,否则HttpService无法被正常注入:
// resources.module.ts import { Module } from '@nestjs/common'; import { HttpModule } from '@nestjs/axios'; import { MongooseModule } from '@nestjs/mongoose'; import { ResourcesController } from './resources.controller'; import { ResourcesService } from './resources.service'; import { ResourcesSchema } from './resource.schema'; @Module({ imports: [ MongooseModule.forFeature([{ name: 'Resources', schema: ResourcesSchema }]), HttpModule.register({ timeout: 5000 }) ], controllers: [ResourcesController], providers: [ResourcesService] }) export class ResourcesModule {}
- 修正Service中的依赖注入逻辑,把Mongoose模型和HttpService分开注入,不要混写:
import { Injectable } from '@nestjs/common' import { HttpService } from '@nestjs/axios' import { InjectModel } from '@nestjs/mongoose' import { Observable } from 'rxjs' import { AxiosResponse } from 'axios' import { Model } from 'mongoose' import { Data } from './resource.schema' @Injectable() export class ResourcesService { constructor( // Mongoose模型单独注入,不要给HttpService加这个装饰器 @InjectModel('Resources') private resourcesModel: Model<Data>, // HttpService按类型自动注入即可,不需要额外装饰器 private httpService: HttpService, ) {} getAll(): Observable<AxiosResponse<Data>> { return this.httpService.get('http://localhost:5000/api/v1/db.json') } }
控制器代码不需要修改,Nest可以自动处理返回的Observable对象。
方法二:直接读取本地JSON文件(推荐,无额外依赖)
不需要启动静态服务托管db.json,也不需要引入HttpModule,直接用Node.js内置能力读文件即可,从根源避免HTTP请求相关的错误:
import { Injectable, OnModuleInit } from '@nestjs/common' import { InjectModel } from '@nestjs/mongoose' import { Model } from 'mongoose' import { readFile } from 'fs/promises' import { join } from 'path' import { Data } from './resource.schema' @Injectable() export class ResourcesService { private dbCache: Data | null = null constructor( @InjectModel('Resources') private resourcesModel: Model<Data>, ) {} // 服务启动时一次性读取文件缓存,避免每次请求都读磁盘 async onModuleInit() { // 用process.cwd()直接定位项目运行根目录,不会出现路径解析错误 const dbPath = join(process.cwd(), 'db.json') const content = await readFile(dbPath, 'utf-8') this.dbCache = JSON.parse(content) } async getAll(): Promise<Data> { return this.dbCache } }
如果需要每次请求都读取最新的文件内容,把读文件的逻辑移到getAll方法里即可。
内容的提问来源于stack exchange,提问作者Finlandary
相关产品推荐
相关产品推荐

