To keep it brief:
I have a service - let's call it CatsService...
import { Injectable } from '@nestjs/common';
@Injectable()
export class CatsService {
GetCat(id: number){
return id + 12345;
}
}
Later on, a module wishes to use this CatsService in order to inject it into a constructor. It also dynamically resolves this CatsService
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import * as ProductionCatsService from "./production"
import * as DevelopmentCatsService from "./development"
const catsServiceProvider = {
provide: CatsService,
useValue: process.env.NODE_ENV === "development" ?
DevelopmentCatsService :
ProductionCatsService
}
@Module({
controllers: [CatsController],
providers: [catsServiceProvider],
exports:[CatsService]
})
export class CatsModule {}
Both of these service implementations are strictly empty. This means that the /cats/:id route returns:
{"statusCode":500,"message":"Internal server error"}
I have had the idea since beginning writing this to make everything implement a ICatsService interface.
After a lot of fiddling about, I have build a sort-of solution:
I have a "service_interface" file, which has an abstract class called ICatsInterface with one abstract method (GetCat)
I have made every one of these implementations implement this service_interface.
I have made the controller take ICatsService instead of CatsService
My problem is that now, the thing compiles, but I get the below error:
TypeError: this.catsService.GetCat is not a function
at CatsController.get (/home/a/learning-nest/src/cats/cats.controller.ts:12:33)
at /home/a/learning-nest/node_modules/@nestjs/core/router/router-execution-context.js:38:29
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at /home/a/learning-nest/node_modules/@nestjs/core/router/router-execution-context.js:46:28
at /home/a/learning-nest/node_modules/@nestjs/core/router/router-proxy.js:9:17
I simply don't know what to do anymore. Even though I have made it compile, I cannot make it actually be forced to implement the interface/abstract class that I want. I have made sure that both DevelopmentCatsService and ProductionCatsService have the implementation of GetCat. They are both marked with @Injectable. I don't truthfully know where to go from here.
Should I abandon my dream of having an compile-time error message for when someone does not implement the methods that I want implemented in my service?
I have solved my own issue. It was very simple.
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import * as ProductionCatsService from "./production"
import * as DevelopmentCatsService from "./development"
const catsServiceProvider = {
provide: CatsService,
useValue: process.env.NODE_ENV === "development" ?
DevelopmentCatsService :
ProductionCatsService
}
@Module({
controllers: [CatsController],
providers: [catsServiceProvider],
exports:[CatsService]
})
export class CatsModule {}
In the above snippet, I am importing "* as ProductionCatsService". This caused my ProductionCatsService to actually be an object wrapping around the real service implementation that I wanted!
Sorry for the bother, all.