GraphQL.js Node/Express: How to pass object as Gra

2019-05-16 12:56发布

问题:

My goal is to be able to pass an object as an argument in a GraphQL query.

Goal:

{
    accounts (filter: 
      {"fieldName": "id",
      "fieldValues":["123"],
      "filterType":"in"}){
        id
      }
 }

Error:

"message": "filterType fields must be an object with field names as keys or a function which returns such an object."

I've tried a few different approaches but this seems to be the closest to the potential solution.

Schema:

const filterType = new GraphQLObjectType ({
  name: 'filterType',
  fields: {
    fieldName: { type: GraphQLString },
    fieldValues: { type: GraphQLString },
    filterType: { type: GraphQLString },
  }
})

const QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: () => ({
    accounts: {
      type: new GraphQLList(accountType),
      args: {
        filter: { type: new GraphQLInputObjectType(filterType) },
      },
      resolve: (root, args, { loaders }) => loaders.account.load(args),
    },

  }),
});

回答1:

You don't define filterType as an object type then wrap it in an input type, you literally create it as an input type:

const filterType = new GraphQLInputObjectType({
  name: 'filterType',
  fields: {
    fieldName: { type: GraphQLString },
    fieldValues: { type: GraphQLString },
    filterType: { type: GraphQLString },
  }
})

const QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: () => ({
    accounts: {
      type: new GraphQLList(accountType),
      args: {
        filter: { type: filterType },
      },
      resolve: (root, args, { loaders }) => loaders.account.load(args),
    },
  }),
});

You'll also want to declare its type at query time, as illustrated in @piotrbienias's answer.



回答2:

I have found the solution here. https://github.com/mugli/learning-graphql/blob/master/7.%20Deep%20Dive%20into%20GraphQL%20Type%20System.md#graphqlinputobjecttype

Schema:

const filterType = new GraphQLInputObjectType({
  name: 'filterType',
  fields: {
    fieldName: { type: GraphQLString },
    fieldValues: { type: GraphQLString },
    filterType: { type: GraphQLString },
  }
})

const QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: () => ({
    accounts: {
      type: new GraphQLList(accountType),
      args: {
        filter: { type: filterType },
      },
      resolve: (root, args, { loaders }) => {
        return loaders.account.load(args)},
    },
  }),
});

Problem was in the query, I had the both the keys and values as strings in the object argument.

Correct Query:

{
  accounts(filter: {fieldName: "id", fieldValues: "123", filterType: "in"}) {
    id
  }
}