-
Notifications
You must be signed in to change notification settings - Fork 0
Description
📝 Graphql과 REST API, 그리고 BFF
📚 주제:
GraphQL, REST API, 그리고 Backend for Frontend(BFF)의 개념과 차이점을 비교하고, 각각의 장단점과 활용 사례를 조사한다.
🎯 스터디 목표
GraphQL과 REST API의 기본 개념을 이해하고, BFF의 필요성과 역할을 분석하여 실무에서 적절한 아키텍처를 선택할 수 있도록 한다.
📖 핵심 내용:
Grpahql
GraphQL은 쿼리(Query) 기반 API로, 클라이언트가 필요한 데이터만 선택적으로 요청 할 수 있는 방식
- 단일 엔드포인트(/grpahql)를 사용하여 필요한 필드만 선택 하고, 한 번의 요청으로 여러 데이터를 가져올 수 있다.
장점
- 오버페칭 방지 → 필요한 데이터만 가져올 수 있음
- 언더페칭 방지 → 한 번의 요청으로 연관 데이터까지 가져올 수 있음
- 유연한 API 확장 가능 → 필드 추가 시 기존 API 변경 없이 사용 가능
단점
- 초기 설정이 복잡 → 스키마 정의 및 백엔드 설정 필요
- 캐싱이 어렵다 → 모든 요청이
POST로 처리될 경우 CDN 캐싱 활용이 어려움 - N+1 문제 발생 가능 → 리졸버 최적화 필요 (DataLoader 사용)
grpahql의 리졸버(resolver)?
👉 graphql에서 쿼리를 해석하고 데이터를 반환하는 함수
즉, 클라이언트가 요청한 데이터를 백엔드에서 찾아서 반환하는 역할
근데 왜 리졸버가 더 많아져?
-
graphql은 각 필드마다 리졸버를 따로 만들어야 하기 때문!
-
예시
✔ 사용자 정보와 게시글을 함께 요청하는 GraphQL 쿼리
query { user(id: 1) { name posts { title content } } }✔ 백엔드 리졸버 (각 필드별로 따로 존재)
const resolvers = { Query: { user: (_, { id }) => getUserById(id) // 사용자 정보 가져오는 리졸버 }, User: { posts: (parent) => getPostsByUserId(parent.id) // 사용자의 게시글 가져오는 리졸버 } };📌 ➡
user리졸버와posts리졸버가 따로 있음!📌 ➡ 데이터가 많아질수록 리졸버가 계속 증가하게 됨.
📌 ➡ 유지 보수가 어려워짐!!
📌 ➡ 데이터 타입마다 리졸버가 계속 추가됨
📌➡ 코드가 많아지고, 유지보수가 어려워짐
📌➡ 각 리졸버가 따로 동작하다 보면
N+1 문제발생 가능
Graphql의 N+1 문제
데이터를 요청할 때 비효율적인 쿼리 실행으로 인해 발생하는 성능 문제인데, 리졸버를 사용하여 데이터를 가져올 때 발생
예시 사용자 목록과 각 사용자의 게시글 리스트를 가져오는 graphql 쿼리를 작성
query { users { id name posts { id title } } }💡 실행 흐름 (문제 발생 과정)
users데이터를 가져오기 위해 1개의 쿼리 실행SELECT * FROM users; -- (1개의 쿼리 실행)
posts데이터를 가져오기 위해 N개의 쿼리 실행SELECT * FROM posts WHERE user_id = 1; -- (N번 실행) SELECT * FROM posts WHERE user_id = 2; SELECT * FROM posts WHERE user_id = 3; ... SELECT * FROM posts WHERE user_id = N;👩🏻💻
users데이터를 먼저 가져온 후, 각 사용자별posts를 개별적으로 가져오면 총 N+1개의 쿼리가 발생(1개의users조회 + N개의posts조회)사용자가 많아질수록 (
N이 커질수록) 데이터베이스 쿼리 요청이 기하급수적으로 증가하게 되고, 이는 성능 저하를 초래하게 된다.
해결 방법
- DataLoader(Facebook이 만든 라이브러리)를 활용 - 가장 많이 사용
- 원리는 쿼리 갯수를 1개로 줄여 성능을 향상 시키는 것
- data loader 사용시 batching(일괄 처리)와 caching(캐싱)을 적용하여 쿼리 갯수를 줄이는 것
- 원리는 쿼리 갯수를 1개로 줄여 성능을 향상 시키는 것
REST API
REST API는 리소스 기반의 HTTP 요청 방식으로, 각 리소스(데이터)에 대해 고정된 엔드포인트(URL)을 사용해 요청하는 방식
장점
- 구조가 단순하고 익숙함 (RESTful 원칙 따름)
- 캐싱 활용 가능 (브라우저 및 CDN 지원)
- HTTP 상태 코드 활용 가능 (200, 404, 500 등)
단점
- 오버페칭(Over-fetching) → 불필요한 데이터까지 포함될 수 있음
- 언더페칭(Under-fetching) → 원하는 데이터를 위해 여러 번 요청해야 할 수도 있음
- API 버전 관리 필요 → 새로운 필드 추가 시
/v1/,/v2/같은 엔드포인트 추가 필요
오버 페칭
👉 필요한 데이터보다 더 많은 데이터를 받아오는 문제
즉, 클라이언트가 원하지 않는 정보까지 같이 전달되는 상황
예시 사용자의 이름(name)만 필요한 상황
REST 방식 (오버페칭 문제 발생)
GET /users/1
{
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Seoul"
},
"phone": "010-1234-5678"
}
- 클라이언트는 이름(name)만 필요한데,
- 이메일, 나이, 주소, 전화번호 등 불필요한 정보까지 받아옴
- 👉 불필요한 데이터 전송으로 네트워크 비용 증가 & 성능 저하
GraphQL 방식 (오버페칭 해결)
query {
user(id: 1) {
name
}
}
{ "data": { "user": { "name": "Alice" } } }
오직 필요한 name 필드만 가져오기 때문에 오버페칭 방지 가능! 🔥
언더페칭
👉 필요한 데이터를 한 번의 요청으로 가져오지 못하고, 여러 번 요청해야 하는 문제
예시 클라이언트에서 특정 사용자(user)와 해당 사용자의 게시글(posts)을 한 번에 가져오고 싶다면?
REST 방식
GET /users/1→ 사용자 정보 요청GET /users/1/posts→ 해당 사용자의 게시글 요청
이렇게 2번의 API 호출이 필요
만약 사용자와 댓글 정보까지 같이 가져오려면 3개의 요청이 필요!
언더페칭은 API가 분리 되어 있어 원하는 데이터를 한 번에 가져오지 못하는 경우 발생
GraphQL 방식
query { user(id: 1) { name posts { title comments { text } } } }
한 번의 요청으로 모든 데이터를 가져올 수 있음.
BFF(backend for frontend)
- 프론트엔드 애플리케이션의 특성에 맞게 백엔드 API를 제공하는 아키텍처 패턴
- BFF는 특정 프론트엔드 클라이언트(웹, 모바일, 데스크톱 등)에 최적화된 API를 제공
- BFF는 프론트엔드와 백엔드 사이의 '맞춤형 API 레이어' 역할
📌 BFF와 GraphQL 비교
| BFF | GraphQL | |
|---|---|---|
| 개발 방식 | 프론트엔드별 맞춤형 API 서버 개발 | 클라이언트가 원하는 데이터만 요청 가능 |
| 데이터 가공 | BFF가 데이터 조합 및 가공 | GraphQL 서버가 데이터 조합 |
| 오버페칭 해결 | 맞춤 API 제공 | 원하는 필드만 요청 가능 |
| 언더페칭 해결 | 여러 API를 조합해서 제공 | 한 번의 요청으로 필요한 데이터 제공 |
📌 BFF vs GraphQL 차이점
- GraphQL은 단일 API로 해결, 하지만 BFF는 맞춤형 API 서버를 추가로 운영
- GraphQL을 사용하면 BFF 없이도 프론트엔드가 필요한 데이터만 요청 가능
💡 참고 자료:
https://graphql.org/learn/
https://tech.kakao.com/posts/364
https://blog.toktokhan.dev/rest-api-vs-graphql-7348f54a220b
https://blog.postman.com/graphql-vs-rest/
https://fe-developers.kakaoent.com/2022/220310-kakaopage-bff/
https://docs.github.com/ko/rest/about-the-rest-api/comparing-githubs-rest-api-and-graphql-api?apiVersion=2022-11-28
https://kosaf04pyh.tistory.com/341