Skip to content

GraphQL Compose

The Compound Field GraphQL Compose sub-module puts compound fields in the schema GraphQL Compose 2.x builds. Each compound becomes a GraphQL type of its own, configured on GraphQL Compose's schema form like a paragraph type. Each sub-field is exposed through GraphQL Compose's own plugin for its field type, so a string, link, date, file, image or reference sub-field looks and resolves the way the same field does on the host.

Install

drush en compound_field_graphql_compose

The sub-module needs GraphQL Compose 2.4 or later. GraphQL Compose 3.x is not supported yet.

Expose a compound field

Settings live on GraphQL Compose's own schema form, under Configuration → Web services → GraphQL Compose (/admin/config/graphql_compose). Every compound has a tab of its own under Compound fields, next to Content, Media and the other entity types.

  1. Enable the host's entity type and bundle, as for any GraphQL Compose field.
  2. Enable the compound field on that bundle's row.
  3. Under Compound fields, open the compound's tab, enable the compound, and enable each sub-field it should expose. Each sub-field's panel offers:
  4. Enable field: whether the sub-field is in the schema.
  5. Schema field name: its GraphQL name. Left blank, the name GraphQL Compose generates is used: the machine name without a field_ prefix, in camel case (start_time becomes startTime).
  6. Embed view as GraphQL query: on a viewfield sub-field only, and only with GraphQL Compose Views enabled. See viewfield sub-fields.

A compound must be enabled on its own tab, with its sub-fields, or its host field resolves as UnsupportedType, as any GraphQL Compose field does whose target type is not enabled. A compound nested in another is a compound of its own: enable it on its own tab too, or the sub-field that nests it is UnsupportedType.

Sub-fields follow GraphQL Compose's defaults, as every other entity type's fields do: each is off until it is enabled. A sub-field added to the compound later stays out of the schema until it is enabled on the compound's tab.

A sub-field whose field type GraphQL Compose has no plugin for, such as timestamp, is left out of the schema.

The settings are saved with the form in graphql_compose.settings, under the compound's item type, cfi_ followed by the compound ID:

entity_config:
  cfi_sessions:
    cfi_sessions:
      enabled: true
field_config:
  cfi_sessions:
    cfi_sessions:
      title:
        enabled: true
        name_sdl: sessionTitle
      speaker:
        enabled: true

There is no GraphQL setting on the compound's own screens.

Schema

Each compound has one type, shared by every host field that uses it and every compound that nests it. Its settings apply wherever it is used: a sub-field cannot be enabled, renamed or embedded differently on different hosts.

A Sessions compound, used by a field on conference nodes, is:

type CompoundSession {
  id: ID!
  title: String
  topics: [String!]
  track: TermUnion
}

The host's field is a list of that type, as every compound field holds a list of items:

{
  node(id: "0eff320f-68b8-4cf8-b88c-5887655e4988") {
    ... on NodeConference {
      sessions { title topics }
    }
  }
}
Sub-field setting or value GraphQL shape
Sub-field capped at one Its field type's GraphQL type, or null when empty
Sub-field capped above one A list of non-null values, or null when empty
Required sub-field left empty null, as for an optional one
Nested compound The nested compound's own type, such as CompoundSpeaker
Sub-field the account may not view null; its siblings keep their values

id is the item's UUID, a stable ID for the row that clients can cache by.

Not queryable on its own

A compound item is reachable only through the field that holds it. Its type has no single query, no edge query and no route, whatever the settings say, including overrides in settings.php. Of a compound's own settings only Enable GraphQL is read, and its tab offers nothing else.

Sub-fields are always nullable, as any row can leave one empty. GraphQL Compose's option to override a field's required flag is not offered on a compound's tab.

Naming

A compound's type is Compound followed by its ID, singularized and in camel case: the sessions compound is CompoundSession. With GraphQL Compose's Enable singularize setting off, the ID is used as it is: CompoundSessions.

GraphQL Compose also registers a union and an interface for each compound, named after the whole ID: CompoundSessionsItemUnion and CompoundSessionsItemInterface.

Two compounds whose IDs singularize alike, such as session and sessions, generate the same type name, and only one of them is in the schema. Give compounds IDs that stay distinct once singularized.

References and unions

With GraphQL Compose's simple unions setting on, the default, a reference sub-field uses the generic union of its target type, such as NodeUnion.

With simple unions off, a reference to a single bundle uses that bundle's type directly, and a reference to several gets a union of its own, named after the compound type and the sub-field: CompoundSessionTrackUnion.

Caching

A response carries the host entity's cache tags. A compound item is saved through its host, so editing a value invalidates the host's tags, and the response with it.

The access result of each enabled sub-field is added to the response's cacheability, so a response that hides a sub-field from one account is never served to another.

The schema is rebuilt automatically when a compound, one of its sub-fields or a compound host field changes, including through a deployment. Nothing needs drush cr. A change to graphql_compose.settings alone, such as enabling or renaming a sub-field there, is picked up when caches are rebuilt, as for any GraphQL Compose setting; drush deploy does that.

Viewfield sub-fields

A viewfield sub-field has two modes, chosen with Embed view as GraphQL query on its panel on the compound's tab:

  • Unchecked (reference mode): the sub-field is a ViewReference, naming the view and display.
  • Checked (embedded mode): the sub-field is the view's ViewResultUnion, with its results, paging, filters and sorting.

Use embedded mode if your responses must be cacheable. In reference mode, GraphQL Compose Views makes every response that selects the sub-field uncacheable (max-age: 0), which also turns off the GraphQL result cache and page caching for that query. This is a GraphQL Compose Views bug that affects an ordinary viewfield the same way. It lasts until it is fixed upstream. Embedded mode keeps the view's own cacheability.

In embedded mode, a view argument that uses a host entity token, such as [node:nid], resolves against the host node, as it does for a viewfield directly on the host. See host tokens inside sub-field values.

Changing the compound

Renaming or removing a sub-field moves or drops its settings in graphql_compose.settings, for the compound and for every compound that includes it.

Deploy graphql_compose.settings with the structural change. The settings are rewritten on the site where the change is made. A configuration import does not rewrite them; it takes the copy in the export. A deployment that ships the compound's change without graphql_compose.settings leaves the old sub-field names in the settings, and the renamed sub-field drops out of the schema until it is enabled again under its new name. See deploy structural changes.

Deleting a compound removes its settings. Uninstalling the sub-module removes the settings of every compound.