1

I've spent quite a bit of time reading through the GraphQL tutorials but unfortunately they don't seem to cover things in quite enough depth for me to get my head around. I'd really appreciate some help with this real world example.

In the examples the queries are placed at the root of the resolver object; I can get this to work fine for single level queries. When I attempt to resolve a nested query however the nested resolver never gets called. What I'm massively confused by is every tutorial I find that isn't issued on the graphql website put in a Query object and nest their queries underneeth that, not root level.

Consider the following Schema:

type Product {
  id: String!
  retailerId: String!
  title: String!
  description: String
  price: String!
  currency: String!
}

type OrderLine {
  product: Product!
  quantity: Int!
}

type Order {
  id: String!
  retailerId: String!
  orderDate: Date!
  orderLines: [OrderLine!]!
}

type Query {
  product(id: String!): Product
  order(id: String!): Order
}

schema {
    query: Query
}

And the following query:

query {
    order(id: "1") {
        id
        orderLines {
            quantity
        }
    }
}

I have tried multiple versions of implementing the resolvers (just test data for now) and none seem to return what I exect. This is my current resolver implementation:

const resolvers = {
  OrderLine: {
    quantity: () => 1,
  },
  Order: {
    orderLines: (parent: any, args: any) => { console.log("Calling order lines"); return []; },
  },
  Query: {
    product(parent, args, ctx, other) {
      return { id: args.id.toString(), test: true };
    },
    order: ({ id }) => { console.log("Calling order 1"); return { id: id.toString(), testOrder: true, orderLines: [] }; },
  },
  order: ({ id }) => { console.log("Calling order 2"); return { id: id.toString(), testOrder: true, orderLines: [] }; },
};

In the console I can oberse the "Calling order 2" log message, there are no logs to "Calling order lines" and the order lines array is empty.

So two part question:

1) Why does it hit "Calling order 2" and not "Calling order 1" in the above example?

2) Why won't the above work for the nested query Order.OrderLines?

Thanks in advance!

jProg2015
  • 1,098
  • 10
  • 40
  • Not sure if it's worth noting but that schema is built using buildSchema from the npm library "graphql". – jProg2015 Sep 17 '19 at 13:21

2 Answers2

0

In query

type Query {
  product(id: String!): Product
  order(id: String!): Order
  users: User
}
schema {
    query: Query
}

In resolvers

const resolvers = {
  order: ({ id }) => function
  product: ({ id }) => function
}

Graphql work on query resolver concept. If you want to any query(example users) you must have resolver(ie users) which return User having definition in type User. Graphql query is interactive and case sensitive The next step is to implement the resolver function for the order/product query. In fact, one thing we haven’t mentioned yet is that not only root fields, but virtually all fields on the types in a GraphQL schema have resolver functions.

1) Why does it hit "Calling order 2" and not "Calling order 1" in the above example? In this Query

 query {
    order(id: "1") {
        id
        orderLines {
            quantity
        }
    }
 } 

then it go to order which return Order with define type

2) Why won't the above work for the nested query Order.OrderLines?

You can only use two query first order and second product only as per your schema

Please check doc for nested query for this requirement.

Ashok
  • 2,846
  • 1
  • 12
  • 20
-1

If you use buildSchema to generate your schema, the only way to provide resolvers for your fields is through the root object. But this is more of a hack -- you're not actually overriding the default resolvers for the fields and as such, you're basically limited to just working with the root-level fields (as you are learning the hard way). This is why only the Query.order function is called -- this is a root-level field. Why passing functions through the root (kind of) works is explained in detail here.

The bottom line is you shouldn't be using buildSchema. If you want to use SDL to define your schema, migrate to using Apollo Server.

Daniel Rearden
  • 80,636
  • 11
  • 185
  • 183
  • It doesn't work with Apollo server either, and they're indicating it is not supported: https://github.com/apollographql/graphql-tools/issues/1026 – Developer Dave Apr 02 '20 at 07:09
  • @DeveloperDave I'm not sure what you're referring to. Providing resolvers for any field, not just root fields, which is what OP was having trouble with, *is supported* when using Apollo Server. The issue you linked is only referring to some unsupported syntax for defining the resolver map. – Daniel Rearden Apr 02 '20 at 10:20
  • Nope. You misunderstood his question (google seems to understand it as it referred this stackoverflow issue thread in addition to that Github issue thread). Both are referring to challenges which occur when troubleshooting why _nested_ resolvers are not invoked. I ran across the same issue last night as well, where a resolver on a "grandchild" field of the response object from one of my queries wasn't being invoked. Besides, this issue occurs whether you're using Apollo / graphql-tools or not (I'm using it and so was the gentleman on that github issue thread). – Developer Dave Apr 03 '20 at 06:35