GraphQL 사용법 알아보기

2017년 04월 01일


GraphQL 코드 분리하기

지금까지는 GraphQL 언어를 typeDefs에 정의해서 사용했습니다. 이런 방식은 따로 설정이 필요없고 직접 문자열을 다룰 수 있는 장점이 있습니다.

하지만 코드를 관리하는 입장으로 보면 GraphQL 코드는 다른 파일로 분리하는 것이 나아보입니다. 단순히 문자열에 대한 js파일을 만들 수도 있지만, GraphQL에 특화된 파일로 분리할 수 있다면 좋을것 같습니다.

이럴때 사용할 수 있는 것이 graphql-tag/loader입니다. 로더를 사용하면 GraphQL 코드를 다른 파일로 분리하고 다시 자바스크립트로 임포트 할 수 있습니다

graphql-tag/loader는 다음과 같이 설치합니다. 개발도구이기 때문에 -D를 줘서 devDependencies에 추가합니다.

yarn add -D graphql-tag

GraphQL 코드를 다른 파일로 분리한 뒤, 적절한 번들러와 로더를 이용해 하나로 합쳐줍니다. 여기서는 웹팩을 사용했습니다.

webpack.config.js

const path = require('path');
module.exports = {
  target: 'node',
  entry: './index.js',
  output: { path: __dirname, filename: 'bundle.js' },
  module: {
    rules: [
      {
        test: /\.(graphql|gql)$/,
        loader: require.resolve('graphql-tag/loader'),
      }
    ]
  }
};

typeDefs.gql

type Query { 
  getCity(id: ID!): City
}
type Mutation { 
  updateCity(id: ID!, name: String!): City
}
type City {
  id: ID!
  name: String!
  greeting: String!
}

schema.js

const { makeExecutableSchema } = require('graphql-tools');
const typeDefs = require('./typeDefs.gql');

const Query = { 
  getCity(root, args, context) {
    const { id } = args;
    return context.db[id];
  }
};
const Mutation = { 
  updateCity(root, args, context) {
    const { id, name } = args;
    let city = context.db[id];
    if (city)
      return Object.assign(city, { name });
    else 
      return null;
  }
};
const City = {
  name(city, args, context) {
    return `${city.name} city`;
  },
  greeting(city, args, context) {
    return `Hello, ${city.name} city`;
  }
};
const resolvers = { Query, Mutation, City };

module.exports = makeExecutableSchema({ typeDefs, resolvers });

이제 webpack을 실행해서 코드를 bundle.js로 번들링하고 node로 실행합니다.

로더가 올바르게 설정됐다면 require('./typeDefs.gql')를 통해 GraphQL 코드를 임포트 할 수 있습니다.

graphql-tag/loader의 또 다른 장점으로 #import 구문이 있습니다. 이는 공식적인 기능은 아니지만 주석 #와 import라는 키워드를 통해 GraphQL 코드 안에서 임포트를 사용할 수 있게 해줍니다.

#import "./Other.gql"

type Query { ... }