@Injectable & Services

The @Injectable decorator marks a class as a provider that Nest can manage and inject.

Syntax@Injectable() export class UsersService {}

A service is where your business logic lives. Controllers stay thin and hand real work to services.

Making a service

Mark the class with @Injectable(). That decorator tells Nest the class can be managed by the injection container. Register it in a module's providers array and it becomes available to inject.

Services are singletons by default: Nest creates one instance and shares it everywhere it is injected.

Example

Example Β· typescript
import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  private users = [{ id: 1, name: 'Ada' }];

  findAll() {
    return this.users;
  }

  create(name: string) {
    const user = { id: this.users.length + 1, name };
    this.users.push(user);
    return user;
  }
}

When to use it

  • A developer marks a MailerService with @Injectable so the DI container can instantiate it once and share it across the app.
  • A team wraps a third-party SDK in an @Injectable adapter class so it can be swapped in tests with a mock.
  • A developer omits @Injectable on a helper class and gets a runtime error, illustrating why every provider needs the decorator.

More examples

@Injectable service with method

The canonical @Injectable example β€” marks the class so the Nest DI container can create and inject it.

Example Β· ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

Injectable wrapping third-party SDK

Wraps the Stripe SDK in an @Injectable class so it can be injected, mocked in tests, and swapped without changing controllers.

Example Β· ts
import { Injectable } from '@nestjs/common';
import Stripe from 'stripe';

@Injectable()
export class PaymentsService {
  private stripe = new Stripe(process.env.STRIPE_KEY!);

  async charge(amount: number, currency: string) {
    return this.stripe.paymentIntents.create({ amount, currency });
  }
}

Injecting one service into another

Shows service-to-service injection: DatabaseService declares ConfigService in its constructor and Nest provides it automatically.

Example Β· ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class DatabaseService {
  constructor(private config: ConfigService) {}

  getConnectionString() {
    return this.config.get<string>('DATABASE_URL');
  }
}

Discussion

  • Be the first to comment on this lesson.