[ GraphQL ]
- GraphQL(이하 GQL)은 Facebook에서 만든 Graph Query Language로 어플리케이션 레이어 쿼리 언어
- GQL은 웹 클라이언트가 데이터를 서버로 부터 효율적으로 가져오는 것이 목적
- GQL의 문장은 주로 클라이언트 시스템에서 작성하고 호출
- API를 위한 쿼리 언어이며, 타입 시스템을 사용하여 쿼리를 실행하는 서버사이드 런타임
- GraphQL은 특정한 데이터베이스나 스토리지에 귀속되어 있지 않으며, 기존 코드와 데이터에 의해 대체
[ GraphQL 동작 방식 ]
- 서버에서는 클라이언트가 GraphQL 방식으로 요청할 수 있는 데이터의 타입들과 각 타입에 대해 요청할 수 있는 필드들을 정의하여 타입 시스템을 구축
- 각 타입의 각 필드에 대한 요청을 해석 및 처리하는 로직을 Resolver 함수들로 구현
- 이후 클라이언트가 GraphQL 쿼리를 보내면, 서버는 미리 정의해둔 타입 시스템에 따라 해당 쿼리를 검증
- 문제가 없다면 미리 구현해둔 Resolver 함수들을 호출하여 해당 쿼리를 실행한 결과를 클라이언트에게 응답
- 클라이언트가 요청하는 데이터들의 타입 및 필드 정보를 GraphQL에서 정해둔 형식의 문자열(쿼리문)로 표현하여 Body에 담고 메소드로는 POST를 사용하는 요청
[ GraphQL 사용이유 ]
- REST API의 경우 필요한 데이터만 요청하려면 쿼리 파라미터 등을 이용해야 하므로 요청 자체가 복잡함
- 요청의 형식으로부터 응답의 형식을 정확히 예측하기는 어려움
- GraphQL은 이러한 문제를 해결
- 클라이언트가 필요한 데이터만 서버에게 요청할 수 있고
- 요청의 형식으로부터 응답의 형식을 정확히 예측할 수 있기 때문
[ GraphQL vs REST API ]
- REST API는 URL, METHOD등을 조합하기 때문에 다양한 Endpoint가 존재
- 반면, gql은 단 하나의 Endpoint가 존재, 불러오는 데이터의 종류를 쿼리 조합을 통해서 결정
GraphQL을 사용하여 클라이언트는 쿼리에 필요한 데이터를 정확히 지정할 수 있다. 서버 응답의 구조는 쿼리에 정의된 중첩 구조를 정확히 따름
GraphQL API를 사용하면 여러번 네트워크 호출을 할 필요없이, 한 번의 네트워크 호출로 처리할 수 있음
[ GraphQL의 구조 ]
스키마
- 데이터베이스 스키마를 작성할 때의 경험을 SQL 쿼리 작성으로 비유
- gql 스키마를 작성할 때의 경험은 C, C++의 헤더파일 작성에 비유
type Character {
name: String!
appearsIn: [Episode!]!
}
- 오브젝트 타입 : Charcter
- 필드 : name, appearsln
- 스칼라 타입 : String, ID, Int 등
- 느낌표(!) : 필수 값을 의미(non-nullable)
- 대괄호([, ]) : 배열을 의미(array)
리졸버
- gql에서는 데이터를 가져오는 구체적인 과정을 직접 구현
- 개발자는 리졸버를 직접 구현해야하는 부담은 있지만, 이를 통해 데이터의 source의 종류에 상관없이 구현이 가능
- 리졸버를 통해 데이터를 데이터베이스 뿐만 아니라, 일반 파일, 심지어 http, SOAP와 같은 네트워크 프로토콜을 활용해서 원격 데이터를 가져올 수도 있음
- 리졸버는 사용자 정의 타입이나 스칼라 값(문자열이나 숫자와 같은 primitive 타입)을 반환할 수 있음
- 사용자 전의 타입을 반환하는 경우 해당 타입의 리졸버를 호출
- 스칼라 값을 반환하는 경우에는 실행이 종료되며 더 이상의 연쇄적인 호출이 일어나지 않음
쿼리/ 뮤테이션
- 쿼리는 데이터를 읽는데 사용(R)하고, 뮤테이션은 데이터를 변경(CUD)하는데 사용
- 오퍼레이션 네임 쿼리
- 앞에 query라는 키워드가 붙는 쿼리문으로 매우 편리
- REST API를 호출할 때와는 다르게, 한 번의 인터넷 네트워크 왕복으로 원하는 모든 데이터를 가져올 수 있음
- 클라이언트 개발자가 작성하고 관리
- GraphQL이 제공하는 추가 기능 덕분에 백엔드 개발자와 프론트엔드 개발자의 헙업 방식에도 영향을 줌
- REST API에서는 프론트앤드 개발자는 백엔드 개발자가 작성해 전달하는 API request/response 형식에 의존하게 되지만, GraphQL 방식에서는 이러한 의존도가 많이 사라짐
인트로스펙션
- gql의 인트로스펙션은 서버 자체에서 현재 서버에 정의된 스키마의 실시간 정보를 공유할 수 있게 함
- 클라이언트 사이드에서는 실시간으로 현재 서버에서 정의하고 있는 스키마에 맞게 쿼리문을 작성
- 인트로스펙션을 활용하여, 직접 쿼리 및 뮤테이션, 필드 스키마를 확인할 수 있으나, 보안상의 이슈로 상용환경에서는 이러한 스키마는 공개하지 않도록 하는 것이 좋음
[ 장점 ]
- GraphQL 스키마는 GraphQL 애플리케이션에 신뢰할 수 있는 단일 소스를 하나 설정, 조직은 이를 통해 전체 API에 페더레이션할 수 있게됨
- GraphQL 호출은 단일 왕복으로 처리되며 클라이언트는 오버페칭 없이 요청한 결과만 얻음
- 엄격하게 정의된 데이터 유형은 클라이언트와 서버 간 통신 오류를 줄여줌
- GraphQL은 세부 검사를 수행, 클라이언트는 사용 가능한 데이터 유형 목록을 요청할 수 있음
- GraphQL은 애플리케이션 API가 기존 쿼리를 중단하지 않고도 진화할 수 있도록 허용
- REST API로 사용할 수 없는 기능을 제공하기 위해 대부분의 오픈소스 GraphQL 확장 기능을 사용할 수 있음
- 특정 애플리케이션 아키텍처를 지정하지 않으므로 기존 REST API에 추가하여 기존 API 관리 툴과 연동할 수 있음
[ 단점 ]
- REST API에 친숙한 개발자의 경우 GraphQL를 학습하는 데 시간이 필요함
- GraphQL은 데이터 쿼리의 상당 작업을 서버측으로 옮겨 서버 개발자 작업의 복잡성이 커짐
- 캐싱이 REST보다 훨씬 복잡함
- API 유지관리자의 경우 유지 관리 가능한 GraphQL 스키마를 작성하기 위한 추가 태스크를 수행해야 함