🧑💻 GraphQL이란?#
GraphQL은 클라이언트가 서버로부터 데이터를 효율적으로 요청하고 가져오기 위해 설계된 데이터 쿼리 언어입니다. Facebook에서 2015년에 공개했으며, 하나의 엔드포인트를 통해 필요한 데이터만 정확히 요청할 수 있는 API 설계 방식입니다.
- 클라이언트 주도형 쿼리: 클라이언트가 원하는 데이터 구조를 지정하여 요청 가능
- 스키마 기반: API의 데이터 구조와 타입을 명확히 정의
- 유연성: 다양한 데이터를 단일 요청으로 가져올 수 있음
🔍 GraphQL의 탄생배경과 목표#
GraphQL은 기존 REST API가 가진 한계를 극복하고, 데이터 전송과 요청 방식을 더 효율적이고 유연하게 만들기 위해 만들어졌습니다.
- Over-fetching과 Under-fetching 문제 해결
REST API에서는 클라이언트가 필요한 데이터보다 더 많은 데이터를 가져오거나(Over-fetching), 부족해서 여러번 요청을 보내야 하는(Under-fetching) 경우가 발생하곤 했습니다. GraphQL은 클라이언트가 필요한 데이터만 요청할 수 있도록하여 이러한 한계점을 해결하고자 했습니다.
- 단일 엔드포인트 제공
REST API는 여러 리소스에 대해 다양한 엔드포인트를 필요로 하는 반면에, GraphQL은 하나의 엔드포인트에서 모든 데이터를 관리할 수 있도록 설계되었습니다. 물론 서버 설계와 구현 방식에 따라 여러 엔드포인트를 두는 것도 가능합니다.
- 스키마 기반의 강력한 타입 시스템
GraphQL은 스키마를 통해 데이터 구조와 타입을 명확히 정의합니다. 이를 통해 클라이언트와 서버 간의 데이터 일관성이 높아지고, 자동화된 문서화 도구를 제공하여 문서화 작업이 간편하게 이루어집니다.
📲 GraphQL 활용 사례#
GraphQL은 Facebook, Shopify, Netflix, GitHub 등 다양한 글로벌 플랫폼에서 데이터 요청과 처리의 효율성을 높이기 위해 활용되고 있습니다. 어떤 기능에 사용되는지 간략하게 정리했습니다.
- Facebook
사용자의 피드, 프로필, 페이지 관리 등에서 클라이언트가 필요한 데이터를 정확히 요청할 수 있도록 사용합니다. 예를 들어, 뉴스 피드에서 게시물, 댓글, 좋아요 데이터를 한 번의 쿼리로 가져올 수 있어 사용자 인터페이스의 성능을 극대화합니다.
- Shopify
제품, 주문 관리 및 고객 데이터를 처리하는 데dp GraphQL을 활용합니다. 관리자 대시보드에서 특정 제품의 재고, 가격, 변형 옵션 등을 한 번의 요청으로 가져오는 방식으로, 데이터를 효율적으로 관리하며 UI 속도를 개선합니다.
- Netflix
사용자 맞춤 추천과 콘텐츠 정보를 제공하기 위해 GraphQL을 사용합니다. 사용자가 영화나 드라마를 탐색할 때 리뷰, 출연진, 콘텐츠 유형 등 다양한 정보를 한 번의 요청으로 받아올 수 있도록 하여, 디바이스별로 최적화된 데이터를 제공합니다.
- GitHub
리포지토리, 커밋, 이슈 관리에 GraphQL API를 활용합니다. 이를 통해 사용자들은 특정 리포지토리의 커밋 내역, 풀 리퀘스트 상태, 이슈 코멘트 등을 유연하게 조회하고 관리할 수 있습니다.
💡 GraphQL vs REST API - 차이점#
GraphQL과 REST API의 주요 차이점을 간략히 비교하기 전에, 기본적인 GraphQL의 세 가지 주요 개념을 잠시 짚고 넘어가겠습니다.
- Query: 데이터 요청
- Mutation: 데이터 변경
- Subscription: 실시간 데이터 처리
- Resolver: 쿼리나 뮤테이션에 대한 실제 데이터 처리 로직을 구현하는 함수
활용할 예제 코드의 출처와 기술 스택은 다음과 같습니다.
ciscorn/starlette-graphene3 GitHub 리포지토리
기술 스택#
기술 스택 | 설명 |
---|
Python | 프로젝트의 주요 프로그래밍 언어 |
Starlette | 비동기 기반의 웹 프레임워크 |
Graphene | GraphQL API 서버 라이브러리 |
- 데이터 모델
1
2
3
| class User(graphene.ObjectType):
id = graphene.ID()
name = graphene.String()
|
1
2
3
| class User:
id: str
name: str
|
- 차이점
GraphQL은 스키마 기반의 데이터 타입을 명시적으로 정의하고, REST API는 단순 클래스 속성으로 타입을 정의합니다. GraphQL은 더 구조화된 데이터 모델링을 제공하며, REST API는 간단하고 직관적인 방식으로 정의됩니다.
- Query
1
2
3
4
| class Query(graphene.ObjectType):
me = graphene.Field(User)
def resolve_me(root, info):
return {"id": "john", "name": "John"}
|
1
2
3
4
| @app.get("/me")
async def get_me():
user = User(user_id="john", name="John")
return {"id": user.id, "name": user.name}
|
- 차이점
GraphQL의 Query는 스키마에서 정의된 필드를 통해 데이터를 요청하고, 리졸버를 통해 처리된 결과를 반환합니다. REST API의 GET 요청은 특정 URL 경로에서 데이터를 가져오는 방식으로, HTTP 메서드와 엔드포인트에 따라 데이터를 처리하는 방식입니다.
- Mutation
1
2
3
4
5
6
7
8
| class FileUploadMutation(graphene.Mutation):
class Arguments:
file = Upload(required=True)
ok = graphene.Boolean()
def mutate(self, info, file, **kwargs):
return FileUploadMutation(ok=True)
class Mutation(graphene.ObjectType):
upload_file = FileUploadMutation.Field()
|
1
2
3
4
| @app.post("/upload-file")
async def upload_file(file: UploadFile = File(...)):
# 파일 처리 로직
return JSONResponse(content={"ok": True, "filename": file.filename})
|
- 차이점
GraphQL의 Mutation은 상태 변경 작업을 처리하는 데 사용되며, 입력 인자와 리졸버를 통해 데이터를 수정하거나 처리합니다. REST API의 POST 요청은 데이터를 서버에 전송하고, 상태 변경을 처리하는 방식으로 파일 업로드나 데이터 수정 작업을 처리합니다.
- Subscription
1
2
3
4
5
6
| class Subscription(graphene.ObjectType):
count = graphene.Int(upto=graphene.Int())
async def subscribe_count(root, info, upto=3):
for i in range(upto):
yield i
await asyncio.sleep(1)
|
1
2
3
4
5
6
7
| @app.websocket("/ws/subscribe-count/")
async def websocket_subscribe_count(websocket: WebSocket, upto: int = 3):
await websocket.accept()
for i in range(upto):
await websocket.send_json({"count": i})
await asyncio.sleep(1)
await websocket.close()
|
- 차이점
GraphQL의 Subscription은 실시간 데이터 업데이트를 위해 클라이언트와 서버 간의 연결을 유지합니다. 특정 이벤트나 변화에 대한 데이터를 비동기적으로 전달하는 반면에, REST API의 WebSocket을 이용한 구독은 클라이언트가 서버에 연결하여 실시간으로 데이터를 주고받는 방식으로, 특정 경로(/ws/subscribe-count/)를 통해 연결을 유지하고 데이터를 송수신합니다.
💡 GraphQL vs REST API - 장단점#
특징 | GraphQL | REST API |
---|
장점 | - 클라이언트 맞춤형 요청: 필요한 데이터만 정확히 요청 가능 | - 단순하고 직관적인 설계: URL과 HTTP 메서드를 통한 간단한 리소스 접근 |
| - 효율적인 데이터 전달: 필요한 필드만 선택하여 요청 가능 | - 널리 사용되는 표준: 다양한 라이브러리와 툴 지원 |
| | |
단점 | - 복잡한 초기 설정: 서버 설정, 스키마 정의, 리졸버 설정 등 많은 단계 필요 | - 오버패칭, 언더패칭 문제: 불필요한 데이터 요청 또는 부족한 데이터 요청 |
| - 캐싱 지원 부족: 다양한 쿼리와 파라미터로 인한 캐시 관리 어려움 | - 반복적인 API 업데이트 필요: 버전 관리와 API 확장이 번거로움 |
| | |
👋 마치며#
해당 포스트에서는 GraphQL과 REST API의 차이점과 각 기술의 장단점에 대해 간략하게 살펴보았습니다. 두 기술은 각각의 특성과 활용 사례에 따라 적합한 환경이 다르기 때문에, 상황에 맞는 적절한 기술을 선택하는 것이 중요하다고 생각합니다. 부족한 점이 많은 내용이지만, GraphQL과 REST API를 이해하고 실무에서 어떤 방식으로 활용할 수 있을지 고민하는 데에 적게나마 도움이 되었기를 바랍니다.
읽어주셔서 감사드리며, 마무리하겠습니다.
감사합니다!