概要
実験的に、 typed-graphqlify
というライブラリを作りました。
TypeScript の型定義っぽいものから、 GraphQL の文字列を生成してくれるライブラリです。
TypeScript + GraphQL の痛みが解消できれば嬉しい。
モチベーション
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
// }
// }
// }
うまくいけば、下記の画像のように型が定義されるはずです。
もっと詳しい使い方は、 GitHub のリポジトリをご参照頂けると嬉しいです。
特徴
- ネストしたクエリを定義できる
- 配列を定義できる
- オプショナル型を定義できる (
types.optional.integer
)
所感
かなり便利そうなので、しばらく使ってみます。
で、これ作った後に知ったのですが、 GraphQL のスキーマから TypeScript の型定義を生成するツールはあるみたいですね・・・
他にあるツールとして、 Apollo-CLI や graphql-code-generator, graphqlgen など。
スキーマの更新が必要になってくる、必要なカラムは定義しないといけない、等の問題があるかも(多分)。でもそっちの方が確実で良いかも。作っちゃった。
Thanks
Inspired by
Refs