1
votes

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!

2
Not sure if it's worth noting but that schema is built using buildSchema from the npm library "graphql".jProg2015

2 Answers

0
votes

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.

-1
votes

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.