3

RedwoodJS automatically maps GraphQL queries resolvers to api/src/services. How do I create a field resolver for a given GraphQL type?

Suppose I have this schema:

type Person {
  name: string!
  birthDate: DateTime!
  age: Int!
}

But only name and birthDate are stored in the database.

Using graphql-tools I would write my resolvers like this:

const resolvers = {
  Query: { ... },
  Mutation: { ... },
  Person: {
    age(person) {
      return new Date().getFullYear() - person.birthDate.getFullYear();
    },
  },
};

PS: I know the age formula is wrong.

PS2: I'm using age here for the sake of simplicity, imagine this is expensive to compute or get from database.

gfpacheco
  • 2,831
  • 2
  • 33
  • 50

2 Answers2

6

It's almost identical to the way you do it with graphql-tools.

You export an object with the same name as your type in your service:

// services/person.js
export const Person = {
    age: (_args, { root }) {
      return new Date().getFullYear() - root.birthDate.getFullYear();
    },
}

As an aside, you could also export a resolvers in the person.sdl.js file (But services take precendence):

// graphql/person.sdl.js

export const schema = gql`/* ... */`

export const resolvers = {
  Query: {},
  Mutation: {},
  Person: {},
}
peterp
  • 3,145
  • 1
  • 20
  • 24
0

Edit: I misunderstood the question, this answer just covers creating query + mutation resolvers, not a resolver for a computed field.

To create a field resolver, you'll need to decide whether you're creating a resolver for a query, or a handler for a mutation.

We can use the following schema as an example:

export const schema = gql`
  type Person {
    id: String!
    name: String!
    age: Int!
  }

  type PersonInput {
    name: String
    age: Int
  }

  type Mutation {
    createPerson(input: PersonInput!): Person
  }

  type Query {
    people: [Person]
    person(id: String!): Person
  }
`

If the above schema is stored in a file called persons.sdl.js, in the api/src/graphql directory, you can implement the queries and mutations in a file called persons.js in the api/src/services/persons directory.

// implements Mutation.createPerson(...)
export const createPerson({ input }) => {
  return db.person.create({
    data: input
  })
}

// implements Query.people
export const people = () => {
  return db.person.findMany()
}

// implements Query.person(...)
export const person = ({ id }) => {
  return db.person.findOne({
    where: { id }
  })
}
Sam Weaver
  • 1,027
  • 16
  • 30
  • This doesn't answer my question about field resolvers, not query or mutation. I'll update the question, but what I mean is: imagine Person type has a field that is computed or a relation that need another query to the database – gfpacheco Mar 23 '20 at 17:34
  • I wonder if the resolver for the `Person.age` field should be a `age` function in a `api/src/services/persons/person.js` file – gfpacheco Mar 23 '20 at 17:50