Graph QL(이하 gql)은 Structed Query Language(이하 sql)와 마찬가지로 쿼리 언어입니다. 하지만 gql과 sql의 언어적 구조 차이는 매우 큽니다.
sql은 데이터베이스 시스템에 저장된 데이터를 효율적으로 가져오는 것이 목적이고, gql은 웹 클라이언트가 데이터를 서버로 부터 효율적으로 가져오는 것이 목적입니다.
sql의 문장(statement)은 주로 백앤드 시스템에서 작성하고 호출 하는 반면, gql의 문장은 주로 클라이언트 시스템에서 작성하고 호출 합니다. - Kakao tech
GraphQL은 REST API와 비교할 수 있다.
위에서 본 것처럼 GraphQL은 Resource를 가져오기 위해 쿼리를 이용한 방식이며, REST API는 REST규칙에 의해 Resource를 요청하는 방식이다.
이 두가지는 Resource의 결정 부분과, 요청 부분에서 차이가 있다.
서버
에서 결정한다.client
단에서 요청 시 결정한다.여러 번의 요청
이 필요하다.한번의 요청
에서 여러 Resource에 접근할 수 있다. REST:
/user
,/profile
,/comment
,/item
GraphQL:/graphql
하나의 Endpoint
GraphQL을 긍정적으로 보는 사람도 많지만, 경험한 사람들 중에는 비추천하는 사람도 많아보인다.
GraphQL의 결정적인 장점으로는 데이터를 필요한 만큼 가져다 쓸 수 있다는 것, 결정적인 단점으로는 캐싱을 특정 Endpoint마다 지정할 수 없다는 것이다.
REST API와는 다르게 Overfetching이나 Underfetching등의 문제가 발생하지 않는다.
Overfetching: 원하는 data 이상의 정보를 요청받는 것.
Underfetching: 원하는 data의 정보를 요청받기 위해 여러번 요청을 보내는 것, 네트워크를 통해 여러번 접근 하여 리소스 낭비.
HTTP의 캐싱 전략은 각각 URL에 각자의 정책을 설정하는 방식으로 이루어 지는데, REST API는 이를 그대로 사용이 가능하다.
// 1. Direct File Upload
POST /avatars HTTP/1.1
Host: localhost:3000
Content-Type: image/jpeg
Content-Length: 284
raw image content
// 2. Upload from URL
POST /avatars HTTP/1.1
Host: localhost:3000
Content-Type: application/json
{
"image_url" : "https://example.org/pic.png"
}
GraphQL은 하나의 URL로 처리하기에, HTTP에서 제공하는 캐싱 전략을 그대로 사용하는 것은 불가능하다.
POST /graphql HTTP/1.1
Host: localhost:3000
Content-Type: application/graphql
mutation addAvatar {
addAvatarFromUrl(image_url: "https://example.org/pic.png") {
id,
image_url
}
}
특정 방식을 이용하면 된다고 하는데, 굉장히 복잡해 보인다.
다른 이유도 있겠지만, 이런 크리티컬한 단점으로 REST API가 더 선호되는 듯하다.
Apollo Client는 GraphQL 기반의 라이브러리로, 클라이언트 애플리케이션의 GraphQL과 데이터 교환을 돕는다.
대표적으로 Query, Mutation을 이용해서 Resource를 요청할 수 있다.
GET
요청과 비슷하게 Query
를 이용할 수 있다. const { data : myGames } = useQuery(MY_GAMES);
// query 선언
export const MY_GAMES = gql`
query myGames {
myGames {
balanceGames: balanceGame {
id
totalVoteCount
commentCount
balanceGameSelections {
description
}
}
}
}
`;
// 요청 후, 받은 데이터 사용
useEffect(() => {
setIsVoted(false);
if (myGames) {
// ...로직
}
}, []);
POST
요청과 비슷하게 Mutation
를 이용할 수 있다.const [mRemoveComment] = useMutation(REMOVE_COMMENT_MUTATION);
// query 선언
const REMOVE_COMMENT_MUTATION = gql`
mutation removeComment($id: String!) {
removeComment(id: $id)
}
`;
// 요청을 보낼 때
const onDeleteComment = (id: string) => async () => {
try {
await mRemoveComment({
variables: { id },
});
} catch (e) {
alert("에러가 발생했습니다.");
}
};
나는 "밸런스 게임 커뮤니티" 사이드 프로젝트를 통해 GraphQL을 경험해 보았다.
GraphQL이 어떤 것인가에 대해 이해가 잘 가지않았고, 사용하는 방식에 대해서도 깊게 이해하기 어려웠다. 왜그랬을까?
웹 개발에 대한 지식이 많지 않은 상태였기 때문에 새로운 컨셉을 받아들이기가 힘들었다. 나는 컨셉에 대해 이해하기 위해, 공식 사이트에 들어가서 계속 예제들을 읽어보며 이해하려고 노력했다. 동시에 진행중이던 사이드 프로젝트에 적용할 수 있는 부분들은 적용했다.
나는 이 경험을 통해 공식문서가 제일 깔끔하고 자세하다는 것도 알았고, 새로운 기술이여도 공부하며 적용해 보면 충분히 할 수 있다는 것도 배웠다.
또 새로 하는 사이드 프로젝트에서도 GraphQL을 사용하기로 결정됐는데, 이번에 더 깊게 알 수 있는 기회가 될 것 같다.
Kakao tech, "GraphQL 개념잡기", https://tech.kakao.com/2019/08/01/graphql-basic/
Phil tech, "GraphQL vs REST: Overview", https://phil.tech/2017/graphql-vs-rest-overview/
Phil tech, "HTTP/REST API File Uploads", https://phil.tech/2016/http-rest-api-file-uploads/
Naver D2, "React와 Apollo, Parcel 기반 서비스 개발", https://d2.naver.com/helloworld/2838729
Naver D2, "Apollo Client는 Redux와 무엇이 다른가", https://d2.naver.com/helloworld/4245995
"GraphQL과 REST의 차이점", https://hwasurr.io/api/rest-graphql-differences/
"GraphQL 특징 및 장단점", https://owin2828.github.io/devlog/2020/11/12/GraphQL-1.html