@Injectable & Services
The @Injectable decorator marks a class as a provider that Nest can manage and inject.
@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
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.
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.
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.
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