재우니의 블로그

서비스란 무엇인가? 역할과 사용 방법 & 의존성 주입을 통해 데이터 서비스 만들기 (Angular 16 기준)

서론

Angular 16에서 서비스(Service) 비즈니스 로직, 데이터 처리, API 호출과 같은 기능을 독립적으로 처리하여 컴포넌트 간에 쉽게 재사용할 수 있는 기능 단위입니다. 서비스를 통해 애플리케이션의 로직과 데이터 관리를 컴포넌트와 분리할 수 있으며, 이렇게 분리된 서비스는 의존성 주입(Dependency Injection, DI)을 통해 컴포넌트에 손쉽게 연결할 수 있습니다. 이번 글에서는 서비스의 역할과 사용 방법을 알아보고, 의존성 주입을 사용해 데이터 서비스를 만드는 실습을 진행하겠습니다.


본론

1. 서비스란 무엇인가?

서비스의 개념

Angular에서 서비스는 특정 기능을 수행하는 독립적인 클래스입니다. 서비스는 비즈니스 로직, 데이터 호출 및 처리, 유틸리티 함수 등을 포함할 수 있으며, 여러 컴포넌트에서 공통적으로 사용해야 하는 코드를 분리하는 데 유용합니다.

서비스의 주요 역할

  • 비즈니스 로직 관리: 서비스는 복잡한 비즈니스 로직을 컴포넌트 외부에서 관리함으로써 컴포넌트를 더 깔끔하고 유지보수하기 쉽게 만듭니다.
  • 데이터 처리 및 API 호출: REST API, 데이터베이스와의 통신 같은 외부 데이터를 처리하는 로직을 서비스에서 관리합니다.
  • 컴포넌트 간 데이터 공유: 하나의 서비스를 여러 컴포넌트에 주입하여 데이터를 공유하거나, 통합된 기능을 제공할 수 있습니다.

Angular 서비스의 사용 방법

Angular에서는 서비스를 @Injectable() 데코레이터를 사용하여 정의합니다. 서비스는 컴포넌트나 다른 서비스에 주입될 수 있으며, 주로 의존성 주입(Dependency Injection)을 통해 연결됩니다.

2. 의존성 주입을 통해 데이터 서비스 만들기

1) Angular 서비스 생성하기

Angular CLI를 사용해 데이터를 처리하는 데이터 서비스를 생성해 보겠습니다. ng generate service 명령어를 통해 서비스 파일을 생성합니다.

ng generate service data

위 명령어를 실행하면 data.service.ts라는 파일이 생성됩니다. 이 파일에는 @Injectable() 데코레이터가 포함되어 있으며, 이 데코레이터는 Angular가 이 클래스를 의존성 주입 시스템에서 사용할 수 있도록 등록해줍니다.

// data.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'  // root에 등록하여 애플리케이션 전반에서 사용 가능
})
export class DataService {
  constructor() { }
}
  • @Injectable() 데코레이터: Angular에게 이 클래스가 서비스로 사용될 수 있음을 알려줍니다.
  • providedIn: 'root': 서비스가 root에 제공되므로, 애플리케이션 전역에서 이 서비스를 사용할 수 있습니다.

2) 데이터 서비스에 데이터 및 메서드 추가하기

이제 DataService 클래스에 데이터를 저장하고 제공하는 메서드를 추가해보겠습니다. 예제에서는 간단한 사용자 정보를 제공하는 메서드를 추가하겠습니다.

// data.service.ts
@Injectable({
  providedIn: 'root'
})
export class DataService {
  private users: string[] = ["Alice", "Bob", "Charlie", "David"];

  constructor() {}

  // 사용자 목록을 가져오는 메서드
  getUsers(): string[] {
    return this.users;
  }

  // 사용자 목록에 새로운 사용자 추가
  addUser(name: string): void {
    this.users.push(name);
  }
}
  • getUsers() 메서드: users 배열에 저장된 사용자 목록을 반환합니다.
  • addUser(name: string) 메서드: users 배열에 새로운 사용자를 추가합니다.

3) 의존성 주입을 통해 컴포넌트에 서비스 연결하기

이제 이 서비스를 의존성 주입을 통해 컴포넌트에 연결해보겠습니다. AppComponent에 DataService를 주입하여 사용자 목록을 가져오고 화면에 표시할 수 있습니다.

// app.component.ts
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  users: string[] = [];

  constructor(private dataService: DataService) {}

  ngOnInit() {
    this.users = this.dataService.getUsers();  // 서비스에서 사용자 목록 가져오기
  }

  addUser(name: string) {
    this.dataService.addUser(name);  // 서비스에 사용자 추가
    this.users = this.dataService.getUsers();  // 사용자 목록 업데이트
  }
}
  • constructor(private dataService: DataService): DataService를 AppComponent에 주입합니다. 이로써 dataService 인스턴스를 통해 DataService의 메서드를 사용할 수 있습니다.
  • ngOnInit(): 컴포넌트 초기화 시 DataService로부터 사용자 목록을 가져와 users에 저장합니다.
  • addUser(name: string) 메서드: 새로운 사용자를 추가하고 업데이트된 목록을 화면에 반영합니다.

4) 템플릿에 데이터 바인딩하기

이제 app.component.html 템플릿에 사용자 목록을 표시하고, 새로운 사용자를 추가할 수 있는 입력 필드와 버튼을 추가해보겠습니다.

<!-- app.component.html -->
<div>
  <h2>사용자 목록</h2>
  <ul>
    <li *ngFor="let user of users">{{ user }}</li>
  </ul>

  <input type="text" #userName placeholder="이름을 입력하세요">
  <button (click)="addUser(userName.value); userName.value=''">사용자 추가</button>
</div>
  • *ngFor="let user of users": users 배열의 각 항목을 반복하여 목록으로 표시합니다.
  • (click)="addUser(userName.value); userName.value='': 버튼 클릭 시 입력한 이름을 addUser 메서드에 전달하고, 입력 필드를 초기화합니다.

결과: 초기에는 기본 사용자 목록이 표시되며, 새 이름을 입력하고 "사용자 추가" 버튼을 클릭하면 목록에 새로운 사용자가 추가됩니다.


결론

이번 글에서는 Angular 16의 서비스 개념과 역할을 알아보고, 의존성 주입을 통해 컴포넌트에 서비스를 연결하는 방법을 실습했습니다. 서비스는 비즈니스 로직과 데이터 관리를 담당하여 코드의 재사용성과 유지보수성을 높여줍니다. 특히 의존성 주입을 통해 컴포넌트에 손쉽게 주입하여 사용할 수 있어 Angular 애플리케이션의 핵심적인 구조 요소로 자리 잡고 있습니다. 앞으로 서비스와 의존성 주입을 적극적으로 활용해 더 효율적이고 모듈화된 Angular 애플리케이션을 개발해보세요.


Q&A 섹션

  • Q1: 서비스와 컴포넌트의 차이점은 무엇인가요?
    A1: 컴포넌트는 UI를 담당하고 사용자와 상호작용하는 데 사용되며, 서비스는 데이터 처리 및 비즈니스 로직을 관리하는 역할을 합니다.
  • Q2: 서비스에 providedIn: 'root'가 필요한 이유는 무엇인가요?
    A2: providedIn: 'root'는 서비스가 애플리케이션 전체에 한 번만 인스턴스화되도록 설정하는 옵션으로, 전역으로 사용할 수 있게 만들어줍니다.
  • Q3: 의존성 주입이란 무엇인가요?
    A3: 의존성 주입은 컴포넌트나 클래스가 필요한 객체(의존성)를 외부에서 주입받아 사용하는 방식입니다. Angular는 이를 통해 각 객체가 서로 의존성을 쉽게 관리할 수 있게 도와줍니다.

관련 태그

  • #angular-서비스
  • #의존성-주입
  • #데이터-서비스
  • #angular-16
  • #비즈니스-로직