0

I have a Resource like:

{
  a: String
  b: String
  c: [JSON]
}

fields a and b are DB object's property, but field c is computed and that computing can take a time.

Problem is whenever I'm making query, it always calculates that field even if query specified only a and b fields to retrieve.

Is there any "graphql ways" to prevent calculating without passing additional parameter which will say to server "don't calculate field c"?

UPD: My resolver is something like:

const x = retrieveFromDB(...)
// x = {a: 'x', b: 'y'}
x.c = computingField(...) // it takes a lot of time
return x
Grzegorzg
  • 659
  • 1
  • 4
  • 17
  • Are the items with properties a, b, and c, and JSON graphql Types that you defined? Can you provide more detail regarding property c and how it is computed? – Greg Brodzik Oct 07 '19 at 23:54

1 Answers1

1

GraphQL fields are never resolved unless they are explicitly requested.

Let's look at a slightly more complicated example. Let's say we have this schema:

type Query {
  getUser: User
}

type User {
  firstName: String
  lastName: String
  fullName: String
}

And our resolvers look like this:

const resolvers = {
  Query: {
    getUser: () => ({ firstName: 'Susan', lastName: 'Martinez' }),
  },
  User: {
    fullName: (user) => `${user.first_name,} ${user.last_name,}`,
  },
}

We return a user object in our getUser resolver. We rely on the default resolver behavior for the firstName and lastName fields, but provide a custom resolver for fullName. If we make this query:

query {
  getUser {
    firstName
  }
}

only two resolvers are called -- the one for getUser and the one for firstName. However, this query

query {
  getUser {
    firstName
    fullName
  }
}

will also cause the fullName resolver to be called. Each resolver has access to whatever value the parent field resolved to. So if determining the fullName is expensive, you can move the logic for evaluating that value into the field's resolver.

On the other hand, if you just need to know which child fields were requested, there's already an answer for that.

Daniel Rearden
  • 80,636
  • 11
  • 185
  • 183