
정의
GraphQL은 API를 위한 쿼리 언어(query language)이고, 서버에서 이 쿼리를 실행해주는 런타임(runtime)이다.
핵심 개념
- 어떤 데이터를 요청할 수 있을지 “타입 시스템(type system)” 으로 미리 정의해둠
- 클라이언트는 이 타입에 맞춰 데이터를 정확하게 원하는 만큼만 요청할 수 있음
- 기존 데이터베이스나 코드 위에서 작동하며, 특정 DB에 종속되지 않음
어떻게 쓰는지 보기
GraphQL을 구성하는 방법은 크게 두 가지이다.
1. 타입 정의 (Type Definitions)
예를 들어 사용자(User)의 이름(name)을 가져오고 싶다면
type Query {
me: User
}
type User {
name: String
}
- Query는 데이터의 입구라고 보면 됨
- me라는 필드는 로그인한 사용자를 나타냄
- User 타입에는 name이라는 문자열이 있음
2. 리졸버 (Resolver): 데이터를 실제로 가져오는 함수
예를 들어 로그인한 사용자의 정보를 가져오는 리졸버
function resolveQueryMe(_, _, context) {
return context.request.auth.user; // 로그인한 사용자 정보
}
function resolveUserName(user, _, context) {
return context.db.getUserFullName(user.id); // DB에서 이름 가져오기
}
리졸버는 실제로 어디서 데이터를 가져올지 정의하는 함수라고 생각하면 된다. (예: 데이터베이스, 인증 정보 등)
정확히 필요한 데이터만 요청한다!
GraphQL의 핵심 장점은 내가 필요한 데이터만, 정확히 그만큼만 요청할 수 있다는 것이다.
{
me {
name
}
}
응답:
{
"data": {
"me": {
"name": "Luke Skywalker"
}
}
}
장점:
- API 하나로 여러 데이터 요청 가능
- 필요한 필드만 선택 가능 (오버페칭/언더페칭 방지)
- 응답 구조도 요청과 동일해서 다루기 쉬움
API 버전 관리 없이 진화한다!
기존 REST API는 버전을 여러 개 관리해야 함 (v1, v2 등).
GraphQL은 필드를 점진적으로 추가하거나 제거하면 됨.
예:
type User {
fullName: String
nickname: String
name: String @deprecated(reason: "Use `fullName`.")
}
- 기존 name 필드는 여전히 쓸 수 있지만, 이제는 fullName을 권장함
- 이렇게 하면 기존 사용자도 문제 없이 사용 가능
직접 써보자!
예를 들어 Star Wars API처럼 이런 쿼리를 써볼 수 있다.
{
hero {
name
}
}
결과:
{
"data": {
"hero": {
"name": "R2-D2"
}
}
}
hero에 id나 appearsIn 같은 필드를 추가하면 더 많은 정보를 받을 수 있다.
아주 도움되는 블로그
'Dev > Backend' 카테고리의 다른 글
| [PostgreSQL] psql 접속 시 role does not exist 에러 해결 (Docker + PostgreSQL) (3) | 2025.07.17 |
|---|---|
| [Springboot] Spring IoC 컨테이너 쉽게 이해하기 (2) | 2025.04.06 |
| RESTful API란? (0) | 2025.03.31 |
| [Spring] 이메일 전송 로직 구현하기 (0) | 2025.01.24 |
| [Node.js / TypeScript] 발생한 문제와 해결 방법들 (2) | 2024.08.26 |