LoginSignup
9
3

More than 5 years have passed since last update.

TypeScript の型定義から GraphQL のクエリを出力するライブラリを作った

Last updated at Posted at 2018-12-18

概要

実験的に、 typed-graphqlify というライブラリを作りました。

TypeScript の型定義っぽいものから、 GraphQL の文字列を生成してくれるライブラリです。
TypeScript + GraphQL の痛みが解消できれば嬉しい。

image.png

モチベーション

GraphQL は良いのですが、戻り値をハンドリングする際、 TypeScript の型定義と二重で管理するのがつらい時があります。

普通に書くとこんな感じになると思います。

interface GetUserQueryData {
  getUser: {
    id: number
    name: string
    bankAccount: {
      id: number
      branch: string
    }
  }
}

const query = graphql(gql`
  query getUser {
    user {
      id
      name
      bankAccount {
        id
        branch
      }
    }
  }
`)

apolloClient.query<GetUserQueryData>(query).then(data => ...)

せっかく TypeScript で型定義しているので、そこから GraphQL も自動生成できたら楽ですよね。

そこで、 TypeScript の型定義と GraphQL を足して2で割ったような JS のオブジェクトから、 GraphQL の文字列を生成するのが typed-graphqlify です。

使い方

インストール

yarn add typed-graphqlify

まず、 GraphQL っぽい JS のオブジェクトを作ります。これがそのまま型定義になります。

import { graphqlify, types } from 'typed-graphqlify'

const getUserQuery = {
  getUser: {
    user: {
      __params: { id: 1 },
      id: types.number,
      name: types.string,
      bankAccount: {
        id: types.number,
        branch: types.string,
      },
    },
  },
}

types を使って、 TypeScript っぽい型定義をしているところに注目してください。

次に、graphqlify 関数で、これを文字列に変換します。

const gqlString = graphqlify('query', getUserQuery)

console.log(gqlString)
// =>
//   query getUser {
//     user(id: 1) {
//       id
//       name
//       bankAccount {
//         id
//         branch
//       }
//     }
//   }

最後に、 GraphQL を実行します。

// We would like to type this!
const result: typeof getUser = executeGraphql(graphqlify('query', getUser))

//`result` を `typeof getUser` にキャストしたので、型定義が生きている
// `result` の型はこんな感じ。
// interface result {
//   user: {
//     id: number
//     name: string
//     bankAccount: {
//       id: number
//       branch: string
//     }
//   }
// }

うまくいけば、下記の画像のように型が定義されるはずです。

image.png

もっと詳しい使い方は、 GitHub のリポジトリをご参照頂けると嬉しいです。

特徴

  • ネストしたクエリを定義できる
  • 配列を定義できる
  • オプショナル型を定義できる (types.optional.integer)

所感

かなり便利そうなので、しばらく使ってみます。

で、これ作った後に知ったのですが、 GraphQL のスキーマから TypeScript の型定義を生成するツールはあるみたいですね・・・
他にあるツールとして、 Apollo-CLI や graphql-code-generator, graphqlgen など。

スキーマの更新が必要になってくる、必要なカラムは定義しないといけない、等の問題があるかも(多分)。でもそっちの方が確実で良いかも。作っちゃった。

Thanks

Inspired by

Refs

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3