GraphQL 개념 (1)

김민아·2022년 10월 5일
0

GraphQL

GraphQL은 Graph + Query Language의 약자로 페이스북이 2012년에 개발하여 2015년에 공개 발표한 API를 위한 쿼리 언어이다. 마인드맵과 유사한 형태의 그래프 구조로 실제 현실 세계의 현상과 가깝게 모델링할 수 있다.

상승중인 GraphQL 인기 (출처: 2020.stateofjs)

SQL이 데이터베이스에 저장된 데이터를 효율적으로 가져오는 것이라면, GraphQL은 웹 클라이언트가 데이터를 서버로부터 효율적으로 가져오는 것이 목적이다. 주체가 클라이언트라는 점이 매우 큰 특징을 가진다. GraphQL 서버는 여러 언어로 구현되어 있는데, 그 중 javascript로 를 참고해 실습해 볼 예정이다.

GraphQL의 구조

📍 쿼리(query, 데이터 조회)

필드 (field)

GraphQL의 구조 필드 (field)

GraphQL의 구조 필드 (field)

GraphQL은 객체의 특정 필드를 요청한다. 위 예시처럼 요청과 응답 항목이 정확히 같은 구조로 이루어져 있음을 알 수 있다(중요). GraphQL은 관련 개체 및 해당 필드를 순회할 수 있으므로 REST API에서 여러 왕복이 필요한 데이터들도 한번의 요청으로 그림2와 같이 관련 데이터를 가져올 수 있다.

전달인자 (Arguments)

GraphQL의 구조 전달인자 (Arguments)

REST API에서 요청시 ?id=1000 쿼리나 /1000(/:id) 파라미터로 전달되었던 전달인자를 GraphQL에서는 모든 필드와 중첩된 객체에서도 전달인자를 적용하여 원하는 데이터만 받아 올 수 있다.

별명(Aliases)

GraphQL의 구조 별명(Aliases)

GraphQL의 구조 별명(Aliases)

다른 전달인자를 가진 같은 필드의 데이터를 요청한 경우, 필드명이 중복되어 별칭이 필요하다. 별칭을 사용하면 그림2와 같이 필드 결과를 원하는 이름으로 바꿀 수 있다.

오퍼레이션 네임(Operation name)

GraphQL의 구조 오퍼레이션 네임(Operation name)

위 예시에서는 operation name을 생략했지만 실제 앱에서는 명시적으로 사용을 권하고 있다. 쿼리 이름은 타입 + 이름으로 작성하는데, 그림은 operation type으로 query 퀴워드와 함께 쿼리명을 HeroNameAndFriends로 작성한 것이다.
query는 type 중 하나이며, 외에도 mutation, subscription, describes 등이 있다. 명시적인 역할 뿐만 아니라, 문제가 발생했을 때 디버깅 및 서버 측 로깅에 매우 유용하다고 한다.

변수(Variables)

GraphQL의 구조 변수(Variables)

대부분 어플리케이션에서 필드에 대한 전달인자는 검색, 필터 등으로 동적인 경우가 많다. 이때 변수를 사용할 수 있는데, 그림에 나온 예시처럼 $는 접두어로 변수를 정의할 수 있다. 그림에서 ($episode: Episode)에 해당하는 부분은 변수를 선언하는 것으로 $변수명: 다음에 따라오는 것은 타입이다.
($episode: Episode = JEDI)처럼 기본값을 정할 수 있다. 당연하지만 변수가 전달되면 기본값은 무시된다. 변수를 정의할 때 필수 조건일 경우 ($episode: Episode!)처럼 !를 함께 작성한다.
그리고 JSON(일반적으로)으로 {"episode": "JEDI"}과 같이 전달한다.

🛑 실습에서 주의! 생각보다 위 부분이 실습하면서 가장 어려웠던 부분이었는데, 괄호의 늪에 빠져 syntax 에러를 많이 만났다.


📍 뮤테이션(mutation, 데이터 수정)

뮤테이션(mutation, 데이터 수정)

여기까지 이미지는 모두 GraphQL의 learn queries 레퍼런스에서 가져온 것인데, 코드가 잘려서 링크를 남겨둔다. (앞부분 mutation 키워드만 참고!)
GraphQL은 조회하는 것에 중점을 두지만 데이터에 수정 요청을 보내직도 한다. query 퀴워드 대신 mutation을 넣어 수정할 수 있다. 마치 REST API의 PUT이나 PATCH처럼.


📍 스키마와 타입(Schema/Type)

스키마와 타입(Schema/Type)

GraphQL에서 필드를 선택할 때, 반환할 내용을 예측할 수 있지만, 정확하게 어떤 종류의 개체를 선택하고 받을 수 있는지 쿼리할 수 있는 가능한 데이터 집합을 설명하는 스키마가 필요하다. 스키마의 가장 기본적인 구성 요소는 서비스에서 가져올 수 있는 객체의 종류, 그리고 포함하는 필드를 나타내는 객체 유형이다. 쿼리가 들어올 때, 해당 스키마에 대한 유효성 검사가 후, 실행된다.

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

📍 리졸버(Resolver)

GraphQL 쿼리문 파싱은 대부분 GraphQL 라이브러리에서 처리하지만 데이터를 가져오는 과정은 resolver(이하 리졸버)가 한다. 리졸버는 요청에 대한 응답을 결정해주는 함수로 각각의 필드마다 함수가 하나씩 존재한다고 이해하면 된다. 이 함수는 타입을 반환하는데, 필드가 원시값인 경우 실행이 종료되며 리졸버 호출이 일어나지 않는다.


이어서 GraphQL의 특징과 REST API 비교

출처

더 공부해 볼 것

  • 갑자기 뜬금없지만 작성하면서 언급되어 궁금해졌다. PUT과 PATCH 비교, 멱등성 차이

0개의 댓글