500===Dev Database/GraphQL
GraphQL과 REST API 비교: 현대 웹 개발에서의 선택 🚀
블로글러
2025. 2. 2. 05:26
오늘은 GraphQL과 REST API를 비교하며, 어떤 상황에서 어떤 방식을 선택하는 것이 유리한지 깊이 있게 알아보겠습니다.
GraphQL과 REST API란? 🤔
REST API
- 정의: REST(Representational State Transfer)는 전통적인 API 디자인 방식입니다.
- 구조: 리소스를 엔드포인트(예:
/users
,/posts
)로 제공하며, HTTP 메서드(GET, POST, PUT, DELETE)를 사용합니다.
특징
- 명시적인 리소스 경로
- 엔드포인트마다 명확한 리소스 단위 (
/users
,/posts
등).
- 엔드포인트마다 명확한 리소스 단위 (
- 여러 번의 요청 가능성
- 복잡한 데이터를 가져오려면, 여러 리소스에 대해 여러 번의 API 요청 필요.
- 고정된 응답 형태
- 서버에서 정해놓은 응답 구조(JSON, XML 등)를 반환합니다.
GraphQL
- 정의: Facebook에서 개발한 API 쿼리 언어로, 클라이언트가 원하는 데이터만 선택해서 요청할 수 있게 해줍니다.
- 구조: 단일 엔드포인트(
/graphql
)를 통해 쿼리(Query), 뮤테이션(Mutation), 구독(Subscription) 등을 수행합니다.
특징
- 단일 엔드포인트
- 모든 요청이
/graphql
에서 처리되어, 엔드포인트가 여러 개 필요 없습니다.
- 모든 요청이
- 유연한 쿼리
- 클라이언트가 필요한 데이터의 구조(필드, 하위 필드 등)를 직접 정의하여 오버페칭(불필요한 데이터)과 언더페칭(필요 데이터 부족) 문제를 해결합니다.
- 스키마 기반
- 서버는 스키마(schema)를 통해 데이터 타입과 가능한 쿼리, 뮤테이션을 정의하고, 클라이언트는 스키마를 바탕으로 정확한 요청을 수행할 수 있습니다.
비유로 이해하기: 뷔페(Rest) vs. 맞춤식 주문(GraphQL) 🍽
REST API를 뷔페에 비유해보면, 한 번의 접시에 특정 메뉴(리소스)들만 담겨져 있어서 메뉴별로 다른 섹션(엔드포인트)에 가서 가져와야 합니다.
필요한 걸 골라먹긴 쉽지만, 원하지 않는 음식(데이터)도 함께 담겨 오버페칭이 될 수 있습니다. 혹은 메뉴가 분산되어 있으면 여러 접시(여러 요청)를 가져와야 하는 언더페칭 문제도 있지요.
GraphQL은 원하는 재료(필드)만 정확히 선택해 요리해주는 맞춤식 레스토랑과 같습니다.
“이 재료와 저 재료만 넣어주세요”라고 정확히 요청할 수 있기 때문에, 필요한 만큼만 받고, 여러 재료도 한 번에 조합할 수 있어 네트워크 요청 수를 줄일 수 있습니다.
하지만 어떤 재료가 가능한지(스키마)를 잘 알아야 주문이 가능하고, 뷔페처럼 간단하지 않을 수 있다는 점이 특징이죠.
REST API vs GraphQL 비교 🥊
비교 항목 | REST API | GraphQL |
---|---|---|
엔드포인트 구조 | 여러 엔드포인트 | 단일 엔드포인트(/graphql ) |
데이터 요청 방식 | 고정된 응답 | 원하는 필드만 쿼리 |
Over-fetching 문제 | 발생 가능 | 최소화 |
Under-fetching 문제 | 여러 번 요청 필요 | 한 번의 요청으로 해결 |
성능 | 요청 횟수 증가 가능 | 네트워크 비용 절감 가능 |
배포/버전 관리 | 새 필드 추가 시 엔드포인트 변경 | 스키마 확장으로 클라이언트가 조절 가능 |
캐싱 | HTTP 캐싱 이용 쉬움 | 별도 캐싱 전략 필요(Apollo Cache 등) |
학습곡선 | 상대적으로 낮음 | 스키마 설계 및 쿼리 작성법 학습 필요 |
GraphQL 구현 예제 🔧
1. GraphQL 서버 (Node.js + Express + Apollo)
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type User {
id: ID!
name: String!
email: String!
}
type Query {
users: [User]
}
`;
const resolvers = {
Query: {
users: () => [
{ id: '1', name: 'John Doe', email: 'john@example.com' },
// 필요하다면 추가 데이터
],
},
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
2. GraphQL 클라이언트 요청 (쿼리 예제)
query {
users {
id
name
email
}
}
- 필요한 필드(id, name, email)만 요청.
- 추가 정보가 필요하다면 필드를 자유롭게 확장 가능.
언제 GraphQL을 선택해야 할까? 🤔
다양한 플랫폼(모바일, 웹, IoT 등)에서 유연한 데이터가 필요할 때
- 예: 모바일은 적은 필드만, 웹은 상세 필드를 필요로 하는 경우.
오버페칭과 언더페칭 문제가 심각할 때
- 예: 여러 테이블 조인이 필요한 복잡한 데이터를 한 번에 불러오고 싶을 때.
다양한 데이터 소스를 조합해야 할 때
- 예: 여러 DB, 외부 API, 마이크로서비스를 한 GraphQL 레이어에서 통합 가능.
반복적인 엔드포인트 업데이트를 줄이고 싶을 때
- 예: 새 필드가 생길 때마다 REST 엔드포인트를 추가/수정하지 않고, GraphQL 스키마만 확장해서 클라이언트가 원하는 데이터 쿼리를 유연하게 구성할 수 있음.
GraphQL이 항상 정답은 아닙니다! 🚨
- 캐싱이 매우 중요할 경우
- REST API의 HTTP 캐싱이 단순하고 효율적일 수 있습니다.
- 간단한 CRUD API
- 테이블처럼 단순 구조로 CRUD만 제공한다면, REST가 더 직관적이고 관리하기 쉬울 수 있습니다.
- 학습 및 도입 비용
- GraphQL 서버와 스키마 설계, Resolver 구현, Apollo 등 추가 라이브러리 학습이 필요합니다.
추가 고려 사항 📝
보안(Security)
- REST와 마찬가지로 인증/인가(Authorization) 로직이 필요합니다.
- GraphQL은 단일 엔드포인트로 모든 요청이 들어오므로, 필드마다 접근 권한 설정을 주의 깊게 해야 합니다.
에러 처리(Error Handling)
- GraphQL에서는 에러가 발생해도 기본 응답 구조(데이터와 에러 정보)를 유지하도록 권장합니다.
- REST처럼 HTTP 상태 코드를 활용하기보다는, GraphQL 에러 객체를 통해 처리하는 패턴이 많습니다.
퍼포먼스 모니터링
- GraphQL은 한 번의 요청에 다수의 리소스 접근이 가능하므로, N+1 쿼리 문제 등 퍼포먼스 이슈가 발생하기 쉽습니다. DataLoader 등 최적화 기술이 필요합니다.
마무리 🎁
- GraphQL과 REST API는 서로 다른 강점이 있으며, 프로젝트 특성에 따라 적절한 선택이 중요합니다.
- REST API는 단순하고 확립된 표준을 토대로 빠르게 구축할 수 있지만, 오버페칭/언더페칭 문제가 발생하기 쉽습니다.
- GraphQL은 맞춤형 요청을 통해 네트워크 사용량을 최적화하고, 여러 소스를 통합하기 쉽지만, 새로운 학습과 인프라 구성이 필요합니다.
결국 선택은 "어떤 기능을 얼마나 유연하게 제공해야 하는가?", "복잡도를 어떻게 관리할 것인가?"에 달려 있습니다.
프로젝트 상황에 맞는 최고의 방식을 고민해보세요! 🚀
📚 참고 자료
- GraphQL 공식 문서 (https://graphql.org/)
- GraphQL 스키마 정의, 쿼리/뮤테이션/구독 등 전반적인 설명 수록.
- Apollo GraphQL Docs (https://www.apollographql.com/docs/)
- GraphQL 서버/클라이언트 구현 예제와 캐싱 전략 등 상세 가이드.
- RESTful Web Services by Leonard Richardson and Sam Ruby, O’Reilly (2007), pp.35–47.
- REST 개념과 사례 연구.
728x90