Documentation
Building your API (server)
Queries and Mutations

Queries and Mutations

The API consists of entry-points which we will use to fulfill our data-requirements, often when we start a new page we'll need to either use an existing entry-point or create a new one.

For retrieving data one or more of those entry-points can be created with the addQueryFields function.

import { addQueryFields } from 'fuse'
 
addQueryFields(t => ({
  me: t.field({
    type: UserNode,
    resolve: (parent, args, context) => context.userId
  })
}))

The above could for instance be an entry-point for a profile page or any page that has a menu-dropdown welcoming the user.

Our API should also be able to manipulate data, these are referred to as mutations and can be added similarly to query entry-points by means of addMutationFields.

import { addMutationFields } from 'fuse'
 
addMutationFields(t => ({
  sayHello: t.field({
    type: 'String',
    args: {
      name: t.arg.string({ required: true })
    }
    resolve: (parent, args, context) => `Hello ${args.name}!`
  })
}))

Now we have an entry-point to retrieve our own user and to greet a user!

Arguments

As you can see in the above examples we can define arguments for our entry-points, these arguments are optional by default and can be made required by means of { required: true }. All scalar values have their own t.arg which can be used to define arguments on a field. The mention of field is important here as arguments aren't exclusive to query and mutation entry-points, they can be used on any field. An example of this could be when we extend the UserNode and want to add a friends field to it, we can add args there to make the list of friends paginated.

Summing up all the built-in argument scalars:

  • id
  • string
  • boolean
  • int
  • float

Most of these also have a *List equivalent to indicate you will pass an array of that scalar type.

We won't always be passing in scalar-values and we might even want to re-use certain inputs for multiple fields, like for example a PaginationInput which we can use on any field we paginate over. We can do this by importing inputType from fuse and creating one as followed

import { inputType } from 'fuse'
 
const PaginationInput = inputType({
  name: 'PaginationInput',
  fields: (t) => ({
    offset: t.int({ defaultValue: 0 }),
    limit: t.int({ defaultValue: 10 }),
  }),
})

Now when we want to use PaginationInput we can pass it to t.arg, for example { pagination: t.arg({ type: PaginationInput }) }.

Now we can pass this input to our fields accepting these arguments!