3편. GraphQL Hello Query 실습: 첫 서버 구축하기
📚 목차
1. createYoga + createSchema로 서버 기본 구성
2. 첫 Query 정의와 Schema-Resolver 연결
3. Playground에서 요청-응답 테스트
4. GraphQL 요청 처리 흐름 시각화
✔ 마무리 - 서버 기초와 실무 적용 포인트
이번 실습에서는 GraphQL 서버의 구조와 작동 원리를 직접 체험하며 Schema와 Resolver 개념을 명확히 이해합니다.
가장 단순한 hello 쿼리를 예제로, createYoga()와 createSchema()를 이용한 서버 구성, 요청-응답 처리 흐름, 그리고 Playground를 통한 테스트 과정을 단계별로 살펴봅니다.
1. createYoga + createSchema로 서버 기본 구성
GraphQL Yoga 서버는 크게 두 가지 핵심 함수로 이루어집니다.
🔸createSchema() – 스키마(Schema)와 리졸버(Resolver)를 결합하여 실행 가능한 GraphQL 스키마를 생성합니다.
🔸createYoga() – GraphQL 서버를 생성하고, HTTP 요청을 처리하는 엔진 역할을 수행합니다.
이번 실습에서는 이 두 함수를 활용하여 가장 단순한 형태의 GraphQL 서버를 직접 구현해 보겠습니다.
🟦예제: 최소 구조의 GraphQL 서버
//graphql-tutorial-server/ch03/src/index.ts
import { createYoga, createSchema } from 'graphql-yoga';
import { createServer } from 'http';
// GraphQL 서버 생성
const yoga = createYoga({
schema: createSchema({
// 1. 타입 정의
typeDefs: /* GraphQL */ `
type Query {
hello: String
}
`,
// 2. 리졸버 정의
resolvers: {
Query: {
hello: () => 'Hello, GraphQL!',
},
},
}),
});
// Node.js HTTP 서버로 실행
const server = createServer(yoga);
server.listen(4000, () => {
console.log('🚀 Server ready at http://localhost:4000/graphql');
});
▸ type Query { hello: String } → hello 필드를 정의하고, 반환 타입을 String으로 지정
▸ hello: () => 'Hello, GraphQL!' → 해당 필드 요청 시 실행되는 리졸버 함수
▸ 서버 실행 주소: http://localhost:4000/graphql
🟦서버 실행 방법
아래 명령어를 실행하면 서버가 구동됩니다.
npx ts-node src/index.ts
성공적으로 실행되면 다음과 같은 메시지가 출력됩니다:
🚀 Server ready at http://localhost:4000/graphql
✔️ 실행 후 확인
▸ 브라우저에서 http://localhost:4000/graphql에 접속하면 GraphiQL Playground가 자동으로 실행됩니다.
▸ 별도의 프론트엔드 없이도 쿼리를 입력하고 결과를 확인할 수 있습니다.
2. 첫 Query 정의와 Schema-Resolver 연결
GraphQL 서버에서 요청을 처리하는 핵심 구성 요소는 스키마(Schema)와 리졸버(Resolver)입니다.
이 두 요소는 클라이언트가 요청한 데이터를 어떻게 해석하고, 어떤 값을 반환할지를 결정하는 구조적 기반입니다.
🟦 Schema
스키마는 API의 명세서 역할을 합니다.
클라이언트가 어떤 필드를 요청할 수 있는지, 해당 필드가 어떤 타입의 값을 반환하는지를 선언합니다.
예를 들어, 다음 정의는 hello라는 필드를 제공하며, 반환 타입이 String임을 의미합니다.
type Query {
hello: String
}
🟦 Resolver
리졸버는 스키마에 정의된 각 필드의 실제 동작을 구현하는 함수입니다.
클라이언트가 특정 필드를 요청하면, 해당 필드에 연결된 리졸버가 실행되어 결과값을 반환합니다.
다음 예제는 hello 필드 요청 시 고정 문자열을 반환합니다
Query: {
hello: () => 'Hello, GraphQL!',
}
🟦 Schema와 Resolver 결합
createSchema() 함수 내부에서 스키마와 리졸버를 함께 정의하면, 이를 기반으로 실행 가능한 GraphQL 스키마가 완성됩니다.
schema: createSchema({
typeDefs: /* GraphQL */ `
type Query {
hello: String
}
`,
resolvers: {
Query: {
hello: () => 'Hello, GraphQL!',
},
},
});
✔️ 요청 처리 예시
클라이언트가 아래와 같은 쿼리를 요청한다고 가정합니다.
query {
hello
}
요청이 들어오면 서버는 다음 과정을 거칩니다.
1. 스키마에서 hello 필드가 존재하고 타입이 유효한지 검증
2. 해당 필드의 리졸버 함수를 호출
3. 결과값("Hello, GraphQL!")을 JSON 형식으로 응답
이렇게 구성하면 스키마와 리졸버의 역할 차이가 명확해지고, 이후 Mutation이나 Subscription을 확장할 때도 일관된 패턴을 유지할 수 있습니다.
3. Playground에서 요청-응답 테스트
GraphQL Yoga는 개발 편의성을 위해 GraphiQL Playground를 기본 내장하고 있습니다.
이 도구를 활용하면 별도의 프론트엔드 개발 없이도 브라우저에서 직접 쿼리를 작성하고, 응답을 실시간으로 확인할 수 있습니다.
또한 스키마 탐색, 자동 완성, 실행 히스토리 관리 등의 기능을 제공해 개발 생산성을 높여 줍니다.
🟦 1) Playground 접속
서버를 실행한 상태에서 브라우저 주소창에 다음 주소를 입력합니다.
http://localhost:4000/graphql
이 경로는 GraphQL 요청을 처리하는 단일 엔드포인트이자, 웹 기반 IDE인 GraphiQL을 제공합니다.
접속 시 좌측에는 쿼리 작성 창, 우측에는 응답 결과 창이 나타납니다.

🟦 2) 테스트 쿼리 작성
쿼리 입력창에 다음 예제를 작성합니다.
query {
hello
}
이 쿼리는 Query 타입 안에 정의된 hello 필드를 요청하는 가장 기본적인 GraphQL 요청입니다.
GraphiQL은 작성 중 자동 완성 기능을 제공하므로, 필드 이름을 일일이 기억하지 않아도 쉽게 쿼리를 작성할 수 있습니다
🟦 3) 실행 및 응답 확인
쿼리를 실행하면 우측 응답 창에 아래와 같은 JSON 데이터가 표시됩니다.
{
"data": {
"hello": "Hello, GraphQL!"
}
}
이는 클라이언트가 hello 필드를 요청했고, 해당 필드의 리졸버 함수가 'Hello, GraphQL!'이라는 문자열을 반환했음을 의미합니다.
GraphQL의 장점은 응답이 요청 필드 구조와 동일한 형태를 유지한다는 점입니다. 덕분에 클라이언트는 예측 가능한 구조의 데이터를 받을 수 있습니다.
✔️ 요청 처리 흐름 요약
Playground에서의 요청-응답 과정은 다음과 같은 단계로 진행됩니다.
1. 클라이언트 요청 전송 – 쿼리 문서, 변수(Variables), 실행할 operationName을 포함해 HTTP POST 요청으로 전송
2. 스키마 검증 – 요청된 필드와 타입이 정의된 스키마와 일치하는지 검사
3. 리졸버 실행 – 해당 필드에 연결된 리졸버 함수 실행
4. JSON 응답 반환 – 결과를 JSON 형식으로 변환하여 클라이언트로 전송
✔️ 실무 활용 팁
🔸 스키마 탐색: GraphiQL 우측 상단의 Docs 탭을 활용하면 서버에 정의된 타입과 필드를 빠르게 확인할 수 있습니다.
🔸 변수 관리: Variables 패널을 활용하면 쿼리에 동적 데이터를 주입할 수 있어, 테스트 케이스를 다양하게 작성 가능
🔸 공유 가능성: Playground에서 작성한 쿼리와 변수 세트를 JSON으로 내보내 팀원들과 공유하면, API 매뉴얼로 재사용할 수 있습니다.
4. GraphQL 요청 처리 흐름 시각화
GraphQL은 하나의 엔드포인트(/graphql)를 통해 모든 요청을 처리합니다.
하지만 내부적으로는 스키마 검증, 리졸버 실행, 응답 생성까지 여러 단계를 거쳐 정교하게 동작합니다.
이 흐름을 이해하면 서버 동작을 디버깅하거나 성능을 최적화할 때 큰 도움이 됩니다
🟦 요청 처리 흐름 개요
아래는 클라이언트가 GraphQL 요청을 전송했을 때, 서버 내부에서 처리되는 단계별 흐름입니다.
[Client]
|
| ① GraphQL 요청 전송 (query, variables, operationName)
▼
[GraphQL Server]
|
| ② 스키마 검증 (요청 필드 및 타입 유효성 확인)
▼
[Resolver 호출]
|
| ③ 비즈니스 로직 실행 (DB 조회, API 호출, 계산 등)
▼
[응답 생성]
|
| ④ JSON 형식으로 변환하여 클라이언트로 반환
🟦 단계별 상세 설명
1. 클라이언트 요청 수신
클라이언트는 GraphQL 문서(query), 요청 변수(variables), 실행 대상(operationName)을 함께 전송합니다.
이 요청은 일반적으로 HTTP POST 메서드와 JSON 형식을 사용합니다.
2. 스키마 검증
서버는 요청된 필드와 타입이 사전에 정의한 스키마(typeDefs)와 일치하는지 검사합니다.
필드가 존재하지 않거나 타입이 불일치할 경우, 서버는 요청을 거부하고 에러를 반환합니다.
3. 리졸버 실행
검증을 통과한 각 필드에 대해 해당 리졸버 함수를 호출합니다.
이 단계에서 DB 조회, 외부 API 호출, 계산 로직 수행 등 실제 비즈니스 처리가 이루어집니다.
4. 응답 생성 및 반환
리졸버에서 반환한 데이터를 JSON 구조로 변환하여 클라이언트에 전달합니다.
GraphQL의 응답 구조는 요청의 필드 구조를 그대로 반영하기 때문에, 클라이언트는 예상 가능한 형태의 응답을 받을 수 있습니다.

🟦 실무 적용 포인트
▸ 성능 최적화: 각 필드의 리졸버가 개별적으로 DB를 조회하면 N+1 문제가 발생할 수 있습니다. 이를 방지하려면 DataLoader와 같은 배치 처리 기법을 적용하는 것이 좋습니다.
▸ 에러 처리: GraphQL 응답에는 data와 errors가 함께 포함될 수 있으므로, 에러 상황에서도 부분 데이터를 반환할 수 있도록 설계하는 것이 안정적입니다.
▸ 로깅과 모니터링: 요청 시작부터 리졸버 실행까지의 시간을 기록하면, 병목 구간을 쉽게 파악할 수 있습니다.
✔ 마무리 - GraphQL 서버 기초와 실무 적용 포인트
이번 글에서는 hello 쿼리를 예제로, GraphQL 서버의 기본 구성과 요청 처리 흐름을 실습했습니다.
createSchema와 createYoga를 이용한 서버 초기화, 스키마와 리졸버의 결합 구조, 그리고 Playground를 활용한 쿼리 테스트 과정을 단계별로 확인했습니다.
실무 관점에서 중요한 포인트는 다음과 같습니다.
🔸구조 이해 – 스키마는 API 형태를, 리졸버는 동작을 정의하며 두 요소의 결합이 필수
🔸Playground 활용 – 빠른 테스트와 스키마 탐색, 팀 내 쿼리 공유에 효과적
🔸처리 흐름 파악 – 요청 검증 → 리졸버 실행 → 응답 생성의 3단계 구조
이 기초 구조를 이해하면, 이후 Mutation, Subscription, 인증·성능 최적화와 같은 확장 기능 구현 시 안정적으로 적용할 수 있습니다.
※ 게시된 글 및 이미지 중 일부는 AI 도구의 도움을 받아 생성되거나 다듬어졌습니다.
'3.SW개발 > GraphQL 배우기' 카테고리의 다른 글
| 6편. GraphQL Scalar 타입 완전 정복 (0) | 2025.11.30 |
|---|---|
| 5편. GraphQL 스키마와 리졸버 구조 이해 (0) | 2025.11.30 |
| 4편. GraphQL 실무 아키텍처 설계: 도메인 구조와 책임 분리 (0) | 2025.11.27 |
| 2편. GraphQL 서버 개발 환경 구축 (Node.js + TS) (0) | 2025.11.25 |
| 1편. GraphQL이 필요한 이유: REST와의 차이 완벽 이해 (0) | 2025.11.25 |