简体   繁体   中英

Graphql resolveType union: throwing must resolve to an object type at runtime

I'm querying a union type in graphql, data comes from MongoDB database, driver: Mercurius, with Fastify framework. I'm trying to implement a search, by fetching data from 2 different database, for example one fetching products the other blog post, so I'm using union to list them both, but the error seems to be persistent.

Below is my schema

interface Details {
        _id: String!
    }

    type Temp {
        min: String
        max: String
        mean: String!
    }

    type Surface implements Details {
        orderFromSun: Int!
        name: String!
        hasRings: Boolean!
        _id: String!
        surfaceTemperatureC: Temp!
    }

    type MainAtmos implements Details {
        orderFromSun: Int!
        name: String!
        hasRings: Boolean!
        _id: String!
        mainAtmosphere: [String]
    }

    type User implements Details {
        _id: String!
        username: String!
        active: Boolean!
        email: String!
        accounts: [String]
    }

    union SearchResult = Surface | User

    type Query {
        add(x: Int, y: Int): Int
        planets: [MainAtmos]
        single_planet(id: String!): Surface
        search(text: String!): [SearchResult!]
        searchUsers(text:String!): [User]
    }

and here's my resolver:

const resolvers = {
    Query: {
        add: async (_, { x, y }) => x + y,
        planets: async (_, args, context, info) => {
            const result = await db.find().toArray();
            return result
        },
        single_planet: async (_, args, context, info) => {
            const result = await db.findOne({ _id: ObjectId(args.id) })
            return result
        },
        search: async (_, { text }, context, info) => {
            const result = await db.aggregate([{
                '$search': {
                  'index': 'default',
                  'text': {
                    'query': text,
                    'path': {
                      'wildcard': '*'
                    }
                  }
                }
              }]).toArray();

            const response = await usersDB.aggregate([{
                '$search': {
                  'index': 'customers',
                  'text': {
                    'query': text,
                    'path': {
                      'wildcard': '*'
                    }
                  }
                }
              }]).toArray();
            // return result
            const finalResponse = [...result, ...response];
            return finalResponse
        },
        searchUsers: async (_, { text }, context, info) => {
            const response = await usersDB.aggregate([{
                '$search': {
                  'index': 'customers',
                  'text': {
                    'query': text,
                    'path': {
                      'wildcard': '*'
                    }
                  }
                }
            }]).toArray();
            return response
        }
    },
    SearchResult: {
      __resolveType: (parameter, context, info) => {
        // return username ? 'User' : 'Surface'
        if (parameter.hasRings) {
          return 'Surface';
        }

        if (parameter.username) {
          return 'User';
        }

        return null;
      }
    },
}

and the error message

"Abstract type \"SearchResult\" must resolve to an Object type at runtime for field \"Query.search\". Either the \"SearchResult\" type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function."

Is there anything I might have done wrong? Here's my query:

query SearchResult {
search(text: "Elizabeth Ray ch4") {
    __typename 
    ... on Surface {
        name
        hasRings
    }
    ... on User {
        email
        accounts
    }
}

}

SearchResult: {
  //-- __resolveType
  resolveType: (parameter, context, info) => {
    // return username ? 'User' : 'Surface'
    if (parameter.hasRings) {
      return 'Surface';
    }

    if (parameter.username) {
      return 'User';
    }

    return null;
  }
},

Change __resolveType to resolveType .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM