Understanding Inject, Injectable and InjectRepository in nest

Viewed 11040

I come from non typescript and non nest background. I was reviewing the code and I found this piece of code snippet

import { Inject, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { AreaService } from '../area/-area.service';
import { Repository } from 'typeorm';
import { Office } from './office.entity';
import { OfficeInterface } from './office.interface';

@Injectable()
export class OfficeService {
  constructor(
    @Inject(AreaService)
    private readonly AreaService: AreaService,
    @InjectRepository(Office)
    private readonly OfficeRepository: Repository<Office>,
  ) {}

Now this is, honestly, quiet overwhelming for me. I went to Nest JS page to understand this and this what they have to say

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully safe for our application

Do they mean in the above statement that they add everything to request object in nestJS?

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {}

Specify injection scope by passing the scope property to the @Injectable() decorator options object:

So if we do @Injectable() what scope is it going to have?

Can someone please explain me difference between @Injectable(), @Inject(AreaService) and @InjectRepository(Office) and when, which one should be used?

3 Answers

To answer your question regarding REQUEST-scope:

@Injectable({ scope: Scope.REQUEST })
export class CatsService {}

This means that for every request that is handled by a Controller which depends on CatsService a new instance of CatsService will be created. This also implies that any other Service/Controller that depends on CatService will become REQUEST-scoped, even if they're defined with default (i.e. singleton)-scope. This is an important thing to keep in mind, since it could have an impact on your app, see this and that for further information.

I know this is a little old but for anyone else looking at this:

The unanswered point on the @InjectRepository() which from the @nestjs/typeorm package, this is a repository pattern which is available within the scope of the request with a db connection & will mean you are able to find an Office, find all Office, create an Office, update an Office or Delete an Office based on your request within your service provider. Here's the reference Nest.js

This module uses the forFeature() method to define which repositories are registered in the current scope. With that in place, we can inject the UsersRepository into the UsersService using the @InjectRepository() decorator:

Also the paragraph you are quoting from Nest.js: your request is handled by your controllers so you can control what is available to the request & what is injected.

That's what @Injectable() does

In cats.service.ts, the @Injectable() decorator declares the CatsService class as a class that can be managed by the Nest IoC container.

https://docs.nestjs.com/fundamentals/custom-providers#di-fundamentals

It declares a class to be recognized by Nest for future Dependency Injection, which are performed through @Inject(TokenName).

Related