Angular Resource API로 비동기 데이터 관리를 한층 더 간편하게!
2025-03-20 10:12:19Angular Resource API로 비동기 데이터 관리 혁신
최근 Angular는 개발자의 워크플로우를 간소화하고 성능을 향상시키기 위해 노력하고 있습니다. 그중에서도 특히 주목받고 있는 실험적인 기능이 바로 Resource API입니다. 이번 글에서는 이 흥미로운 기능이 어떤 역할을 하고, Angular 애플리케이션에 어떻게 기여할 수 있는지 살펴보겠습니다.
왜 새로운 Resource API가 필요한가?
현재 Angular 개발자들은 주로 비동기 작업을 위해 Observable과 HttpClient를 사용하고 있습니다. 이러한 도구들은 강력하지만, 반응형 업데이트, 정확한 에러 처리 또는 효율적인 스트리밍 시나리오에서 복잡성을 유발할 수 있습니다. Resource API는 이러한 문제를 해결하기 위해 고안되었습니다.
- 직관적이고 단순한 API 제공
- 반응형 데이터 페칭 지원
- 내장된 상태 추적(로드 중, 에러, 성공)
- 더 세밀한 반응성을 통한 성능 향상
현재 이 API는 실험 단계이며 계속 발전 중입니다. 어떤 기능들은 아직 구현되지 않았습니다. 예를 들면 디바운싱이나 변이(mutations) 같은 중요한 기능들은 아직 초기 개발 단계에 있습니다.
Core Resource 인터페이스
Resource API의 핵심은 반응형 데이터 페칭을 캡슐화한 Resource 인터페이스에 있습니다.
interface Resource<T> {
readonly value: Signal<T>;
readonly status: Signal<ResourceStatus>;
readonly error: Signal<Error | undefined>;
readonly isLoading: Signal<boolean>;
hasValue(): boolean;
}
이 인터페이스의 주요 포인트는 다음과 같습니다:
- value: 반응형 데이터를 Signal로 보유합니다.
- status: 현재 상태(Idle, Loading, Resolved, Error)를 나타냅니다.
- error: 페칭 중 발생한 오류를 캡쳐합니다.
- isLoading: 로딩 상태를 쉽게 확인할 수 있는 지표입니다.
이러한 설정은 Angular 템플릿에서 비동기 데이터를 처리하는 방식을 크게 간소화시킵니다.
리소스 생성
Angular는 리소스를 생성하는 직관적인 방법을 제공합니다.
const userResource = resource({
request: () => userId(),
loader: async ({ value }) => fetchUser(value),
defaultValue: null,
});
- request: 페칭을 위한 반응형 입력값입니다.
- loader: 페칭을 수행하는 비동기 함수입니다.
- defaultValue: 페칭 완료 전의 초기 플레이스홀더 값입니다.
리소스 상태를 템플릿에서 쉽게 추적할 수 있습니다.
@if (userResource.isLoading()) {
Loading...
} @else if (userResource.hasValue()) {
{{ userResource.value().name }}
} @else if (userResource.status() === ResourceStatus.Error) {
Error: {{ userResource.error().message }}
}
HTTP 리소스를 전문화하기
Angular는 httpResource를 통해 HTTP 페칭을 더욱 간소화합니다.
const products = httpResource('/api/products');
이 방식은 Angular의 기존 HttpClient와 직접 통합되며, 기본적으로 JSON 응답을 자동으로 파싱합니다. 요청을 맞춤화할 수도 있습니다.
const productDetail = httpResource({
url: `/api/products/${productId()}`,
method: 'GET',
headers: { Authorization: 'Bearer token' },
});
다양한 응답 유형
httpResource는 다양한 응답 형식을 지원합니다.
- ArrayBuffer:
httpResource.arrayBuffer() - Blob:
httpResource.blob() - Text:
httpResource.text()
바이너리 데이터를 페칭하는 예제입니다.
const fileData = httpResource.arrayBuffer('/file.bin');
고급 기능
런타임 검증을 통한 타입 안전성
Angular의 Resource API는 Zod와 같은 런타임 검증 라이브러리와 매끄럽게 작동하여 타입 안전성을 강화합니다.
const ProductSchema = zod.object({
id: zod.number(),
name: zod.string(),
});
const product = httpResource('/api/product', { parse: ProductSchema.parse });
자원 스트리밍
Resources는 스트리밍 응답을 처리할 수 있습니다.
const streamResource = resource({
stream: async ({ value }) => fetchStreamedData(value),
});
RxJS 통합
기존 Observable은 rxResource와 쉽게 통합될 수 있습니다.
const observableResource = rxResource({
stream: param => observableService.getData(param),
});
상태 및 에러 처리
Resources는 로딩 상태(초기 로드 vs. 재로드)를 명확히 구분합니다.
enum ResourceStatus {
Idle,
Loading,
Reloading,
Resolved,
Error,
Local,
}
명시적인 상태 추적은 템플릿의 에러 처리를 간소화합니다.
@let resourceStatus = resource.status();
@let error = resource.error();
@if (resourceStatus === ResourceStatus.Loading) {
Loading...
} @else if (resourceStatus === ResourceStatus.Resolved) {
Data Loaded
} @else if (resourceStatus === ResourceStatus.Error) {
Error: {{ error.message }}
}
프리페칭 및 지연 로딩
Resources는 지연 로딩(@defer 블록)과 매끄럽게 통합되어 응용 프로그램의 성능을 최적화합니다.
<button #loadBtn>Load Data</button>
@defer (on interaction(loadBtn)) {
<data-cmp [data]="resource.value()"></data-cmp>
}
프리페칭은 성능을 더욱 향상시킵니다.
@defer (prefetch on viewport(elementRef)) {
<component-cmp />
}
마이그레이션 및 제한 사항
이 API는 실험 단계이므로 다음 사항을 고려하시길 권장합니다:
- Observable과 매끄럽게 통합됩니다.
- 구조적 지시문과 호환됩니다.
- 변이 및 디바운싱과 같은 중요한 기능은 아직 구현되지 않았습니다.
실험적 API를 채택하는 데 주의하는 것이 좋으며, 특히 운영 환경에서 주의해야 합니다. 이 기능의 개발에 참여하고 싶거나 논의에 참여하고 싶다면 Angular Resource API RFC에 참여할 수 있습니다.
결론
Angular의 실험적 Resource API는 비동기 데이터 관리의 복잡성을 해결하고 성능을 향상시키는 혁신적인 방향을 제시합니다. 아직 발전 중이지만 주목할 만한 가치가 있습니다. Angular는 개발자의 경험을 개선하고 더 나은, 더 빠른 애플리케이션을 만드는 데 주력하고 있습니다. 🚀✨
더 논의하고 싶거나 의견을 공유하고 싶다면 Twitter, Threads, LinkedIn, BlueSky에서 연락해 주세요. 함께 탐험해 봅시다! 💻☕️
이 가이드를 도움이 되셨다면 커피 한 잔 사주는 것도 환영합니다. 당신의 지원은 큰 힘이 됩니다! ☕️🙏