GraphQL은 Facebook에서 만든 Graph Query Language라는 애플리케이션 레이어 쿼리 언어이다. 즉, API를 위한 쿼리 언어이며 타입 시스템을 사용하여 쿼리를 실행하는 서버사이드 런타임이다. GraphQL은 특정한 데이터베이스나 스토리지에 귀속되어 있지 않으며 기존 코드와 데이터에 의해 대체된다.
Sql은 데이터베이스 시스템에 저장된 데이터를 효율적으로 가져오는 것이 목적이지만, GraphQL은 웹 클라이언트가 데이터를 서버로 부터 효율적으로 가져오는 것이 목적이다.
또한, GraphQL은 기존에 사용하고 있는 RESTApi의 한계점을 극복하고자 나온 통신 규약으로 RESTApi를 대체할 수 있다.
REST API의 한계
REST API는 모든 Resource들을 하나의 Endpoint에 연결하고 연결된 Endpoint는 Resource와 관련된 내용만 관리하게 하는 것이다. 단순 서비스 뿐만 아니라 복잡한 서비스 혹은 클라이언트 요청사항에 따라 over-fetching과 under-fetching이 발생한다.
Over-Fetching 예
예를 들어, 사용자의 데이터를 조회하는 /user/ API가 있다고 가정하고 이 때, 사용자 번호: 1 에 해당하는 데이터를 조회한다면 아래와 같은 형태가 된다.
GET /user/1/
response body
{
"user_no": 1,
"user_name": "test",
"usere_grade": "VVIP",
"zip": "11053",
"last_login_timestamp": "2019-08-08 12:11:44",
...
}
여기서 클라이언트에서는 1번에 해당하는 유저의 이름만을 사용하고자 한다고 해도 유저 이름만 반환하는 API가 없다면 위와 같은 /user/1/ API를 호출한 다음, user_name을 가져와 사용해야 합니다. 이때, user_grade, zip 등등의 데이터는 사용하지 않는 데이터도 같이 반환된다. 이와 같이 리소스의 낭비를 바로 Over-Fetching이라 칭합니다.
Under-Fetching
쇼핑몰 서비스의 경우, 로그인한 사용자의 장바구니 정보를 보여준다고 가정하면 여러 API를 호출하게 된다..
/user/1/
/cart/
/notification/
/wish/
...
요청에 맞게 유효한 데이터를 보여주기 위해 여러 API를 호출하게 되는 경우를 Under-Fetching이라 한다.
GraphQL로 문제 해결
GraphQL은 클라이언트에서 자기에 필요한 데이터만을 쿼리할 수 있도록 하여 위에 발생한 문제를 매우 직관적이고 깔끔하게 해결한다. 이를 위해 GraphQL은 클라이언트에서 사용할 Query Language를 정의한다. 클라이언트가 자신에게 필요한 데이터에 대한 Query를 선언해 GraphQL로 넘기면 GraphQL은 Query를 해석해 서버에서 필요한 데이터만 가져온 후 클라이언트에 해당 쿼리에 반환 데이터를 반환한다.
위의 Under-Fetching 문제를 GraphQL을 사용하면 손쉽게 해결할 수 있다.
요청 쿼리
query {
user(user_no: 1) {
user_name
}
}
반환 데이터
{
"data": {
"user": {
"user_name": "jim",
}
}
}
또한 Over-Fetching 문제도 GraphQL을 사용해 해결할 수 있습니다.
요청 쿼리
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": "jim",
"user_grade": "VVIP"
}
}
GraphQL은 쿼리를 선언하면 해당 값에 맞는 데이터만 가져온다. 이는 최근 선언형 패러다임이 절차적으로 쿼리를 처리하는 것이 아닌 선언적으로 쿼리를 처리함으로써 더욱 직관적으로 어떤 데이터가 오는지를 알 수 있다.
장점
- 클라이언트가 필요한 데이터만 반환할 수 있다.
- GraphQL 호출은 단일 왕복으로 처리되며 클라이언트는 오버패칭 없이 요청한 결과만 얻는다.
- 엄격하게 정의된 데이터 유형은 클라이언트와 서버 간 통신 오류를 줄여준다.
- RESP API로 사용할 수 없는 기능을 제공하기 위해 대부분의 오픈소스 GraphQL 확장 기능을 사용할 수 있다.
- GraphQL은 특정 애플리케이션 아키텍처를 지정하지 않으므로 기존 RESP API에 추가하여 기존 API 관리 툴과 연동할 수 있다.
단점
- GraphQL은 데이터 쿼리의 상당 작업을 서버측으로 옮겨 서버 개발자 작업의 복잡성이 커진다.
- 백엔드와 클라이언트 개발자 양쪽으로 러닝 커브가 있다.
- 단순한 서비스에는 사용하기가 복잡하고 학습하는 데 시간이 필요하다.
- 캐싱 기능의 구현이 복잡하다.
- 요청이 텍스트로 날아가기 때문에 파일 전송을 구현하기가 어렵다.
마무리
GraphQL은 애플리케이션 프로그래밍 인터페이스(API) 를 위한 쿼리 언어이자 서버측 런타임으로 클라이언트에게 요청한 만큼의 데이터를 제공하는 데 우선 순위를 둔다.
GraphQL은 API를 더욱 빠르고 유연하며 개발자 친화적으로 만들기 위해 설계되었다. GraphiQL이라고 하는 통합 개발 환경(Integrated Development Environment, IDE) 내에 배포될 수도 있다. REST를 대체할 수 있는 GraphQL은 개발자가 단일 API 호출로 다양한 데이터 소스에서 데이터를 끌어오는 요청을 구성할 수 있도록 지원한다.
또한 GraphQL은 API 유지 관리자에게 기존 쿼리에 영향을 미치지 않고 필드를 추가하거나 폐기할 수 있는 유연성을 부여한다. 개발자는 자신이 선호하는 방식으로 API를 빌드할 수 있으며, GraphQL 사양은 이러한 API가 예측 가능한 방식으로 작동하도록 보장한다.
출처 : 아래의 사이트들을 보면서 큰 공부 하였습니다
https://www.redhat.com/ko/topics/api/what-is-graphql
https://tech.kakao.com/2019/08/01/graphql-basic/
https://kotlinworld.com/330#GraphQL�%B-�%--��%B-�%A-%-C%--�%--%B-�%B-%B-