Skip to content
KeystoneJS LogoKeystoneJS
👋🏻 Keystone 5 has officially moved to maintenance only. For the latest release of Keystone please visit the Keystone website.

Relationship

A link between the current list and others, often paired with a field on the other list. The relationships cardinality is determined by the many and isRequired configuring on either side.

See the Configuring Relationships guide for more information.

Usage

JS
const { Relationship, Text } = require('@keystonejs/fields');

keystone.createList('User', {
  fields: {
    name: { type: Text },
    posts: { type: Relationship, ref: 'Post', many: true },
    company: { type: Relationship, ref: 'Org' },
  },
});

keystone.createList('Post', {
  fields: {
    title: { type: Text },
  },
});

keystone.createList('Org', {
  fields: {
    name: { type: Text },
  },
});

Config

OptionTypeDefaultDescription
isUniqueBooleanfalseAdds a unique index that allows only unique values to be stored

Nested mutations

Using the example list config above, the to-many (User.posts) and to-single (User.company) relationships can be mutated as part of a mutation on items in the parent list (eg; during a createUser, or updateUser mutation, etc).

The available nested mutations:

Nested Mutationto-single relationshipto-many relationship
createCreate a new item, and set it as the relation.
Note: the previously set item (if any) is not deleted.
Create 1 or more new items, and append them to the list of related items.
connectFilter for an item, and set it as the relation.
Note: the previously set item (if any) is not deleted.
Filter for one or more items, and append them to the list of related items.
disconnectUnset the relation (if any) if it matches the given filter.
Note: the previously set item (if any) is not deleted.
Filter for one or more items, and unset them from the list of related items (if any).
Note: the previously set items (if any) are not deleted.
disconnectAllUnset the relation (if any).
Note: the previously set item (if any) is not deleted.
Unset the list of related items (if any).
Note: the previously set items (if any) are not deleted.

Order of execution

Nested mutations are executed in the following order:

  1. disconnectAll
  2. disconnect
  3. create
  4. connect

Examples

Use the create nested mutation to create and append an item to a to-many relationship:

GraphQL
# Replace all posts of a given User
mutation replaceAllPosts {
  updateUser(
    id: "abc123",
    data: {
      posts: {
        create: { title: "Hello World" },
      }
    }
  ) {
    # Now has a new post appended with the title "Hello World"
    posts {
      id
    }
  }
}

Append an existing item

Use the connect nested mutation to append an existing item to a to-many relationship:

GraphQL
# Replace the company of a given User
mutation replaceAllPosts {
  updateUser(
    id: "abc123",
    data: {
      posts: {
        connect: { id: "def345" },
      }
    }
  ) {
    # Now has an existing post appended with the id "def345"
    posts {
      id
    }
  }
}

Overriding a to-single relationship

Using either create or connect nested mutations is sufficient to override the value of a to-single relationship (it's not necessary to use disconnectAll as is the case for to-many relationships):

GraphQL
# Replace the company of a given User
mutation replaceAllPosts {
  updateUser(
    id: "abc123",
    data: {
      company: {
        connect: { id: "def345" },
      }
    }
  ) {
    # Will now be the company with id "def345"
    company {
      id
    }
  }
}

Overriding a to-many relationship

To completely replace the related items in a to-many list, you can perform a disconnectAll nested mutation followed by a create or connect nested mutation (thanks to the order of execution):

GraphQL
# Replace all posts related to a given User
mutation replaceAllPosts {
  updateUser(
    id: "abc123",
    data: {
      posts: {
        disconnectAll: true,
        connect: [{ id: "def345" }, { id: "xyz789" }],
      }
    }
  ) {
    # Will now only contain posts with ids "def345" & "xyz789"
    posts {
      id
    }
  }
}

On this page

Edit on GitHub