Search code examples
reactjsgraphqlrelayjsgraphql-js

React Relay update a root query as part of a mutation fat query


I am trying to build an application using GraphQL and React Relay.

As part of this I have created a root query with the following specification:

query {
  AllServices {
    edges {
      node {
        id
      }
    }
  }
}

So I have created a mutation - which works well - called CreateGithubService.

Here is a snippet from the Relay mutation:

getFatQuery() {
      return Relay.QL`
        fragment on CreateGithubServicePayload {
          createdService
        }
      `
  }

  getConfigs() {
      return [{
          type: "REQUIRED_CHILDREN",
          children: [
              Relay.QL`
                  fragment on CreateGithubServicePayload {
                      createdService {
                          id
                      }
                  }
              `
          ]
      }]
  }

The problem I have is that this is not causing the views which rely on the information to update.

My AllServices query is not refetched and I am unable to specify it in the Fat Query.

How can I setup my mutation to add the element to the all services query?

Thanks!


Solution

  • REQUIRED_CHILDREN will not update the local graph; it's strictly for fetching extra data that is only used in the success callback of the mutation update. In fact, it's not even documented outside of the source code, so I'm not sure how you decided to use it like this...

    Although you haven't said so, I assume you want this new node (createdService) to be added to the AllServices connection? If so, you need to tell Relay that your mutation affects that connection:

    1. At the moment, Relay basically assumes all mutations affect nodes, not arbitrary queries. To my knowledge, you won't be able to configure a mutation to update a non-node root query. Therefore, you should add a node at the root that acts as the parent of your AllServices connection (the convention for this is typically viewer). In other words, make it work like this: query { viewer { AllServices { ... } } }

    2. Your mutation payload should always return everything that has been changed, not just the new data. That means you need a way to refetch the AllServices connection from the payload. Once you add the viewer node to your schema, you can return that node in the mutation payload and change your fat query to specify that the connection has changed, e.g.: fragment on CreateGithubServicePayload { viewer { AllServices } }

    3. Given those two schema changes, you can then configure your mutation using FIELDS_CHANGE and specify the fieldIDs like { viewer: this.props.viewer.id }