RFC 0 / Strawman

Add support for directives for an object field name

Opened on2020-04-07
Updated on2021-10-26

At a glance

Spec PR description

Custom directives have been widely used to increase the power of GraphQL, however they are missing from object field names.

NOTE: Such directives are also missing from argument names as well, but we don't have a pressing use case for that. However, I think for uniformity and extensibility, they should be allowed in both object fields and arguments, but that's a topic for another PR (though I'm happy to included here if people want it).

Back to object fields.

It would be useful to indicate a different mutation behavior. For example, in a mutation whose purpose is to update an object, we can can consider the default behavior to update only the objects and fields specified in the mutation.

There is a pattern in some GraphQL implementations of automatically generating generic CRUD queries and mutations in the schema, where the actual definitions are declared outside of the GraphQL schema.

In this example, we have a generic updateCustomer mutation (automatically generated in the schema) which allows arbitrary changes to the customer.

input CustomerInput {
  id: String
  address: AddressInput
}

input AddressInput {
  street1: String
  apartment: String
  city: String
  state: String
  zipCode: String
}

If we wanted to change the zip code, without changing anything else:

mutation { 
  updateCustomer( input: { id: "custId"
    address: { 
      zipCode: "94610-2233" 
    } 
  } ) { id }
}

However, if we wanted to replace the entire address, we could use a custom directive @replace which would replace the entire contents of the object with what was specified. So in this case, if the customer previously had an apartment, that would not be present after this mutation:

mutation { 
  updateCustomer( input: { id: "custId"
    @replace address: { 
      street1: "123 Main St"
      city: "Oakland"
      state: "CA"
      zipCode: "94610"
    } 
  } ) { id }
}

Of course you could argue that simply providing null values for all of the other fields would accomplish the same thing, but this is tedious and error-prone. And in fact the client may not know all of the possible values in the object.

Note also, contrary to the other locations directives are used, the directive would appear before the name rather than after. This is to make the syntax with the use of the ":" separating the name and value more clean.

If this is accepted, I would be happy to do the work of championing the process to implementation, including any required work in the reference implementations.

Timeline