liminfo

GraphQL Reference

GraphQL API 쿼리 레퍼런스

25개 결과

GraphQL Reference 소개

GraphQL 레퍼런스는 GraphQL 쿼리 언어와 서버 측 스키마 정의에 대한 종합적이고 검색 가능한 가이드입니다. GraphQL API의 여섯 가지 주요 영역을 모두 다룹니다: 스키마(type, input, enum, interface, union), 쿼리(기본 쿼리, 변수를 사용한 쿼리, 프래그먼트, 필드 별칭), 뮤테이션(변수 사용 여부에 따른 생성/수정/삭제 뮤테이션), 서브스크립션(PubSub을 통한 실시간 데이터와 구독 리졸버), 리졸버(context를 사용하는 Query/Mutation/Field 리졸버와 N+1 배치 로딩을 위한 DataLoader), 디렉티브(@deprecated, @skip, @include, 커스텀 auth 디렉티브, @cacheControl).

Apollo Server, graphql-yoga, Hasura 등 다양한 GraphQL 구현체를 사용하는 풀스택 개발자, 백엔드 엔지니어, API 설계자에게 유용한 레퍼런스입니다. 각 스키마 정의 항목은 실제 타입 예제와 함께 SDL(Schema Definition Language) 문법을 보여줍니다. 각 쿼리 항목은 클라이언트 측 요청 문법을 보여주며, 리졸버 항목은 표준 패턴인 (parent, args, context) 리졸버 시그니처와 데이터베이스 context 객체에서 데이터를 반환하는 방법을 설명합니다.

레퍼런스는 기본 CRUD를 넘어서는 실제 GraphQL 패턴에 특히 주목합니다: 여러 쿼리에서 필드 집합을 재사용하기 위한 프래그먼트 시스템, 동일 필드를 서로 다른 인자로 두 번 가져오기 위한 필드 별칭, field 리졸버의 N+1 쿼리 문제를 제거하는 DataLoader 배치 패턴, 인증 및 캐싱 같은 횡단 관심사를 처리하는 커스텀 스키마 디렉티브. SDL 스키마 문법과 JavaScript 리졸버 구현 문법 모두 각 개념과 함께 설명됩니다.

주요 기능

  • 스키마 정의 언어(SDL): 객체 타입, 입력 타입, 열거형, implements를 사용한 인터페이스, 다형성 검색 결과를 위한 유니온 타입
  • 쿼리 문법: 기본 쿼리, 변수를 사용한 이름 있는 쿼리($id: ID!), 프래그먼트 정의(fragment UserFields on User), 필드 별칭(admin: user(id: "1"))
  • 뮤테이션 연산: 생성/수정/삭제 뮤테이션(인라인 및 $input 변수 방식 모두), 반환 타입에 대한 선택 집합
  • 실시간 데이터를 위한 서브스크립션 문법과 서버 측 PubSub 패턴: pubsub.publish()로 트리거되는 asyncIterator 기반 구독 리졸버
  • 리졸버 구현 패턴: context.db를 사용하는 Query 리졸버, input 구조 분해를 사용하는 Mutation 리졸버, 관계 해결을 위한 Field 리졸버
  • 배치 및 캐싱을 위한 DataLoader 패턴: 요청별 데이터베이스 조회를 하나의 배치 쿼리로 그룹화하여 N+1 문제 해결
  • 내장 디렉티브: reason 문자열을 사용하는 @deprecated, 클라이언트 제어 필드 선택을 위한 조건부 @skip(if: $var) 및 @include(if: $var)
  • 커스텀 디렉티브: 필드 수준 접근 제어를 위한 스키마 레벨 @auth(requires: Role!), HTTP 캐싱 헤더를 위한 @cacheControl(maxAge: N)

자주 묻는 질문

GraphQL 쿼리와 뮤테이션의 차이는 무엇인가요?

쿼리는 읽기 작업(데이터 조회)에 사용되며 병렬로 실행될 수 있습니다. 뮤테이션은 쓰기 작업(생성, 수정, 삭제)에 사용되며 경쟁 조건을 방지하기 위해 직렬로 실행됩니다. 두 가지 모두 동일한 필드 선택 문법을 사용하지만, 뮤테이션은 일반적으로 클라이언트가 캐시를 업데이트할 수 있도록 수정된 객체를 반환합니다.

GraphQL 프래그먼트란 무엇이고 왜 사용하나요?

프래그먼트는 "fragment 이름 on 타입 { ... }" 형태로 정의하는 재사용 가능한 필드 집합입니다. "...프래그먼트이름"으로 쿼리에 스프레드합니다. 여러 쿼리 또는 하나의 쿼리 내 여러 위치에서 동일한 필드가 필요할 때 중복을 제거하여 클라이언트 코드를 DRY하게 유지합니다.

GraphQL 변수는 어떻게 동작하나요?

변수는 쿼리 시그니처에서 선언하고(예: query GetUser($id: ID!)), JSON 객체로 별도 전달합니다(예: { "id": "1" }). 인라인 인자 리터럴을 대체하여 쿼리를 재사용 가능하게 하고 인젝션 공격을 방지합니다. 타입 뒤의 ! 는 해당 변수가 필수임을 의미합니다.

GraphQL의 N+1 문제란 무엇이고 DataLoader는 어떻게 해결하나요?

N+1 문제는 field 리졸버가 목록의 각 항목에 대해 별도의 데이터베이스 쿼리를 실행할 때 발생합니다 — 목록에 1개, 각 항목의 필드에 N개의 쿼리. DataLoader는 단일 이벤트 루프 틱 동안 요청된 모든 ID를 수집하고 하나의 데이터베이스 쿼리로 배치 처리하여 라운드 트립을 획기적으로 줄입니다.

@skip과 @include 디렉티브의 차이는 무엇인가요?

@skip(if: $condition)은 조건이 true일 때 필드를 제외합니다. @include(if: $condition)은 조건이 true일 때만 필드를 포함합니다. 논리적으로 서로 반대입니다. 둘 다 Boolean 변수를 받아, 클라이언트가 쿼리 문자열을 변경하지 않고도 동적으로 가져올 필드를 제어할 수 있게 합니다.

GraphQL 서브스크립션은 실시간 데이터에 어떻게 동작하나요?

서브스크립션은 클라이언트와 서버 사이에 지속적인 WebSocket 연결을 설정합니다. 서버에서는 PubSub 인스턴스가 mutation 리졸버에서 이벤트를 발행(pubsub.publish("TOPIC", data))합니다. 구독 리졸버는 pubsub.asyncIterator(["TOPIC"])로 해당 토픽을 구독하고, 발행된 각 이벤트를 연결된 클라이언트에게 스트리밍합니다.

커스텀 GraphQL 디렉티브란 무엇이고 언제 사용하나요?

커스텀 디렉티브는 스키마 어노테이션(예: directive @auth(requires: Role!) on FIELD_DEFINITION)으로, 필드 리졸버 실행을 가로채어 인증, 권한 부여, 입력 유효성 검사, 요청 제한 등의 횡단 관심사 동작을 추가합니다. 이 로직을 개별 리졸버에서 분리하여 재사용 가능한 스키마 레벨 관심사로 중앙화합니다.

GraphQL context 객체란 무엇이고 리졸버에서 어떻게 사용하나요?

context는 요청 내 모든 리졸버에 전달되는 공유 객체로, 일반적으로 데이터베이스 연결, 인증된 사용자 정보, 서비스 인스턴스를 포함합니다. 리졸버 시그니처 (parent, args, context, info)에서 세 번째 인자로 접근합니다: context.db.users.findAll(), context.user.id 등. 서버의 context 함수에서 요청당 한 번 설정됩니다.