Looking for the Prisma documentation? You can find it here

Hooks

Last updated a day ago Edit this page

#Overview

Graphcool allows to intercept the requests that are sent to your GraphQL API and invoke functions when it reaches one of the dedicated hook points. This allows to perform data transformation and validation operations on the request payload or synchronously call out to 3rd-party APIs.

Graphcool offers two of these hook points:

  • operationBefore: Invoked right before a write to the database
  • operationAfter: Invoked right after a write to the database

Functions invoked through these hooks are executed synchronously.

Notice that for nested mutations, the operationBefore and operationAfter hooks are invoked for each individual write operation. If you're creating a User and a new Post in the same (nested) mutation, this means operationBefore and operationAfter are each invoked twice.

#Adding a Hook function to a service

When you want to create a hook function in your Graphcool service, you need to add it to the service configuration file under the functions section.

#Example

Here is an example of two hook functions:

1
2
3
4
5
6
7
8
9
10
11
12
functions:
  validateEmail:
    type: operationBefore
    operation: User.create
    handler:
      webhook: http://example.org/email-validator
  reloadProfilePicture:
    type: operationAfter
    operation: Photo.update
    handler:
      code:
        src: ./code/reloadProfile.js
  • validateEmail is invoked before a User node is created and is defined as a webhook.
  • reloadProfilePicture is invoked after a Photo node is updated and is defined as a managed function.

#Properties

Each function that's specified in the service definition file needs to have the type and handler properties.

For hook functions, you additionally need to specify the concrete operation which consists of a model type and the specific database write (create, update or delete), e.g. User.create or Post.delete.

#Input type

The input type for these hook functions is determined by the input arguments of the mutation that invokes the function.

Consider the following mutation:

1
updateUser(id: ID!, name: String, email: String): User

The input type for the operationBefore and operationAfter functions can is the following:

1
2
3
4
5
type UpdateUserInput {
  id: ID!
  name: String
  email: String
}

#Current limitations

  • Input arguments for nested mutations are read-only at the moment. Changes to these are ignored. This applies to all hook points.

#Current limitations

Currently, only fields that are already part of the mutation payload can be modified. No fields can be added or removed.

#Examples

No transformation

The request is not modified at all.

1
2
3
4
5
export default event => {
  console.log(`event: ${event}`)

  return {data: event.data}
}

Computed fields

Some of the input arguments are used to compute a different input argument.

1
2
3
4
5
6
export default event => {
  console.log('Compute area')
  event.data.area = event.data.width * event.data.length

  return event
}

Input validation

Reject further processing of the incoming GraphQL mutation by throwing an error.

1
2
3
4
5
6
7
8
9
export default event => {
  if (event.data.length < 0 || event.data.width < 0) {
    return {
      error: 'Length and width must be greater than 0!'
    }
  }

  return event
}

Was this page helpful?