이번엔 GraphQL의 서버 구성요소에 대해 알아보자.
GraphQL의 구성요소
GraphQL의 구성요소는 크게 4가지로 나눌 수 있다.
- 스키마
- 미들웨어
- 리졸버
- AST
GraphQL의 구성요소 - Schema
먼저 스키마에 대해 알아보자.
스키마는 GraphQL 서버의 데이터 구조와 API 형태를 정의한다.
이러한 스키마는 다시 4가지 구성요소로 나눌 수 있는데, 이 요소들을 스키마 정의 언어(SDL)를 통해 스키마로 작성하고 작성된 스키마는 각 타입의 필드와 관계가 어떻게 되는지 명확하게 규정된다.
그리고 이렇게 작성된 스키마는 GraphQL의 인트로스펙션 기능을 통해 Altair나 GraphQL 보이저 같은 도구에서 문서화나 시각화가 된다.
클라이언트에서는 이러한 특징 덕분에 쉽게 다룰 수 있다.
GraphQL의 구성요소 - Middleware
미들웨어는 웹 서버 어플리케이션에서 트래픽 대부분이 가장 먼저 도착하는 곳이다.
미들웨어에 도착한 트래픽은 사용자를 인증하고 요청 권한을 검증하거나 트래픽에 대한 로깅 또는 모니터링을 한다.
이번 포스팅에서는 미들웨어에 대해 다루지 않을 것이므로 자세한 내용은 생략할 것이다.
Node에서는 Express 미들웨어, Spring에서는 Spring Security가 이 미들웨어에 해당한다.
미들웨어를 통과한 트래픽은 GraphQL 엔진에 도착하게 된다.
GraphQL의 엔진은 수신된 트래픽의 쿼리를 엔진이 이해할 수 있는 구문으로 파싱한다.
이렇게 파싱된 구문을 추상 구문 트리, 즉 AST라고 부른다.
GraphQL의 구성요소 - AST
AST로 변환된 데이터는 아래와 같은 구조를 가지고 있다.
AST를 보면, 각 구간을 노드라고 부르고 Document는 최상위 노드이다.
도큐먼트는 하나 또는 여러 개의 query나 mutation, subscription을 definitions에 포함하고 있다.
다음으로 Operation Definition은 클라이언트가 요청한 Query의 Operation에 대응된다.
요청에 따라 Mutation이나 Subscription이 될 수 있다.
이 구문에서는 요청이 Query인 것을 알 수 있다.
Selection Set은 Query에서 선택한 필드를 나타내는 부분이다.
Selection Set에 배열로 필드가 나열되는데, 이 부분을 통해 User 필드를 요청하고 있는 것을 알 수 있다.
그리고 다시 안쪽으로 가면 Arguments가 있는데, 이 부분은 필드에 전달된 Arguments가 나열된다.
이름이 id인 argument에 값이 1로 전달된 것을 알 수 있다.
아래에는 다시 selectionSet이 나타나는데, 상위 노드인 User의 중첩 필드들이 나열된다.
클라이언트는 네임과 이메일을 조회하려고 하는 것을 볼 수 있다.
GraphQL의 엔진은 이렇게 변환된 AST를 크게 두 가지 과정에서 활용한다.
첫번째는 유효성 검사이다.
파싱된 AST를 기반으로 쿼리의 구조와 문법을 검사한다.
이 단계에서 잘못된 요청이 있으면 오류를 반환한다.
예를 들어 쿼리에서 요청된 필드가 스키마에 존재하는지 확인하는 작업을 한다는 것이다.
두번째는 실행이다.
트리 구조의 AST를 탐색해서 어떤 데이터를 요청하고 있는지 파악하고 요청에 해당하는 Resolver를 호출한다.
GraphQL 엔진은 이런 과정을 자동으로 수행해서 개발자가 세부적인 처리를 직접 신경 쓸 필요는 없다.
GraphQL의 구성요소 - Resolver
Resolver는 특정 GraphQL 작업이 실행될 때 실제 데이터를 가져오거나 변환하는 함수이다.
Node.js나 Spring 같은 프레임워크를 사용하면 JavaScript나 Kotlin, Java 같은 언어로 작성된 비즈니스 로직이 Resolver가 된다.
이제 이런 요소들을 포함해서 GraphQL 서버의 전반적인 동작 과정을 알아보자.
GraphQL 동작 과정
클라이언트가 서버로 요청을 하고 미들웨어가 트래픽을 인증, 권한부여, 로깅을 처리한다.
미들웨어를 통과한 트래픽은 GraphQL 엔진에 도착하고 GraphQL 엔진은 트래픽의 쿼리를 AST로 변환하며, 이렇게 변환된 AST를 통해 유효성 검사를 하고 문제가 없다면 해당 요청에 맞는 리졸버를 호출한다.
리졸버는 요청한 데이터를 처리하고 GraphQL 엔진에 반환한다.
마지막으로 GraphQL엔진은 데이터를 유저의 요청에 맞게 변환하고 클라이언트에 응답한다.
위와 같은 방식은 매우 복잡하지만, 실제로 개발자가 관리하고 개발해야 할 부분은 GraphQL 라이브러리 덕분에 아래처럼 줄어들게 된다
'DEV > GraphQL' 카테고리의 다른 글
GraphQL 스키마 타입에 대해 알아보자. (2) | 2025.01.04 |
---|---|
RESTAPI와 GraphQL의 차이점과 특징에 대해 공부해보자. (2) | 2025.01.01 |