Finlay Beaton
Finlay Beaton

Reputation: 620

how to nest graphql queries

All the examples I find have a query top level object, then a list of queries, which then return types to go deeper.

Since I have a large number of queries, I would like to group them up, this is what I tried:

const AppType = new GraphQLObjectType({
    name: 'App',
    description: 'Generic App Details',

    fields: () => ({
        name: { type: GraphQLString },
        appId: { type: GraphQLInt },
    }),
});

const MyFirstQuery = {
    type: new GraphQLList(AppType),
    args: {
        appId: { type: GraphQLInt },
    },
    resolve: (root, args) => fetchApp(args.appId),
};     

/* snip MySecondQuery, MyThirdQuery, MyFourthQuery */

const MyFirstGroupQuery = new GraphQLObjectType({
    name: 'myFirstGroup',
    description: 'the first group of queries',

    fields: () => ({
        myFirstQuery: MyFirstQuery,
        mySecondQuery: MySecondQuery,
        myThirdQuery: MyThirdQuery,
        myFourthQuery: MyFourthQuery,
    }),
});

/* snip MySecondGroupQuery, MyThirdGroupQuery and their types */    

const QueryType = new GraphQLObjectType({
    name: 'query',
    description: 'read-only query',

    fields: () => ({
        myFirstGroup: MyFirstGroupQuery,
        mySecondGroup: MySecondGroupQuery,
        myThirdGroup: MyThirdGroupQuery,
    }),
});

const Schema = new GraphQLSchema({
    query: QueryType,
});

Why can't I make MyFirstGroupQuery like I did QueryType to make more nesting levels? The code works fine if I put all queries in QueryType, but my MyFirstGroupQuery produces errors:

Error: query.myFirstGroup field type must be Output Type but got: undefined.

How do I accomplish what I want? I really don't want to just prefix all my queries.

Upvotes: 0

Views: 948

Answers (1)

parwatcodes
parwatcodes

Reputation: 6796

Error query.myFirstGroup field type must be Output Type but got: undefined. means that you haven't provided the type for myFirstGroup you have to provide the type using type field

myFirstGroup: { type: MyFirstGroupQuery, resolve: () => MyFirstGroupQuery, },

and if the type MyFirstGroupQuery each field must have the type defined such as GraphQLInt, GraphQLString, GraphQLID even if it's tht customtype like MyFirstGroupQuery

In GraphQLSchema constructor function you provide your RootQuery which is QueryType, It's a GraphQLSchema it only accepts the rootQuery with the GraphQLObjectType whose fields must have the type defined

GraphQL is strictly type based, every field you declared must have the type defined

https://github.com/graphql/graphql-js

https://github.com/graphql/graphql-js/blob/master/src/type/schema.js#L32

const {
    GraphQLID,
    GraphQLInt,
    GraphQLString,
    GraphQLObjectType,
    GraphQLSchema,
    GraphQLList,
} = require('graphql');

const AppType = new GraphQLObjectType({
    name: 'App',
    description: 'Generic App Details',

    fields: () => ({
        name: { type: GraphQLString },
        appId: { type: GraphQLInt },
    }),
});

// const MyFirstQuery = {
//     type: new GraphQLList(AppType),
//     args: {
//         appId: { type: GraphQLInt },
//     },
//     resolve: (root, args) => fetchApp(args.appId),
// };

const myFirstQuery = new GraphQLObjectType({
    name: 'First',
    fields: () => ({
        app: {
            type: new GraphQLList(AppType),
            args: {
                appId: { type: GraphQLInt },
            },
            resolve: (root, args) => fetchApp(args.appId),
        },
    }),
});

/* snip MySecondQuery, MyThirdQuery, MyFourthQuery */

const MyFirstGroupQuery = new GraphQLObjectType({
    name: 'myFirstGroup',
    description: 'the first group of queries',
    fields: () => ({
        myFirstQuery: {
            type: myFirstQuery,
            resolve: () => [], // promise
        },
        // mySecondQuery: {
        //     type: MySecondQuery,
        //     resolve: () => //data
        // }
        // myThirdQuery: {
        //     type: MyThirdQuery,
        //     resolve: () => // data
        // }
        // myFourthQuery: {
        //     type: MyFourthQuery,
        //     resolve: () => //data
        // }
    }),
});

/* snip MySecondGroupQuery, MyThirdGroupQuery and their types */

const QueryType = new GraphQLObjectType({
    name: 'query',
    description: 'read-only query',

    fields: () => ({
        myFirstGroup: {
            type: MyFirstGroupQuery,
            resolve: () => MyFirstGroupQuery,
        },
        // mySecondGroup: {
        //     type: MySecondGroupQuery,
        //     resolve: MySecondGroupQuery
        // }
        // myThirdGroup: {
        //     type: MyThirdGroupQuery,
        //     resolve: MyThirdGroupQuery
        // }
    }),
});

const Schema = new GraphQLSchema({
    query: QueryType,
});

module.exports = Schema;

GraphiQL

enter image description here

Upvotes: 2

Related Questions