회사를 구직하다보면 grapthQL을 요구하는 회사가 종종 있었는데 오늘은 유튜브를 보다가 알고리즘에 graphQL에 관한 내용이 떠서 해당 내용을 공부해 보았다.
GraphQL(GQL)이란?
Facebook에서 만든 Graph Query Language로 어플리케이션 레이어 쿼리 언어이다.
GQL은 Structed Qurery Language(이하 SQL)와 마찬가지로 쿼리 언어이다.
GQL vs SQL
SQL
: 데이터베이스 시스템에 저장된 데이터를 효율적으로 가져오는 것이 목적
GQL
: 웹 클라이언트가 데이터를 서버로 부터 효율적으로 가져오는 것이 목적
SQL의 문장(statement)은 주로 백엔드 시스템에서 작성하고 호출하는 반면,
GQL의 문장은 주로 클라이언트 시스템에서 작성하고 호출한다.
정리
GQL은 API를 위한 쿼리 언어이며, 타입 시스템을 사용하여 쿼리를 실행하는 서버사이드 런타임이다.
GraphQL은 특정한 데이터베이스나 스토리지에 귀속되어 있지 않으며, 기존 코드와 데이터에 의해 대체된다.
SQL 쿼리 예시
SELECT user_id, name, sex, weight
FROM testdatabase;
GQL 쿼리 예시
{
hero {
name
friends {
name
}
}
}
서버사이드 GQL 어플리케이션은 GQL로 작성된 쿼리를 입력으로 받아 쿼리를 처리한 결과를 다시 클라이언트로 돌려준다.
HTTP API 자체가 특정 데이터베이스나 플렛폼에 종속적이지 않은 것 처럼 마찬가지로
GQL 역시 어떠한 특정 데이터베이스나 플렛폼에 종속적이지 않다.
(심지어 네트워크 방식에도 종속적이지 않다. 일반적으로 GQL의 인터페이스간 송수신은
네트워크 레이어 L7의 HTTP POST 메서드와 웹소켓 프로토콜을 활용한다.
필요에 따라서는 얼마든지 L4의 TCP/UDP를 활용하거나 심지어 L2 형식의 이더넷 프레임을 활용 할 수도 있다.)
REST API의 한계
REST API의 개념을 간단하게 말하자면
- 모든 Resource들을 하나의 Endpoint에 연결
- 연결된 Endpoint는 Resource와 관련된 내용만 관리
- 복잡한 정보 요구시 Over-Fetching과 Under-Fetching이 발생
: 단순한 서비스에서는 아주 좋지만 다른 엔드포인트에서 여러개의 정보를 가져오는 등의 복잡한 요구시 좋지 않음 - 비슷하지만 Endpoint가 다른 API가 많이 파생
: REST API로 여러 환경에서 필요한 정보들을 Resource 별로 Endpoint를 갖도록 구현하는 것은 어려움
Over-Fetching
필요한 정보보다 더 많은 정보를 받는 것을 Over-Fetching이라고 한다
필요 이상의 리소스 낭비가 된다.
예를 들어 사용자의 데이터를 조회하는 API가 있다고 가정하고
이 때, 사용자 ID: 1 에 해당하는 데이터를 조회한다면 아래와 같은 형태가 된다.
GET /user/1/
response body
{
"user_id":1,
"user_name": "test",
"user_grade": "3",
"zip": "1234",
...
}
여기에서 클라이언트는 1번에 해당하는 유저의 이름만을 사용하고자 한다고 해도
유저 이름만 반환하는 API가 없다면 위와 같은
/user/1/API를 호출한 다음, user_name을 가져와 사용해야한다.
이 때, user_grade, zip 등등의 데이터는 사용하지 않는 데이터도 같이 반환받는다.
이는 곧 리소스의 낭비라고 볼 수 있고 이와 같은 낭비를 Over-Fetching이라 한다.
Under-Fetching
필요한 정보보다 적은 정보를 받는 경우를 Under-Fetching이라고 한다
이경우 2개이상의 엔드포인트를 사용해서 정보를 요청하여야 한다.
예를들어 쇼핑몰 서비스의 경우, 로그인한 사용자의 장바구니 정보를 보여준다고 가정하면 여러 API를 호출하게 된다.
/user/1/
/cart/
/notification/
/wish/
...
요청에 맞게 유효한 데이터를 보여주기 위해 여러 API를 호출하게 되는 경우를 Under-Fetching이라 한다.
GraphQL
GraphQL은 위에서 설명한 것처럼 REST API의 한계(Under-Fetching, Over-Fetching)를 극복하고자 나왔다.
Endpoint는 보통 1개만 생성하고 클라이언트에게 필요한 데이터는 클라이언트가 직접 쿼리를 작성, 호출하여 반환 받는다.
요청 쿼리
query{
user(user_id:1){
user_name
}
}
반환 데이터
{
"data": {
"user": {
"user_name": "test",
}
}
}
요청 쿼리
query{
cart{
product_name
price
}
notification{
is_read
}
user(user_id:1){
user_name
user_grade
}
}
반환 데이터
{
"cart": [{
"product_name": "shoes",
"price": 12000
}, ...],
"notifications": [{
is_read: true
}],
"user": {
"user_name": "test",
"user_grade": "3"
}
}
장점
- 클라이언트가 필요한 데이터를 한번에 반환할 수 있다.
- REST API의 Over-Fetching, Under-Fetching을 해결 할 수 있다.
- 확장이 용이하다.
단점
- 백엔드, 클라이언트 개발자 양쪽 다 학습이 필요하다
: 단순한 서비스에서는 사용하기가 복잡하다. - 캐싱 기능의 구현이 복잡하다.
- 요청이 text로 날아가기 때문에 File 전송 등을 구현하기가 어렵다.
정리
즉 원하는 데이터의 요청을 백엔드에서 관리를 해서 보내줄것이냐 프론트엔드에서 관리해서 보내줄 것이냐가 관건으로 보인다.
REST API와 GraphQL둘다의 장단점이 있으니 상황에 맞추어서 사용하면 좋을 것 같다.
'언어(JS,TS) > 네트워크' 카테고리의 다른 글
네트워크 [Study: 인터넷 주소를 입력하면 일어나는 일들] (0) | 2025.05.10 |
---|---|
HTTP [정보: 쿠키옵션] (0) | 2022.05.05 |
네트워크 [책정보 요약 : TCP/IP가 보이는 그림책] (0) | 2022.04.30 |