Programming

Graffle.js: JavaScript 개발자를 위한 간단하고 타입 안전한 GraphQL 클라이언트

danny-shim 2025. 10. 22. 14:05

안녕하세요, 개발자 여러분! GraphQL을 다루다 보면 클라이언트 라이브러리의 복잡함에 지치신 적이 있나요? 오늘은 그런 고민을 싹 날려줄 수 있는 새로운 도구, Graffle.js를 소개하려고 합니다. 이 라이브러리는 최소주의적 설계와 완벽한 타입 안전성을 강조하며, JavaScript 환경에서 GraphQL 쿼리를 더 쉽게 실행할 수 있게 해줍니다. 아직 개발 중인 프로젝트지만, 이미 강력한 잠재력을 보여주고 있어요. 이 포스트에서는 Graffle.js의 주요 기능, 설치 방법, 그리고 실제 사용 예제를 중심으로 살펴보겠습니다.

Graffle.js란 무엇일까?

Graffle.js는 Jason Kuhrt가 개발한 GraphQL 클라이언트로, Prisma와 Nexus 같은 프로젝트로 유명한 개발자의 손에서 탄생했습니다. 이 라이브러리의 핵심 철학은 단순함(minimal), 확장성(extensible), 타입 안전성(type-safe) 입니다. 어디서나 동작할 수 있도록 설계되었으며, HTTP 엔드포인트나 인메모리 스키마에 대한 실행을 지원합니다.

현재는 pre-release 버전으로, 안정화되지 않았지만 최신 기능을 체험하기에 딱입니다. MIT 라이선스 하에 공개되어 있어 자유롭게 사용할 수 있어요. GraphQL 쿼리를 작성할 때 타입 추론을 통해 실수 없이 코드를 작성할 수 있고, 필요에 따라 TypeScript API를 생성해 더 강력한 개발 경험을 제공합니다.

왜 Graffle.js를 써야 할까? 주요 기능

Graffle.js의 매력은 복잡한 설정 없이도 타입 안전한 쿼리를 실행할 수 있다는 점입니다. 주요 기능을 간단히 나열해 보죠:

  • 완벽한 타입 안전성: GraphQL 문법에 대한 전체 타입 추론과, 옵션으로 Document Builder를 통해 생성된 TypeScript API를 제공합니다. 변수와 결과에 대한 정적 타입 체크로 런타임 오류를 최소화해요.
  • 유연성: 기본 설정으로 시작해 점진적으로 타입 안전 기능을 추가할 수 있습니다. GraphQL 문자열을 직접 작성하거나, 타입 안전한 빌더 API를 선택할 수 있어요.
  • 확장성: 미들웨어 같은 확장 시스템을 통해 OpenTelemetry(관찰성), 스키마 오류 처리, 커스텀 스칼라 등을 쉽게 추가합니다.
  • 다중 전송 지원: HTTP URL이나 인메모리 스키마에 쿼리를 실행할 수 있어, 서버사이드나 클라이언트사이드 모두 유연합니다.
  • 커스텀 스칼라 지원: Date나 BigInt 같은 커스텀 타입을 위한 코덱을 등록해 인코딩/디코딩을 자동화합니다.

이 기능들은 Apollo Client나 Relay 같은 기존 라이브러리와 비교해도 가볍고 직관적입니다. 특히, 타입 안전성을 추구하는 TypeScript 개발자에게 추천해요.

설치와 기본 사용법

설치는 간단합니다. 아직 개발 중이니 pre-release 버전을 설치하세요:

npm install graffle@next graphql

기본적으로 Graffle.create()로 인스턴스를 생성하고, 전송(transport), 확장(extensions), 스칼라(scalars)를 체이닝으로 설정합니다. 쿼리는 gql 템플릿 리터럴이나 Document Builder로 실행할 수 있어요.

빠른 시작 예제

간단한 국가 쿼리를 HTTP 엔드포인트에 실행해 보죠. (countries.trevorblades.com 스키마 사용)

import { Graffle } from 'graffle'

const graffle = Graffle
  .create()
  .transport({ url: 'https://countries.trevorblades.com/graphql' })

const data = await graffle.gql`
  query {
    countries(filter: { name: { in: ["Canada", "Germany", "Japan"] } }) {
      name
      capital
      emoji
    }
  }
`.send()

console.log(data)

이 코드로 캐나다, 독일, 일본의 국가 이름, 수도, 이모지를 출력할 수 있습니다. 타입 추론 덕분에 data의 타입이 자동으로 알려져 편리해요.

Document Builder 사용: 타입 안전 쿼리

옵션으로 TypeScript API를 생성하면, 문자열 없이 IntelliSense를 활용한 쿼리를 작성할 수 있습니다. (포켓몬 스키마 예제)

const pokemons = await graffle.query.pokemons({
  $: { filter: { name: { in: ['Pikachu', 'Charizard'] } } },
  name: true,
  hp: true,
})

GraphQL 문자열 + 타입 추론

전통적인 GraphQL 문법을 좋아한다면 이 방식이 딱입니다.

const data = await graffle.gql(`
  query pokemonByName($name: String!) {
    pokemonByName(name: $name) {
      name
      hp
    }
  }
`).pokemonByName({ name: 'Pikachu' })

확장과 커스텀 스칼라 추가

OpenTelemetry를 추가하거나, Date 스칼라를 처리하는 예제입니다.

const graffle = Graffle
  .create()
  .use(OpenTelemetry())
  .use(SchemaErrors)
  .scalar('Date', {
    decode: (value: string) => new Date(value),
    encode: (value: Date) => value.toISOString(),
  })

const pokemons = await graffle.query.pokemons({
  $: { filter: { birthday: { lte: new Date('1987-01-13') } } },
  birthday: true, // JavaScript Date로 반환
})

이처럼 확장은 체이닝으로 쉽게 적용됩니다.

지원 요소와 한계

Graffle.js는 표준 GraphQL 요소(쿼리, 변수, 필터, 스칼라)를 지원하며, mutations도 유사하게 사용할 수 있습니다. 하지만 아직 개발 중이라 일부 기능(예: 스타일링이나 내보내기)은 없어요. 대신, 강력한 확장 시스템으로 커스터마이징이 가능합니다.

마무리: Graffle.js를 지금 써보세요!

Graffle.js는 GraphQL 클라이언트의 미래를 보여주는 프로젝트입니다. 타입 안전성과 유연성을 동시에 잡아, 초보자부터 고급 사용자까지 만족시킬 거예요. 아직 pre-release지만, npm으로 쉽게 설치해 테스트해 보세요. 더 자세한 문서는 공식 사이트에서 확인하세요.