6
votes

I was following tutorial for React + Relay + GraphQL @ https://facebook.github.io/relay/docs/tutorial.html

And I was confused on what interface : [nodeInterface] does in a GraphQL object definition.

2

2 Answers

7
votes

Short Answer

nodeInterface is ONLY used by GraphQL when the client-side (usually browser) requests for a piece of GraphQL data that is already in its possession from initial fetch, to be re-fetched.

Re-fetch is performed under any of these circumstances:

  • A different/same React component (on the same web page) requests for additional pieces of data, at a later stage, and those data are not available in the initial data fetched
  • The code in React component executes this.props.relay.forceFetch(), which usually happens if programmer believes that the data on the server-side may have changed due to other external
  • The code in React component executes this.props.relay.setVariable(...) when the user performs an action such as changing the number of items to show, picture size, etc., that requires a variation of the initially fetched data.

During re-fetch, GraphQL calls nodeInterface with the (global) Node ID, which the nodeInterface needs to retrieve the server-side object associated with that Node ID. With that server-side object, the GraphQL server can then return additional/variation of data required by the client.

Thus, Node ID is never required if initial object data is never re-fecthed.

For more details, please refer to: https://medium.com/@khor/relay-graphql-de-mystifying-node-id-38757121b9c

Details

nodeInterface performs Node ID to server-side object resolution thus it always looks something like:

var {nodeInterface, nodeField} = nodeDefinitions(
  (globalId) => {
    var {type, id} = fromGlobalId(globalId);

    if (type === 'ClassA') {
      // Get ClassA type of instance with id
      // E.g.,
      return ClassA.find_by_id(id)
    } else if (type === 'ClassB') {
      return ClassB.find_by_id(id)
    }

    ...
  }
)

Since GraphQL types that needs to be re-fetched needs Node ID, in the GraphQL schema you need to:

  • Request that GraphQL auto-generates the Node ID upon creation of the instance of the GraphQL type, using globalIdField keyword
  • Tell GraphQL how that GraphQL type resolves the Node ID provided during re-fetch back into the corresponding server-side object, which is your interface : [nodeInterface]

Thus:

var ClassAType = new GraphQLObjectType({
  name: 'ClassA',
  description: 'A',
  fields: () => ({
    id: globalIdField('ClassA'),

    ... other fields ...

  }),
  interfaces: [nodeInterface],
});
5
votes

For a Relay compliant GraphQL server, object with a global ID is called a Node, any node could be refetch by query

{
  node: (id: "some global id") {
    id,
    ... on SomeType {
      someField
    }
  }
} 

Node interface is used for that on GraphGL schema, which helps you to define the Type with global id.

Check details on Global Object Identification and it's Specification