[GraphQL #2] GraphQL 쿼리어
해당 포스팅은 프로그래밍 인사이트에서 출판한 <웹 앱 API 개발을 위한 GraphQL> (이브 포셀로, 알렉스 뱅크스 저)을 바탕으로 작성한 글임을 먼저 밝힙니다.
우리가 익숙하게 쓰던 SQL이라는 구조화된 영문 쿼리 언어가 있다. 이 언어는 오랜 시간 많이 사용되어오면서 REST와 궁합이 좋았고 나름대로의 장점을 가지고 있었지만, 한계도 분명히 존재헀다. 이를 보완하기 위해 만들어진 GraphQL은 쿼리 데이터베이스 용으로 만들어진 개념을 가져다가 인터넷에 적용해 만들어진 것이다. GraphQL 쿼리 하나로 여기저기 흩어져 있는 데이터를 한데 모아서 받는다.
SQL과 GraphQL은 모두 쿼리 언어(Query Language)라는 공통점을 가지고 있다. 차이점은 SQL 쿼리는 데이터베이스로 보내는 반면, GraphQL 쿼리는 API로 보낸다. 그리고 SQL 데이터는 데이터 테이블 안에 저장되어 있지만, GraphQL 데이터는 저장 환경을 가리지 않는다. 예를 들면 단일 데이터베이스, 여러 개의 데이터베이스, 파일 시스템, REST API, 웹 소켓(Web Socket), 다른 GraphQL API로부터 데이터를 받아올 수가 있다.
GraphQL과 SQL의 구문은 매우 다르다. GraphQL에서는 SELECT 대신 Query를 사용하여 데이터 요청을 보낸다. 그리고 INSERT, UPDATE, DELETE 등을 사용하는 대신 Mutation이라는 데이터 타입을 가지고 데이터를 조작한다. 그리고 Subscription 이라는 타입도 있는데 이 타입을 사용해 소켓 연결로 전달되는 데이터 변경 사항을 감지할 수 있다.
지금부터는 snowtooth에서 제공하는 graphql api를 가지고 예제를 보면서 쿼리문을 살펴보도록 한다.
Query
쿼리를 보낼 때는 요청 데이터를 필드로 적어서 넣는다. 아래의 예시는 allLifts 쿼리를 보낼 때 name과 status 필드 요청을 보내는 경우이다.
쿼리 문에는 쿼리를 여러개 추가할 수도 있다. 이런 경우 작업은 한 번에 한 쿼리에 대해서만 이루어진다. 그리고 예를 들어 상태가 OPEN인 리프트를 조건으로 걸어서 가져오고 싶으면 다음과 같이 쿼리문 안에 한꺼번에 다 넣어주면 된다. 여기서 GraphQL의 장점이 나타난다.
여기서 가장 앞에 써주는 query는 GraphQL 타입이다. 이는 루트 타입이라고 한다. 타입 하나가 곧 하나의 작업을 수행하면서, 작업이 곧 쿼리 문서의 루트를 의미한다. 여기에서 중괄호로 묶인 블록은 셀렉션 세트(selection set)로 부른다. 여기에서 셀렉션 세트는 중첩시킬 수 있다.
GraphQL 쿼리 결과에 대한 필터링 작업을 하고 싶다면 쿼리 인자(query arguments)를 넘기면 된다. 예를 들면 현재 가동중이 아닌 리프트의 이름만 받고 싶다면 인자를 다음과 같이 넘겨서 응답 결과를 필터링 할 수 있다.
GraphQL 쿼리어에서 필드는 스칼라 타입과 객체 타입이 있다. 스칼라 타입은 다른 프로그래밍 언어에서의 원시 타입과 비슷하다. 객체 타입은 스키마에 정의한 필드를 그룹으로 묶어 둔 것이다. 또한 GraphQL 쿼리 안에는 각종 작업에 대한 정의와 프래그먼트에 대한 정의가 들어갈 수 있는데 프래그먼트는 셀렉션 세트의 일종이며, 여러번 재사용할 수 있다는 장점이 있다.
그리고 프래그먼트를 쓰면 한 차례의 수정으로 여러 쿼리의 셀렉션 세트를 한 번에 바꿀 수 있다는 점도 프래그먼트의 큰 장점이다.
Mutation
지금까지는 데이터를 읽는 방법에 대해서 다루어 보았다. 데이터를 새로 쓰려면 뮤테이션(mutation)해야 한다. 데이터를 뮤테이션 하는 방법은 쿼리를 작성하는 법과 비슷하며, 이름을 붙여주어야 한다. 전반적으로 쿼리와 비슷하지만 차이가 있다면 데이터를 뮤테이션하면 백엔드 데이터에 영향을 준다.
아래의 예제는 새로운 음악 데이터를 만들어 보는 뮤테이션이다.
데이터를 생성하는 것 뿐만 아니라 수정, 삭제도 물론 가능하다.
뮤테이션에 인자로 변수를 넣어서 보낼 수도 있다. GraphQL은 언제나 변수명 앞에 $ 문자가 붙는다.
Subscription
서브스크립션은 GraphQL에서 수행할 수 있는 세 번째 작업 타입이다. 서버에서 푸시 중인 업데이트 내역을 실시간으로 클라이언트에서 받아야 할 때가 있다. 이럴 때 데이터 서브스크립션을 하면 GraphQL API를 사용해 실시간 데이터 변경 내용을 받을 수 있다.
쿼리와 뮤테이션과 달리 서브스크립션은 일회성으로 끝나지 않고 계속 열려 있다. 리프트의 상태에 변경이 생길 때 마다 받는 쪽으로 새로운 데이터가 푸시된다.