How to
ExpressのGraphQLで相互のRelation関係にあるTypeをimportする方法
ExpressでGraphQLを実装している時に、TypeでRelationの関係を作ろうとして
1
Error: Expected undefined to be a GraphQL type
というエラーに出会いました。
原因はType同士でimportしていたために、一方のTypeがundefinedになってしまうことです。
この問題に対応してみました。
GraphQLのType同士で循環参照する場合
まず今回エラーが発生したコードは書きのようなものです。
それぞれのTypeからお互いをimportしています。
1 2 3 4 5 6 7 8 9 10 11
import UserType from './UserType'; const PostType = new GraphQLObjectType({ name: 'Post', fields: { title: { type: GraphQLString }, user: { type: UserType } } }); export default PostType;
1 2 3 4 5 6 7 8 9 10 11
import PostType from './PostType'; const UserType = new GraphQLObjectType({ name: 'User', fields: { name: { type: GraphQLString }, posts: { type: new GraphQLList(PostType) } } }); export default UserType;
お互いをimportしている循環参照の関係にあるため、当然ですがこのコードでは先に読み込まれる方が、読み込み先のTypeをundefinedとして認識します。
ただGraphQLでTypeを定義しているとこういうコードは避けられないと思う一方で、どのような風に対策するのがよいのか。
fieldsではオブジェクトではなく関数で返す
fieldsはオブジェクトではなく、オブジェクトを関数を指定できます。
関数で返すことをfieldsの部分が遅延評価されるようになり、先に書いたように読み込んだ時点ではundefinedでもエラーが発生しなくなります。
コードとしては下記のような形です。
1 2 3 4 5 6 7 8 9
const PostType = new GraphQLObjectType({ name: 'Post', fields: { title: { type: GraphQLString }, user: { type: UserType } } }); export default PostType;
1 2 3 4 5 6 7 8 9
const UserType = new GraphQLObjectType({ name: 'User', fields: { name: { type: GraphQLString }, posts: { type: new GraphQLList(PostType) } } }); export default UserType;
わかってしまえばなんてことないけど、少しハマってしまいました・・。