In my backend API, each controller inherits from a generic base controller in order to support auto CRUD to most of my entities.
The issue begins in the following scenario, The base controller has for the following routes
- POST -> Create
- PUT -> Update
- DELETE -> Delete
- GET -> /all
- GET -> /:id
The route /:id must be last because express ordering as described here. But now, I needed to override the get(/:id) function since there is a requirement for a custom logic in one of the children controllers, When I override it, all the static routes from base got ignoration. (which makes sense because the /:id becomes the first route), I'll be glad to have any idea how to handle the base controller in that case or how to override custom routes with parameters without destroying other static routes in the base controller, please.
The base controller
export class BaseController<MODEL_TYPE, T_DTO> {
public constructor(protected _service: IServiceBase<MODEL_TYPE,T_DTO>) {
}
@Get()
public async list<T>(@Query(new RequestValidationPipe()) options?: ListQueryOptionsDto
): Promise<IResponse<T[]|T_DTO[]>> {
return await this._service.list<T>(options);
}
@Post()
public async create<DTO>(@Body() createDTOs: DTO | DTO[]): Promise<IResponse<DTO |DTO[]>> {
return await this._service.create<DTO>(createDTOs);
}
@Get('/all')
public async all<DTO>(): Promise<IResponse<DTO[]>> {
return await this._service.all();
}
@Delete('/:id')
public async delete(@Param('id') id: string): Promise<IResponse<boolean>> {
return await this._service.delete(id);
}
@Get('/:id')
public async get<DTO>(@Param('id') id: string): Promise<IResponse<DTO|T_DTO>> {
return await this._service.get<DTO|T_DTO>(id);
}
}
The user's controller (which inherit from the base)
import { FileInterceptor } from '@nestjs/platform-express';
@Controller(ApiRoutes.USERS)
@ApiTags(ApiRoutes.USERS)
export class UsersController extends BaseController<User,UserDto> {
constructor(protected _service: UserService) {
super(_service);
}
@Get('/:id')
public async get<GetPromotionDto>(@Param('id') id: string):Promise<IResponse<GetPromotionDto>> {
return await this._service.get<GetPromotionDto>(id, { schema: getPromoSummaryMapper });
}
}
UPDATE - I understood that this is an express by-design behavior, so it becomes a more general question, whether is solvable or limitation of express with TS(especially with NestJS)