본문 바로가기
FE/React & RN

GraphQL

by Chars4785 2022. 6. 14.

GraphQL 이란?

Graph QL(이하 gql)은 Structed Query Language(이하 sql)와 마찬가지로 쿼리 언어입니다. 자체적으로 서버와 클라이언트를 구축해 애플리케이션 서버 및 데이터베이스와 클라이언트 사이에서 Operation과 Resolve의 과정을 통해 서로 간의 데이터 상호작용을 도와줍니다. 하지만 gql과 sql의 언어적 구조 차이는 매우 큽니다. 또한 gql과 sql이 실전에서 쓰이는 방식의 차이도 매우 큽니다. gql과 sql의 언어적 구조 차이가 활용 측면에서의 차이를 가져왔습니다. 이 둘은 애초에 탄생 시기도 다르고 배경도 다릅니다. sql은 데이터베이스 시스템에 저장된 데이터를 효율적으로 가져오는 것이 목적이고, gql은 웹 클라이언트가 데이터를 서버로 부터 효율적으로 가져오는 것이 목적입니다. sql의 문장(statement)은 주로 백앤드 시스템에서 작성하고 호출 하는 반면, gql의 문장은 주로 클라이언트 시스템에서 작성하고 호출 합니다.

탄생 배경

특징으로는 어떤 종류의 Back-End(데이터베이스 및 다른 API 등)에도 연동이 가능하며, 강타입 및 단일 Endpoint를 지향합니다. 특히, REST API가 가진 구조적 문제인 Over-fetching Under-fetching을 해결할 수 있다는 큰 장점으로 인해 REST API의 대체자로 점점 떠오르고 있습니다.

* Over-fetching

예를 들어, 운영하는 서비스의 특정 회원 이름과 나이가 각기 다른 페이지에서 따로 필요하다고 가정했을 때, 기존 REST API 체계에서는 /user/name, /user/age처럼 요청할 Endpoint를 두 갈래로 분리하지 않는 이상 해당 페이지에서 필요하지 않은 정보들까지 받아와야만 합니다.

 

* Under-fetching

예를 들어, 채팅 서비스를 운영한다고 가정할 시 사용자가 서비스에 로그인했을 때, 상태를 표시할 회원 정보, 친구 목록, 프로필 사진, 대화 기록 등 여러 데이터를 요청하기 위해, 기존 REST API 체계에서는 /user/status, /user/friendslist/, /user/profilephoto, /user/talkrecord 등 여러 Endpoint를 통해 데이터를 받아와야만 합니다.

 


스키마, 리졸버를 비롯한 일반적인 GraphQL 용어

API 개발자는 GraphQL을 사용해 클라이언트가 서비스를 통해 쿼리할 가능성이 있는 모든 데이터를 설명하는 스키마를 생성합니다.

GraphQL 스키마는 개체 유형으로 구성되어 어떤 종류의 개체를 요청할 수 있으며 어떠한 필드가 있는지 정의합니다.

쿼리가 수신되면 GraphQL은 스키마에 대해 쿼리를 검증하고 그 다음 검증된 쿼리를 실행합니다.

API 개발자는 스키마의 각 필드를 리졸버라고 불리는 기능에 첨부합니다. 실행 중 값을 생산하기 위해 리졸버가 호출됩니다.

 

** GraphQL를 이용할 수 있는 클라이언트 라이브러리

  • Apollo: 프론트엔드 클라이언트 라이브러리(Apollo Client)와 백엔드 서버 프레임워크(Apollo Server)를 포함하는 GraphQL 플랫폼
  • Offix: 애플리케이션에 도달할 수 없는 경우에도 GraphQL 변형 및 쿼리를 실행할 수 있도록 허용하는 오프라인 클라이언트
  • Graphback: GraphQL 지원 Node.js 서버를 생성하기 위한 커맨드라인 클라이언트
  • OpenAPI-GraphQL: OpenAPI 사양 또는 Swagger로 설명된 API를 GraphQL로 번역하기 위한 커맨드라인 인터페이스 및 라이브러리

GraphQL의 핵심 요소

GraphQL은 서버에 Query, Mutation 등 사용자가 원하는 구조의 Schema를 직접 구축한 후, 클라이언트로부터 해당 요청을 받을 시, Resolver를 통해 요청된 데이터를 반환하는 구조입니다.

** CRUD 에서 query 거 R Mutation이 CUD를 담당하고 있다고 생각하면 됩니다.

 

(1) Query

Query란 데이터베이스로부터 데이터를 얻어오기 위해 사용하는 것으로,

type Query {
     (쿼리명): (반환 타입) (!)	
}

의 형태로 선언합니다.

만약 반환 타입 뒤 !(느낌표)를 붙일 시, 해당 요청이 들어오면 명시한 타입의 데이터를 반드시 반환해야만 하며, 사용자 정의 반환 타입을 생성하여 Query의 반환 타입에 적용이 가능하므로 임의의 객체를 반환하고자 할 때 반환 타입을 새로 만들어 타입 지정을 합니다.

  • 오브젝트 타입 : Character
  • 필드 : name, appearsIn
  • 스칼라 타입 : String, ID, Int 등
  • 느낌표(!) : 필수 값을 의미(non-nullable)
  • 대괄호([, ]) : 배열을 의미(array)

ex)

(2) Mutation

Mutation이란 서버, 데이터베이스 혹은 메모리에서 데이터를 변경할 때 사용하며,

CRUD(Create, Read, Update, Delete) 중 CUD 요청을 담당합니다.

만약, GraphQL을 데이터베이스와 연동하여 사용하지 않는다면, Mutation을 하더라도 메모리에 변경사항이 적용되어 서버 재실행 시 초기화가 되므로 주의해야 하며, 선언은 Query의 방식과 같습니다.

ex)

(3) Resolver

Resolver란 클라이언트로부터 요청된 Query 혹은 Mutation에 대해 반환할 결과를 생성하는 로직으로, GraphQL 서버가 Resolver를 찾아 Query와 Mutation에 해당하는 함수를 실행합니다.

 

데이터베이스 사용시, 데이터를 가져오기 위해서 sql을 작성 했습니다. 또한, 데이터베이스에는 데이터베이스 어플리케이션을 사용하여 데이터를 가져오는 구체적인 과정이 구현 되어 있습니다. 그러나 gql 에서는 데이터를 가져오는 구체적인 과정을 직접 구현 해야 합니다. gql 쿼리문 파싱은 대부분의 gql 라이브러리에서 처리를 하지만, gql에서 데이터를 가져오는 구체적인 과정은 resolver(이하 리졸버)가 담당하고, 이를 직접 구현 해야 합니다. 프로그래머는 리졸버를 직접 구현해야하는 부담은 있지만, 이를 통해서 데이터 source의 종류에 상관 없이 구현이 가능 합니다. 예를 들어서, 리졸버를 통해 데이터를 데이터베이스에서 가져 올 수 있고, 일반 파일에서 가져 올 수 있고, 심지어 http, SOAP와 같은 네트워크 프로토콜을 활용해서 원격 데이터를 가져올 수 있 습니다. 덧붙이면, 이러한 특성을 이용하면 legacy 시스템을 gql 기반으로 바꾸는데 활용 할 수 있습니다.

 

GraphQL 의 여러 가지 타입 중 Query, Mutation, Subscription 과 같은 타입이 실제로 일을 하는 부분이라 생각하시면 됩니다. 선언된 타입의 정의 부분이죠. 그래서 스키마를 정의하면 그 스키마 필드에 사용되는 함수의 실제 행동을 Resolver에서 정의하고 이러한 함수들이 모여 있기 떄문에 Resolvers 라 부릅니다.

 

또한, Resolver를 통해 데이터베이스, 메모리, 다른 API 등과 연결해 자유자재로 프로그래밍이 가능해지며, 실행 함수의 첫 번째 인자로는 현재 Object가 넘어오고, 두 번째부터 요청된 Query나 Mutation에서 넘어온 인자가 객체의 형태로 전달되기 때문에 ( _, { arg1, arg2, ... } )의 형태로 인자를 넘겨받아 사용합니다.

ex)

 

참고

 

https://hellominchan.tistory.com/220

https://tech.kakao.com/2019/08/01/graphql-basic/

'FE > React & RN' 카테고리의 다른 글

react-query (1)  (0) 2022.06.21
Apollo  (0) 2022.06.15
Context  (0) 2022.06.07
[react-native] react-native-ble-plx  (0) 2022.03.30
[React-native] 자동 배포  (0) 2021.11.17

댓글