GraphQL은 페이스북에서 만든 쿼리 언어입니다. 줄여서 gql은 웹 클라이언트가 데이터를 서버로 부터 효율적으로 가져오는 것을 목적으로 탄생하게 되었습니다. gql의 문장은 주로 클라이언트 시스템에서 작성하고 호출합니다.
gql 쿼리 예시
{
hero {
name
fiends {
name
}
}
}
서버사이드 gql 어플리케이션은 gql로 작성된 쿼리를 입력받아 쿼리를 처리한 결과를 다시 클라이언트로 돌려줍니다. HTTP API 자체가 특정 데이터베이스나 플렛폼에 종속적이지 않은것 처럼 마찬가지로 gql 역시 어떠한 특정 데이터베이스나 플렛폼에 종속적이지 않습니다. 또한, 네트워크 방식에도 종속적이지 않습니다.
REST API는 URL, METHOD등을 조합하기 때문에 다양한 Endpoint가 존재 합니다. 반면, gql은 단 하나의 Endpoint가 존재 합니다. 또한, gql API에서는 불러오는 데이터의 종류를 쿼리 조합을 통해서 결정합니다. 예를 들어, REST API에서는 각 Endpoint 마다 데이터베이스 SQL 쿼리가 달라지면, gql API는 gql 스키마의 타입마다 데이터베이스 SQL 쿼리가 달라집니다.
쿼리와 뮤테이션 그리고 응답 내용의 구조는 상당히 직관적입니다. 요청하는 쿼리문의 구조와 응답 내용의 구조는 거의 일치합니다.
gql에서는 굳이 쿼리와 뮤테이션을 나누는데 내부적으로 들어가면 사실상 이 둘은 별로 차이가 없습니다. 쿼리는 데이터를 읽는데(R) 사용하고, 뮤테이션은 데이터를 변조(CUD)하는데 사용한다는 개념적인 규약을 정해 놓은 것 뿐입니다.
데이터베이스 스키마를 작성할 때의 경험을 SQL 쿼리 작성으로 비유한다면, gql스키마를 작성할 때의 경험은 C, C++의 헤더파일 작성에 비유가 됩니다.
type Character {
name: String!
appearsIn: [Episode!]!
}
gql에서는 데이터를 가져오는 구체적인 과정을 직접 구현해야합니다. gql 쿼리문 파싱은 대부분의 gql 라이브러리에서 처리를 하지만, gql에서 데이터를 가져오는 구체적인 과정은 resolver(이하 리졸버)가 담당하고, 이를 직접 구현 해야 합니다. 프로그래머는 리졸버를 직접 구현해야하는 부담이 있지만, 이를 통해 데이터의 source 종류와 상관없이 구현이 가능합니다.
gql 쿼리에서는 각각의 필드마다 함수가 하나씩 존재 한다고 생각하면 됩니다. 이 함수는 다음 타입을 반환합니다. 이러한 각각의 함수를 resolver라고 합니다. 만약 필드가 스칼라 값인 경우에는 실행이 종료됩니다. 하지만 필드의 타입이 스칼라 타입이 아닌 우리가 정의한 타입이라면 해당 타입의 리졸버를 호출되게 됩니다.
기존 서버-클라이언트 협업 방식에서는 연동규격서라고 하는 API 명세서를 주고 받는 절차가 반드시 필요했습니다. 프로젝트 관리 측면에서 관리해야 할 대상의 증가는 작업의 복잡성 및 효율성 저해를 의미합니다.
이 API 명세서는 때때로 관리가 제대로 되지 않아, 인터페이스 변경 사항을 제때 문서에 반영되지 못하기도하고, 제 타이밍에 전달 못하곤 합니다.
REST의 API 명세서 공유와 같은 문제를 해결하는 것이 gql의 인트로스펙션 기능입니다. gql의 인트로스펙션은 서버 자체에서 현재 서버에 정의된 스키마의 실시간 정보를 공유 할 수 있게 해줍니다. 이 스키마 정보만 알고 있으며 클라이언트 사이드에서는 따로 연동규격서를 요청할 필요가 없게 됩니다.
gql 자체는 쿼리 언어 입니다. 이것 만으로는 할 수 있는 것이 없습니다. gql을 실제 구체적으로 활용할 수 있도록 도와주는 라이브러리들이 몇가지 존재합니다. gql 자체는 개발 언어와 사용 네트워크에 완전히 독립적입니다. 이를 어떻게 활용 할지는 사용자에게 달려있습니다.