Providers & Services
Providers & Services
If controllers are the "how requests come in," providers are the "where the work happens." A provider is any class NestJS can inject as a dependency — most commonly a service that holds business logic. This lesson is where dependency injection, the heart of NestJS, finally clicks.
Defining a service
A service is a class marked with the @Injectable() decorator. That decorator tells NestJS, "this class can be managed and injected":
Injecting a service into a controller
You never call new UsersService() yourself. Instead you declare it as a constructor parameter and NestJS supplies the instance — this is dependency injection:
The private readonly usersService shorthand both declares and assigns the dependency in one line. NestJS sees the type UsersService and injects the right instance.
Registering the provider
For injection to work, the service must be listed in a module's providers array:
Singletons by default
By default every provider is a singleton — NestJS creates one instance and shares it across the entire application. Inject UsersService into ten controllers and all ten share the same object and its state.
Why dependency injection wins
- Testability: in a test you inject a fake/mock service instead of the real one — no code change needed.
- Loose coupling: classes depend on abstractions the container provides, not on objects they build themselves.
- Single responsibility: controllers route, services compute, each stays small.
providers array, or the module that exports it was not imported. Read the bracketed hint in the message — it names the missing dependency.
Summary
Providers — usually services marked @Injectable() — hold your business logic and are supplied to controllers through constructor injection. Register them in a module's providers array; they are singletons by default. Dependency injection is what keeps NestJS apps testable, loosely coupled, and easy to grow. This completes Phase 1: you can now build a structured, working NestJS API.