이번 프로젝트를 하면서 Angular와 함께 GraphQL을 새롭게 배우게 되어 공부해 보며 정리해보고자 한다 !
1. GraphQL이란 ?
- 클라이언트가 필요한 데이터만 요청할 수 있도록 만든 쿼리 언어이자, 이를 처리하는 런타임 환경
- 2012년 Facebook이 모바일 최적화를 위해 개발, 2015년 오픈소스로 공개
- 기존 REST API 방식의 한계(Over-fetching, Under-fetching)를 해결하기 위해 탄생
2. GraphQL이 왜 필요한가 ?
- 기존 REST 방식 문제
- Over-fetching : 필요 없는 데이터까지 과도하게 받음
ex) 사용자 프로필 화면에 이름과 이메일만 필요한데, 주소, 전화번호, 생일 같은 불필요한 데이터까지 함께 받아야 했다. - Under-fetching : 필요한 정보를 얻기 위해 여러 번 API 호출
ex) 글을 띄우려면 /posts, 작성자를 띄우려면 /users 따로 요청해야 했다.
- GraphQL 방식
- 필요한 데이터만 명시해서 요청 가능
- 한 번의 요청으로 여러 데이터 취합 가능
- 예시
query {
user(id: "123") {
name
email
}
}
→ REST와 달리, 원하는 필드만 골라 요청 가능
→ 네트워크 트래픽 감소, 개발 속도 향상
Q. GraphQL이 REST에 비해 갖는 가장 큰 장점은 ?
➔ 필요한 데이터만 요청해 네트워크 효율성과 개발 유연성이 높아진다.
3. GraphQL 기본 구조
- GraphQL은 세 가지 작업으로 구성
| 구분 | 역할 | 예시 코드 |
| Query | 데이터 조회 | query { users { id, name } } |
| Mutation | 데이터 생성/수정/삭제 | mutation { createUser(name: "Tom") { id } } |
| Subscription | 실시간 데이터 수신 | subscription { newMessages { content } } |
여기서 Query는 REST의 GET 요청과 비슷하고,
Mutation은 POST/PUT/DELETE에 대응한다.
Subscription은 WebSocket을 통해 서버로부터 실시간 알림을 받는다.
- 추가 구성 요소
- 스키마(Schema) : 서버가 제공하는 데이터 타입과 쿼리 구조를 정의
- 리졸버(Resolver) : 스키마에 매칭되는 실제 데이터 조회/변경 함수
Q. GraphQL 서버의 주요 구성요소는 ?
➔ 스키마(Schema), 리졸버(Resolver), 실행 엔진
4. GraphQL 작동 흐름
[Angular 컴포넌트]
↓ (GraphQL Query 요청)
[Apollo Client (서비스)]
↓
[GraphQL 서버]
↓ (스키마 검증 → 리졸버 실행)
[DB 조회]
↓
[결과 반환]
5. GraphQL을 언제 쓰는 게 좋을까 ?
| 상황 | 설명 |
| 복잡한 화면이 많은 경우 (게시글 + 작성자 + 댓글 등) | 다양한 데이터를 한 번에 조회 |
| 네트워크 트래픽 최적화가 필요한 경우 | 모바일/저속 네트워크 환경 |
| 프론트/백 분리 개발 환경 (백엔드 API 수정 없이 프론트 수정 가능) | API 구조를 자주 수정하지 않고 유연하게 대응 |
| 실시간 데이터 수신 (채팅, 주식 시세 등) | Subscription 기능 활용 가능 |
6. Angular에서 GraphQL 사용하는 방법
-> Angular에서는 Apollo Client를 사용해 GraphQL과 통신
(1) 설치
npm install @apollo/client graphql apollo-angular
(2) Apollo Client 설정 (app.module.ts)
import { ApolloModule, APOLLO_OPTIONS } from 'apollo-angular';
import { HttpLink } from 'apollo-angular/http';
import { InMemoryCache } from '@apollo/client/core';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [ApolloModule, HttpClientModule],
providers: [
{
provide: APOLLO_OPTIONS,
useFactory: (httpLink: HttpLink) => ({
cache: new InMemoryCache(),
link: httpLink.create({ uri: 'https://your-server.com/graphql' }),
}),
deps: [HttpLink],
},
],
})
export class AppModule {}
(3) 서비스로 쿼리 작성 (example.service.ts)
import { Injectable } from '@angular/core';
import { Apollo, gql } from 'apollo-angular';
@Injectable({ providedIn: 'root' })
export class ExampleService {
constructor(private apollo: Apollo) {}
getUser(id: string) {
return this.apollo.query({
query: gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
`,
variables: { id },
});
}
}
(4) 컴포넌트에서 사용 (example.component.ts)
import { Component, OnInit } from '@angular/core';
import { ExampleService } from './example.service';
@Component({
selector: 'app-example',
template: `
<div *ngIf="user$ | async as user">
<h1>{{ user.data.user.name }}</h1>
<p>{{ user.data.user.email }}</p>
</div>
`,
})
export class ExampleComponent implements OnInit {
user$ = this.exampleService.getUser('123');
constructor(private exampleService: ExampleService) {}
ngOnInit() {}
}
7. GraphQL의 단점과 주의사항
| 단점 | 설명 | 대안책 |
| 복잡한 쿼리 | 관계가 깊어질수록 쿼리가 무거워질 수 있음 | 쿼리 Depth 제한 |
| 보안 문제 | 쿼리를 통해 민감 정보 접근 가능 | 인증, 인가 필수 처리 |
| 캐시 관리 어려움 | Apollo Client 캐시 충돌 가능성 | 타입 정책(typePolicies) 설정 |
- 추가 문제
- N+1 문제 : 관계형 데이터 조회 시 다수 DB 호출 → DataLoader로 해결
Q. GraphQL의 단점은 무엇인가 ?
➔ 복잡성 증가, 보안 이슈, 캐시 관리 이슈가 있으며, 이를 해결하기 위한 전략이 필요하다.
최종 요약
- GraphQL은 클라이언트가 원하는 데이터만 요청할 수 있는 효율적인 통신 방법
- REST의 Over-fetching/Under-fetching 문제를 해결
- Angular에서는 Apollo Client로 GraphQL을 쉽게 연동
- 실무에서는 쿼리 최적화, 인증 처리, 캐시 설계를 신경 써야 한다 !
참고 링크
'FRONTEND' 카테고리의 다른 글
| React, Vue, Angular 차이점 (0) | 2025.05.26 |
|---|---|
| 실시간 협업 캔버스에서의 동기화 처리 방식 (Yjs 기반) (0) | 2025.05.18 |
| Yjs Awareness로 실시간 사용자 상태 공유하기 (0) | 2025.05.11 |
| 공통 프로젝트 후기 | 프론트엔드 | Kotlin (1) | 2025.03.05 |
| Zustand의 주요 기능과 유틸리티에 대해 알아보기 (1) | 2025.01.19 |