Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NestJS with TypeORM: When using custom repository, is a service needed anymore?

Tags:

typeorm

nestjs

Newbie question: When working with NestJS and TypeORM, and one has created a custom repository (which extends the standard repository), is a seperate service class needed anymore?

At the moment, I'm working only with the custom Repository class and it works fine, but I'm not sure if this is correct and perhaps has some side effects.

Btw, in another project i have no custom repo, only a service which get's two standard repo's injected, and this works also fine.

Regards,
sagerobert

like image 969
sagerobert Avatar asked Aug 26 '18 20:08

sagerobert


1 Answers

I think it's up to you how much you want to add layers between typeORM and your most "front-office" code (that would be the controllers in a typical nest application).

I explain myself:

If you want, you could typically inject directly the built-in typeORM repositories into your controllers:

import {Controller, Get} from '@nestjs/common';
import {InjectRepository} from '@nestjs/typeorm';
import {Repository} from 'typeorm';
import {User} from './entities/User.entity';

@Controller()
export class AppController {
    constructor(
        @InjectRepository(User)
        private readonly userRepository: Repository<User>,
    ) {
    }

    @Get()
    async root(): Promise<User> {
        return await this.userRepository.find(1);
    }
}

So this would be the less layered implementation of how to retrieve the user with ID = 1.

Now, the documentation of NEST recommends to abstract this repository and inject it into a service rather than in a controller directly. This allows you to have less binding between your controller and TypeORM. Instead, it's your service that has this binding. If you have many controllers that use this repository, and you decide that you want to change TypeORM and use the new fancy ORM, you'll have to change every controller.

Now, if you just inject the repository inside your service and use this service into all your controllers, you will just have to change the implementation of your service and all the controllers will remain the same.

Secondly, imagine that you want to test your application. You will face the same problem. How can you run your tests without an SQL connection? I suppose that your unit tests are not created to test the TypeORM behaviour, but instead written to test YOUR code behavior.

It will be much easier to mock a repository injected in a service than mock all repositories injected in your controllers.

So to conclude this answer, I think that this question should be closed because it is primarily opinion-based. But IMO, the dreamed architecture is the following:

  • Create a Custom Repository that extends the TypeORM Repository.
  • Inside the Custom Repository, add methods that use the Query Builder.
  • Inject this Custom Repository into your services
  • Inject the services into your controllers.

Don't ever use the query builder into controllers because it is hard to mock.

I hope this answers to your question: A service class is not needed. But it will help you keep your code clean.

like image 72
Hammerbot Avatar answered Dec 31 '22 08:12

Hammerbot