Angular에서 서비스 레벨
Source: Dev.to
루트 레벨 서비스: 전역 MVP 🌍
Angular CLI(ng generate service)로 서비스를 생성하면 기본 형태는 다음과 같습니다:
@Injectable({
providedIn: 'root'
})
export class UserService { }
Angular은 이 서비스의 단일 인스턴스를 생성하고 애플리케이션 전체에 공유합니다.
호텔의 프런트 데스크 직원과 같다고 생각하면 됩니다: 모든 컴포넌트가 같은 직원에게 이야기하고 같은 정보를 받습니다.
전형적인 사용 사례
- 인증 서비스 – 모든 컴포넌트에서 로그인 상태를 공유
- 설정 서비스 – 변하지 않는 전역 앱 설정
- HTTP/API 서비스 – 백엔드와 통신하는 단일 진입점
- 상태 관리 – 여러 컴포넌트가 필요로 하는 공유 데이터
루트 레벨 서비스는 간단하고 효율적이며 불필요한 인스턴스를 방지하기 때문에 대부분의 시나리오에서 기본 선택입니다.
컴포넌트 레벨 서비스: 로컬에 두기 🏠
서비스를 단일 컴포넌트에서만 사용하거나, 컴포넌트마다 별도의 복사본이 필요할 경우 컴포넌트 레벨에서 제공할 수 있습니다:
@Component({
selector: 'app-shopping-cart',
templateUrl: './shopping-cart.component.html',
providers: [CartService]
})
export class ShoppingCartComponent { }
컴포넌트가 생성될 때마다 Angular은 해당 컴포넌트 전용 새 인스턴스의 CartService를 만듭니다.
비유하자면, 각 호텔 방마다 전담 관리인이 있는 것과 같습니다; 101호는 자체 관리인이 있고, 102호는 또 다른 관리인이 있어 정보를 공유하지 않습니다.
언제 사용해야 할까
- 폼 상태 – 각 폼 컴포넌트가 자체 데이터를 보관
- 컴포넌트 전용 로직 – 다른 컴포넌트에 노출돼서는 안 되는 데이터
- 다중 인스턴스 – 페이지에 같은 컴포넌트가 여러 번 나타나고 각각 독립적인 동작이 필요할 때
예시: 여러 페이지에 표시되는 ProductFilterComponent가 각자 자신의 필터를 기억하는 경우.
모듈 레벨 서비스: 중간 지대 ⚖️
Standalone 컴포넌트 대신 Angular 모듈을 사용하는 경우, 모듈 레벨에서 서비스를 제공할 수 있습니다:
@NgModule({
declarations: [...],
imports: [...],
providers: [AuthGuardService]
})
export class AdminModule { }
즉시 로드된 모듈
앱 시작 시 모듈이 로드되면, 서비스는 전체 앱에서 싱글톤처럼 동작합니다—실질적으로 providedIn: 'root'와 동일합니다.
지연 로드된 모듈
모듈이 라우트를 통해 지연 로드될 때(예: loadChildren), Angular은 해당 모듈을 위한 별도 인젝터를 생성하고, 서비스는 새 인스턴스를 갖게 됩니다. 이 인스턴스는 지연 로드된 기능에만 범위가 제한됩니다.
const routes: Routes = [
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }
];
이 경우 AdminService는 지연 로드된 admin 모듈 내부에만 존재하며, 모듈이 언로드될 때 파괴됩니다.
어느 것을 사용해야 할까? 🤔
| 질문 | 권장 스코프 |
|---|---|
| 서비스가 애플리케이션 전체에서 필요합니까? | 루트‑레벨 ✅ |
| 서비스가 단일 컴포넌트에서만 사용됩니까? | 컴포넌트‑레벨 ✅ |
| 서비스가 지연 로드되는 피처 모듈에 한정됩니까? | 모듈‑레벨 ✅ |
Angular의 의존성 주입(Dependency Injection) 계층 구조—인젝터가 컴포넌트 트리를 따라 상위로 의존성을 해결하는 방식—를 이해하면 적절한 레벨을 선택하는 데 도움이 됩니다.
핵심 요약 💡
- 루트 레벨: 하나의 인스턴스가 전체에 공유됩니다.
- 컴포넌트 레벨: 컴포넌트당 새로운 인스턴스가 생성됩니다.
- 모듈 레벨: 즉시 로드 여부에 따라 인스턴스가 달라집니다(즉시 로드 시 싱글톤, 지연 로드 시 별도 인스턴스).
올바른 레벨을 선택하면 앱을 유지보수하기 쉽고 성능도 최적화됩니다. 잘못 선택하면 디버깅이 골칫거리가 될 수 있습니다.