GraphQL Codegen 사용법: 초보자 가이드

Maurice Odida

Maurice Odida

20 June 2025

GraphQL Codegen 사용법: 초보자 가이드

끊임없이 진화하는 웹 개발 환경에서 GraphQL은 기존 REST API의 강력한 대안으로 떠올랐으며, 클라이언트가 필요한 데이터를 정확하게 요청할 수 있는 기능을 제공합니다. 하지만 이러한 유연성은 특히 프런트엔드와 백엔드 간의 타입 안정성을 유지하는 데 있어 새로운 과제를 야기할 수 있습니다. 바로 이 지점에서 graphql-codegen이 등장합니다. 이 혁신적인 도구는 GraphQL 스키마로부터 타입이 지정된 코드를 자동으로 생성하여 개발 워크플로우를 대폭 개선하고 런타임 오류의 상당 부분을 제거합니다.

이 글은 graphql-codegen을 이해하고 숙달하기 위한 가이드 역할을 할 것입니다. 기본적인 개념부터 시작하여 도구를 설정하고 구성하는 실용적인 단계별 예제를 살펴보고, 프로젝트에 통합하기 위한 모범 사례를 탐색할 것입니다. 이 가이드를 마치면 graphql-codegen을 활용하여 더욱 견고하고 유지보수하기 쉬우며 타입 안전성이 높은 애플리케이션을 구축할 수 있게 될 것입니다.

💡
아름다운 API 문서를 생성하는 훌륭한 API 테스트 도구를 원하시나요?

최대 생산성으로 개발팀이 함께 작업할 수 있는 통합된 올인원 플랫폼을 원하시나요?

Apidog는 귀하의 모든 요구 사항을 충족하며, 훨씬 저렴한 가격으로 Postman을 대체합니다!
button

graphql-codegen이란 무엇이며 왜 필요한가요?

본질적으로 graphql-codegen은 GraphQL 스키마와 GraphQL 오퍼레이션(쿼리, 뮤테이션, 서브스크립션)을 인트로스펙트하고 다양한 언어로 코드를 생성하는 명령줄 도구입니다. 이 초보자 가이드에서는 가장 일반적인 사용 사례인 프런트엔드 애플리케이션을 위한 TypeScript 타입 및 훅 생성에 초점을 맞출 것입니다.

graphql-codegen이 해결하는 주요 문제는 GraphQL API의 데이터 구조와 쿼리 결과에 대한 TypeScript 인터페이스를 수동으로 작성하는 지루하고 오류가 발생하기 쉬운 과정입니다. 이 도구가 없으면 개발자는 타입이 지정되지 않은 데이터로 작업하거나(TypeScript의 이점을 잃게 됨) API가 발전함에 따라 쉽게 구식이 될 수 있는 타입을 생성하고 유지 관리하는 데 상당한 시간을 소비해야 합니다.

graphql-codegen을 도입하면 다음과 같은 여러 이점을 얻을 수 있습니다:

이 접근 방식은 GraphQL 스키마가 API의 단일 정보 소스 역할을 하는 "스키마 우선(schema-first)" 개발 철학과 완벽하게 일치합니다.

시작하기: 첫 번째 graphql-codegen 설정

graphql-codegen 사용의 실질적인 측면을 살펴보겠습니다. 이 튜토리얼에서는 GraphQL, TypeScript에 대한 기본적인 이해가 있고 Node.js와 패키지 관리자(npm 또는 yarn 등)가 설치되어 있다고 가정합니다.

우리의 목표는 간단한 React 애플리케이션에서 graphql-codegen을 설정하여 블로그 게시물 목록을 표시하는 것입니다.

1단계: 프로젝트 초기화 및 종속성 설치

먼저 TypeScript로 새 React 프로젝트를 생성하고 필요한 종속성을 설치해 보겠습니다.Bash

npx create-react-app my-blog --template typescript
cd my-blog
npm install @apollo/client graphql
npm install -D @graphql-codegen/cli @graphql-codegen/client-preset typescript

설치한 종속성에 대한 설명은 다음과 같습니다:

2단계: graphql-codegen 초기화 마법사

graphql-codegen을 시작하는 가장 쉬운 방법은 초기화 마법사를 사용하는 것입니다. 프로젝트의 루트 디렉토리에서 다음 명령을 실행합니다:Bash

npx graphql-codegen init

마법사는 프로젝트 구성을 돕기 위해 일련의 질문을 할 것입니다. 블로그 애플리케이션 시나리오에 대한 일반적인 답변 세트는 다음과 같습니다:

이 질문들에 답하면 마법사는 프로젝트 루트에 codegen.ts 파일을 생성하고 package.jsoncodegen 스크립트를 추가합니다.

3단계: 구성 파일(codegen.ts) 이해하기

codegen.ts 파일은 graphql-codegen 설정의 핵심입니다. 마법사가 생성하는 간소화된 버전을 살펴보겠습니다:TypeScript

import type { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
  overwrite: true,
  schema: "https://swapi-graphql.netlify.app/.netlify/functions/index",
  documents: "src/**/*.tsx",
  generates: {
    "src/gql/": {
      preset: "client",
      plugins: []
    }
  }
};

export default config;

주요 구성 옵션을 분석해 보겠습니다:

4단계: 첫 번째 GraphQL 쿼리 작성

이제 graphql-codegen이 구성되었으므로 블로그 게시물을 가져올 GraphQL 쿼리를 작성해 보겠습니다. 새 파일 src/components/Posts.tsx를 생성합니다:TypeScript

import { gql } from '../gql/gql';
import { useQuery } from '@apollo/client';

const GET_POSTS = gql(`
  query GetPosts {
    allFilms {
      films {
        id
        title
        director
        releaseDate
      }
    }
  }
`);

const Posts = () => {
  const { loading, error, data } = useQuery(GET_POSTS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <div>
      {data?.allFilms?.films?.map((film) => (
        <div key={film?.id}>
          <h2>{film?.title}</h2>
          <p>Director: {film?.director}</p>
          <p>Release Date: {film?.releaseDate}</p>
        </div>
      ))}
    </div>
  );
};

export default Posts;

생성된 src/gql/gql.ts 파일에서 gql 함수를 가져오는 것을 확인하세요. 이것은 client-preset에서 제공하는 gql 함수이며, 타입 추론의 마법을 가능하게 하는 것입니다.

5단계: graphql-codegen 실행 및 마법 확인

이제 package.json에서 codegen 스크립트를 실행합니다:Bash

npm run codegen

이 명령은 스키마를 인트로스펙트하고, GET_POSTS 쿼리를 찾아, 해당 TypeScript 타입을 src/gql 디렉토리에 생성합니다.

이제 Posts.tsxuseQuery 훅에서 반환된 data 객체를 검사하면 완전히 타입이 지정된 것을 볼 수 있습니다! IDE는 data.allFilms.films에 대한 자동 완성을 제공하고, 쿼리에 존재하지 않는 필드에 액세스하려고 하면 TypeScript가 경고할 것입니다.

심층 탐구: 실용적인 블로그 프런트엔드 예제

이해를 굳히기 위해 예제를 확장해 보겠습니다. 블로그가 다음과 같은 더 전통적인 스키마를 가지고 있다고 상상해 보세요:GraphQL

type Author {
  id: ID!
  name: String!
}

type Post {
  id: ID!
  title: String!
  content: String!
  author: Author!
}

type Query {
  posts: [Post!]!
  post(id: ID!): Post
}

type Mutation {
  createPost(title: String!, content: String!, authorId: ID!): Post!
}

이 스키마가 http://localhost:4000/graphql에서 실행되고 있다고 가정해 보겠습니다. 그에 따라 codegen.ts를 업데이트할 것입니다:TypeScript

// codegen.ts
// ...
schema: "http://localhost:4000/graphql",
// ...

이제 단일 게시물을 표시하는 컴포넌트와 새 게시물을 생성하는 컴포넌트를 만들어 보겠습니다.

단일 게시물 가져오기TypeScript

// src/components/Post.tsx
import { gql } from '../gql/gql';
import { useQuery } from '@apollo/client';
import { useParams } from 'react-router-dom';

const GET_POST = gql(`
  query GetPost($id: ID!) {
    post(id: $id) {
      id
      title
      content
      author {
        id
        name
      }
    }
  }
`);

const Post = () => {
  const { id } = useParams<{ id: string }>();
  const { loading, error, data } = useQuery(GET_POST, {
    variables: { id },
  });

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <div>
      <h2>{data?.post?.title}</h2>
      <p>By {data?.post?.author?.name}</p>
      <p>{data?.post?.content}</p>
    </div>
  );
};

export default Post;

npm run codegen을 실행하면 GetPostQuery 및 해당 변수에 대한 타입이 생성되어 useQuery 훅 및 그 결과에 대한 타입 안전성을 제공합니다.

새 게시물 생성TypeScript

// src/components/CreatePost.tsx
import { gql } from '../gql/gql';
import { useMutation } from '@apollo/client';
import { useState } from 'react';

const CREATE_POST = gql(`
  mutation CreatePost($title: String!, $content: String!, $authorId: ID!) {
    createPost(title: $title, content: $content, authorId: $authorId) {
      id
    }
  }
`);

const CreatePost = () => {
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');
  const [createPost, { data, loading, error }] = useMutation(CREATE_POST);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    createPost({ variables: { title, content, authorId: '1' } }); // Assuming authorId '1' for simplicity
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Title"
        value={title}
        onChange={(e) => setTitle(e.target.value)}
      />
      <textarea
        placeholder="Content"
        value={content}
        onChange={(e) => setContent(e.target.value)}
      />
      <button type="submit" disabled={loading}>
        {loading ? 'Creating...' : 'Create Post'}
      </button>
      {error && <p>Error creating post: {error.message}</p>}
      {data && <p>Post created with ID: {data.createPost.id}</p>}
    </form>
  );
};

export default CreatePost;

여기서 graphql-codegenCreatePostMutation 및 해당 변수에 대한 타입을 생성합니다. 이를 통해 createPost 함수를 호출할 때 title, content, authorId에 대해 올바른 타입을 전달하도록 보장합니다.

고급 개념 및 모범 사례

graphql-codegen에 익숙해지면 더 많은 고급 기능과 모범 사례를 접하게 될 것입니다:

일반적인 문제 해결

graphql-codegen은 강력한 도구이지만, 초보자는 몇 가지 일반적인 문제에 직면할 수 있습니다:

결론: 타입 안전성의 미래를 받아들이세요

graphql-codegen은 단순한 코드 생성 도구 그 이상입니다. GraphQL로 애플리케이션을 구축하는 방식에 대한 패러다임 전환입니다. 자동화를 수용하고 스키마의 힘을 활용함으로써 더 견고하고 유지보수하기 쉬우며 작업하기 즐거운 코드베이스를 만들 수 있습니다.

이 튜토리얼은 graphql-codegen 시작을 위한 견고한 기반을 제공했습니다. 핵심 개념을 다루고, 실용적인 예제를 살펴보고, 모범 사례를 언급했습니다. 여정은 여기서 끝나지 않습니다. graphql-codegen 생태계는 방대하며, 다양한 프레임워크 및 사용 사례를 충족하는 풍부한 플러그인 컬렉션을 가지고 있습니다. 공식 문서를 탐색하고, 다양한 플러그인을 실험하며, graphql-codegen이 GraphQL 개발 워크플로우를 어떻게 혁신할 수 있는지 발견해 보시기 바랍니다. 즐거운 코딩 되세요!

💡
아름다운 API 문서를 생성하는 훌륭한 API 테스트 도구를 원하시나요?

최대 생산성으로 개발팀이 함께 작업할 수 있는 통합된 올인원 플랫폼을 원하시나요?

Apidog는 귀하의 모든 요구 사항을 충족하며, 훨씬 저렴한 가격으로 Postman을 대체합니다!
button

Apidog에서 API 설계-첫 번째 연습

API를 더 쉽게 구축하고 사용하는 방법을 발견하세요