[REST API] [GraphQL]
/users -> { id, name, email } +--> { name, posts { title } }
/posts -> { id, title, content} |
|
( Query ) -->> /graphql
|
|
+--> { name, email }
API 설계를 앞두고 'REST를 써야 하나, GraphQL을 써야 하나' 고민해 본 경험, 다들 있으시죠? 저 역시 그랬습니다. 클라이언트에서 필요한 건 사용자의 이름뿐인데, 응답으로는 거대한 JSON 객체가 날아오는 '오버페칭(Over-fetching)' 문제. 반대로 화면 하나를 그리기 위해 API를 대여섯 번 호출해야 하는 '언더페칭(Under-fetching)'의 늪에 빠지기도 했습니다. 이런 비효율을 해결하기 위해 등장한 것이 바로 GraphQL입니다.
이 글을 끝까지 읽으시면 두 기술의 핵심 차이를 명확히 이해하고, 여러분의 다음 프로젝트에 어떤 아키텍처가 더 적합할지 확신을 갖고 결정할 수 있게 될 겁니다.
⚡ TL;DR
- REST API: 리소스마다 정해진 엔드포인트로 통신하며, HTTP 표준 캐싱에 유리합니다[2][6].
- GraphQL: 단일 엔드포인트를 사용하며, 클라이언트가 데이터 구조를 직접 결정해 통신 효율을 극대화합니다[1][3][6].
목차
- 배경: GraphQL은 왜 등장했을까?
- 핵심 개념 비교
- 요청 방식 비교: 코드 레벨에서 살펴보기
- 언제 무엇을 선택해야 할까? (Best Practice)
- 마치며 & 참고자료
1. 배경: GraphQL은 왜 등장했을까?
GraphQL은 2012년 페이스북이 모바일 앱의 성능 개선을 위해 내부적으로 개발하여 2015년에 오픈소스로 공개한 기술입니다[4]. 당시 페이스북은 모바일 환경에서 REST API의 고질적인 문제, 즉 오버페칭과 언더페칭으로 인한 네트워크 비효율을 해결해야 했습니다[3][4].
기존 REST API 방식으로는 클라이언트의 다양한 요구사항을 유연하게 처리하기 어려웠고, 이 문제를 해결하기 위해 '클라이언트가 필요한 데이터만 정확하게 요청'하는 새로운 접근법이 필요했습니다. 이것이 바로 GraphQL의 탄생 배경입니다[4][10].
✅ 주요 용어 정리
- REST API: HTTP 메서드(GET, POST 등)와 여러 URL(엔드포인트)을 조합해 통신하는 API 설계 아키텍처 스타일입니다[1][2].
- GraphQL: API를 위한 쿼리 언어(Query Language)이자 사양으로, 클라이언트가 서버로부터 필요한 데이터를 효율적으로 가져올 수 있게 해줍니다[1][2].
- Over-fetching: 클라이언트가 필요한 데이터보다 더 많은 정보를 서버로부터 받는 현상입니다[4][6].
- Under-fetching: 원하는 정보를 모두 얻기 위해 클라이언트가 여러 번의 API 요청을 보내야 하는 현상입니다[4][6].
2. 핵심 개념 비교
GraphQL은 클라이언트가 단일 엔드포인트에 원하는 데이터의 구조를 담아 요청하면, 서버가 그에 맞춰 정확한 데이터를 반환하는 API 쿼리 언어입니다[5][6].
REST와 GraphQL의 가장 큰 차이는 데이터를 요청하고 응답하는 방식에 있습니다[1]. REST는 서버가 정의한 여러 엔드포인트에서 고정된 구조의 데이터를 제공합니다[5][6]. 반면 GraphQL은 클라이언트가 하나의 엔드포인트에 '이런 모양의 데이터가 필요하다'고 쿼리로 명시하면, 서버는 그 모양 그대로 데이터를 만들어 응답합니다[3][9].
예를 들어, GitHub에서 특정 사용자의 팔로워 10명과, 그 팔로워 각각의 팔로워 10명의 로그인 아이디를 가져온다고 가정해봅시다[5].
- REST API 방식
GET /user/followers
를 호출해 첫 팔로워 10명의 정보를 받습니다. (필요 없는 정보까지 포함됨)- 받아온 팔로워 10명 각각에 대해
GET /users/{username}/followers
를 총 10번 더 호출합니다. - 총 11번의 요청이 필요하며, 매번 불필요한 데이터를 함께 받게 됩니다[5].
- GraphQL 방식
단 한 번의 요청으로 모든 정보를 가져올 수 있습니다. 클라이언트가 응답의 구조를 미리 알고 있으며, 필요한 데이터만 정확히 받게 됩니다[5]. 단일 요청으로 필요한 모든 정보를 계층적으로 가져옴
{ viewer { followers(first: 10) { nodes { login followers(first: 10) { nodes { login } } } } } }
3. 요청 방식 비교: 코드 레벨에서 살펴보기
상황: 특정 사용자(id: 1)의 이름과 그가 작성한 게시물들의 제목만 가져오고 싶습니다.
① REST API 방식
REST API는 일반적으로 리소스별로 엔드포인트가 나뉘어 있습니다[3]. 따라서 두 종류의 정보를 얻으려면 최소 두 번의 요청이 필요합니다.
- Step 1: 사용자 정보 요청
- 클라이언트는 사용자 정보를 얻기 위해
/users/{id}
엔드포인트에 요청을 보냅니다. GET example.com/users/1
- 응답 (Response): 서버는 사용자의 모든 정보를 담은 고정된 구조의 JSON을 반환합니다. 이름 외에 이메일, 가입일 등 불필요한 정보가 포함됩니다(오버페칭)[4].
{ "id": 1, "name": "Leanne Graham", "email": "Sincere@april.biz", "address": { ... } }
- 클라이언트는 사용자 정보를 얻기 위해
- Step 2: 게시물 정보 요청
- 다음으로, 해당 사용자의 게시물 목록을 얻기 위해 다른 엔드포인트에 요청합니다.
GET example.com/users/1/posts
- 응답 (Response): 게시물의 제목뿐만 아니라 내용, 작성자 ID 등 모든 정보를 받게 됩니다[4].
결과적으로 클라이언트는 두 번의 HTTP 요청을 보내고, 받은 응답에서 필요한 데이터만 골라 조합해야 합니다.[ { "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit..." }, ... ]
② GraphQL 방식
GraphQL은 보통 모든 요청을 /graphql
이라는 단일 엔드포인트에서 처리합니다[3][8][9]. 클라이언트는 원하는 데이터의 구조를 쿼리로 만들어 보냅니다.
- Step 1: 단일 쿼리 요청
- 클라이언트는 사용자 이름과 게시물 제목을 명시한 쿼리를 작성하여
/graphql
엔드포인트에 POST 방식으로 요청합니다. POST example.com/graphql
- 요청 본문 (Request Body):
query { user(id: "1") { name posts { title } } }
- 클라이언트는 사용자 이름과 게시물 제목을 명시한 쿼리를 작성하여
- 응답 (Response): 서버는 요청받은 쿼리의 구조와 정확히 일치하는 JSON을 반환합니다. 불필요한 데이터 없이 깔끔합니다[5].
{ "data": { "user": { "name": "Leanne Graham", "posts": [ { "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit" }, ... ] } } }
- 단 한 번의 요청으로 오버페칭이나 언더페칭 없이 원하는 모든 데이터를 얻을 수 있습니다[3][5].
4. 언제 무엇을 선택해야 할까? (Best Practice)
GraphQL이 REST API의 단점을 보완하며 등장했지만, 모든 면에서 우월한 것은 아닙니다[6]. 각 기술은 장단점이 명확하므로 프로젝트의 특성과 요구사항에 따라 적합한 것을 선택해야 합니다[2][6].
비교 항목 | REST API | GraphQL |
---|---|---|
데이터 요청 | 서버가 정의한 고정된 구조로 반환[5][6] | 클라이언트가 원하는 필드만 유연하게 요청[2][6] |
엔드포인트 | 다수의 엔드포인트 (e.g., /users , /posts )[3][6] |
단일 엔드포인트 (e.g., /graphql )[3][6][8] |
Over/Under-fetching | 발생 가능성 높음[4][6] | 구조적으로 방지[5][6] |
캐싱 | HTTP 표준 캐싱을 통해 쉽게 구현 가능[2][6] | 동적 쿼리로 인해 캐싱 구현이 상대적으로 복잡[2][6] |
적합한 프로젝트 | 단순한 CRUD API, HTTP 캐싱이 중요한 서비스[6] | 데이터 요구사항이 다양한 모바일 앱, 복잡한 시스템[2][6] |
5. 마치며
오늘 우리는 REST API와 GraphQL의 핵심적인 차이점과 각각의 장단점을 살펴보았습니다.
- 첫째, REST는 리소스 중심의 아키텍처로 단순하고 직관적이지만, 오버페칭과 언더페칭 문제가 발생할 수 있습니다[4].
- 둘째, GraphQL은 클라이언트 중심의 쿼리 언어로, 단일 엔드포인트를 통해 데이터 통신을 최적화합니다[3][8].
- 셋째, 두 기술은 대체재가 아닌 보완재의 관계입니다. 프로젝트의 성격에 맞는 기술을 선택하는 것이 중요합니다[2][6].
실제 프로젝트에 적용할 때는 클라이언트의 종류가 다양하고 요구하는 데이터 조합이 복잡하다면 GraphQL을, 서버 간 통신이나 파일 업로드, 단순한 CRUD API가 주를 이룬다면 REST API를 우선적으로 고려해 보세요. 때로는 인증은 REST로, 데이터 조회는 GraphQL로 처리하는 하이브리드 방식이 최고의 선택이 될 수도 있습니다[2].
이 글이 여러분의 기술 스택 결정에 도움이 되었기를 바랍니다.
궁금한 점이 있다면 언제든지 댓글로 남겨주세요! ❤️
참고자료
- AWS: GraphQL과 REST API 비교
- GitHub: GitHub의 REST API 및 GraphQL API 비교
- IBM: GraphQL과 REST API: 차이점은 무엇인가요?
[1] https://aws.amazon.com/ko/compare/the-difference-between-graphql-and-rest/
[2] https://blog.toktokhan.dev/rest-api-vs-graphql-7348f54a220b
[3] https://hahahoho5915.tistory.com/63
[4] https://velog.io/@jiyaho/GraphQL%EA%B3%BC-REST-API-%EC%B0%A8%EC%9D%B4-%EB%B9%84%EA%B5%90
[5] https://docs.github.com/ko/enterprise-cloud@latest/rest/about-the-rest-api/comparing-githubs-rest-api-and-graphql-api
[6] https://epicarts.tistory.com/176
[7] https://www.ibm.com/kr-ko/think/topics/graphql-vs-rest-api
[8] http://dev.blog.sellmate.co.kr/post/graphql-restapi-comparison/
[9] https://velog.io/@djaxornwkd12/REST-API-vs-GraphQL-%EC%B0%A8%EC%9D%B4%EC%A0%90-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0
[10] https://aiday.tistory.com/84