Skip to content

Commit bae277d

Browse files
committed
GraphQL: Matrix fields and mutations updates
1 parent 491761c commit bae277d

File tree

1 file changed

+103
-71
lines changed

1 file changed

+103
-71
lines changed

docs/5.x/development/graphql.md

Lines changed: 103 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,117 +1660,117 @@ While mutations are mostly straightforward, there are a few important cases to c
16601660

16611661
### Matrix Fields in Mutations
16621662

1663-
GraphQL’s limited input types can be challenging with complex [Matrix fields](../reference/field-types/matrix.md).
1663+
Connecting GraphQL’s input types to complex [Matrix fields](../reference/field-types/matrix.md) can be challenging.
16641664

16651665
::: tip
1666-
We recommend reading [how to save matrix field data in entry forms](../reference/field-types/matrix.md#saving-matrix-fields-in-entry-forms) first if you’ve not saved Matrix field form data.
1666+
We recommend studying how to [save Matrix field data in entry forms](../reference/field-types/matrix.md#saving-matrix-fields) before diving in to the equivalent GraphQL.
16671667
:::
16681668

1669-
Matrix input types generally have the following structure:
1669+
Matrix input types have the following structure, and are always named `{fieldHandle}_MatrixInput`:
16701670

1671-
| Field | Description
1672-
| ----------- | -----------
1673-
| `sortOrder` | A list of all the block IDs, including any new blocks, in the order you’d like to persist after the mutation.
1674-
| `blocks` | A list of all the actual blocks. You can omit any blocks that aren’t modified, but they must be represented on the `sortOrder` field or they’ll be deleted.
1671+
| Field | Description
1672+
| --- | ---
1673+
| `sortOrder` | A list of all the nested entry IDs, including any new entries, in the order you’d like to persist after the mutation.
1674+
| `entries` | A list of all the actual entries. You can omit any entries that aren’t modified, but they must be represented on the `sortOrder` field or they’ll be deleted.
16751675

1676-
An actual block input type will contain fields for all the possible block types for this field, however, the first non-empty block will be considered in the order that the block types are defined on the field.
1677-
1678-
As an example, let’s pretend we have a Matrix field with a handle `ingredients`.
1679-
1680-
The field has three block types: `spirit`, `mixer`, and `garnish`. Each block type has one or two fields:
1676+
As an example, let’s pretend we have a Matrix field with a handle `ingredients`. The field has three entry types: `spirit`, `mixer`, and `garnish`. Each entry type has one or two fields:
16811677

16821678
```
1683-
ingredients
1684-
├── spirit
1679+
ingredients (Matrix field)
1680+
├── spirit (Entry type)
16851681
│ ├── spiritName (Plain Text)
16861682
│ └── ounces (Number)
1687-
├── mixer
1683+
├── mixer (Entry type)
16881684
│ ├── mixerName (Plain Text)
16891685
│ └── ounces (Number)
1690-
└── garnish
1686+
└── garnish (Entry type)
16911687
└── garnishName (Plain Text)
16921688
```
16931689

1694-
These are all the GraphQL input types Craft generates for this Matrix field:
1690+
These are all the GraphQL input types Craft generates for this Matrix field:
16951691

16961692
| Type Name | Type Description |
1697-
| - | -
1698-
| `ingredients_MatrixInput` | Input type for the Matrix field, containing `sortOrder` and `blocks`.
1699-
| `ingredients_MatrixBlockContainerInput` | Input type that represents the block, in this case containing `spirit`, `mixer`, and `garnish`.
1700-
| `ingredients_spirit_MatrixBlockInput` | Input type for the `spirit` block, containing `spiritName` and `ounces`.
1701-
| `ingredients_mixer_MatrixBlockInput` | Input type for the `mixer` block, containing `mixerName` and `ounces`.
1702-
| `ingredients_garnish_MatrixBlockInput` | Input type for the `garnish` block, containing `garnishName`.
1693+
| --- | --- |
1694+
| `ingredients_MatrixInput` | Input type for the Matrix field, containing `sortOrder` and `entries`.
1695+
| `ingredients_MatrixEntryContainerInput` | Input type that represents the block, in this case containing `spirit`, `mixer`, and `garnish`.
1696+
| `ingredients_spirit_MatrixEntryInput` | Input type for `spirit` entries, containing `spiritName` and `ounces` fields.
1697+
| `ingredients_mixer_MatrixEntryInput` | Input type for `mixer` entries, containing `mixerName` and `ounces` fields.
1698+
| `ingredients_garnish_MatrixEntryInput` | Input type for `garnish` entries, containing the `garnishName` field.
17031699

17041700
Those input types would look like this in [GraphQL Schema Definition Language (SDL)](https://www.prisma.io/blog/graphql-sdl-schema-definition-language-6755bcb9ce51):
17051701

17061702
```graphql
17071703
input ingredients_MatrixInput {
17081704
sortOrder: [QueryArgument]!
1709-
blocks: [ingredients_MatrixBlockContainerInput]
1705+
entries: [ingredients_MatrixEntryContainerInput]
17101706
}
17111707

1712-
input ingredients_MatrixBlockContainerInput {
1713-
spirit: ingredients_spirit_MatrixBlockInput
1714-
mixer: ingredients_mixer_MatrixBlockInput
1715-
garnish: ingredients_garnish_MatrixBlockInput
1708+
input ingredients_MatrixEntryContainerInput {
1709+
spirit: ingredients_spirit_MatrixEntryInput
1710+
mixer: ingredients_mixer_MatrixEntryInput
1711+
garnish: ingredients_garnish_MatrixEntryInput
17161712
}
17171713

1718-
input ingredients_spirit_MatrixBlockInput {
1719-
# ... common Matrix Block fields ...
1714+
input ingredients_spirit_MatrixEntryInput {
1715+
# ... common entry fields ...
17201716
spiritName: String
17211717
ounces: Number
17221718
}
17231719

1724-
input ingredients_mixer_MatrixBlockInput {
1725-
# ... common Matrix Block fields ...
1720+
input ingredients_mixer_MatrixEntryInput {
1721+
# ... common entry fields ...
17261722
mixerName: String
17271723
ounces: Number
17281724
}
17291725

1730-
input ingredients_garnish_MatrixBlockInput {
1731-
# ... common Matrix Block fields ...
1726+
input ingredients_garnish_MatrixEntryInput {
1727+
# ... common entry fields ...
17321728
garnishName: String
17331729
}
17341730
```
17351731

1736-
A mutation saving a new entry with multiple Matrix blocks might look like this:
1732+
A mutation saving a new entry with multiple nested entries might look like this:
17371733

17381734
::: code
17391735
```graphql GraphQL
17401736
mutation saveEntry(
17411737
$title: String,
17421738
$slug: String,
17431739
$authorId: ID,
1744-
$ingredients: [ingredients_MatrixBlockContainerInput],
1740+
$ingredients: [ingredients_MatrixEntryContainerInput],
17451741
$sortOrder: [QueryArgument]
17461742
) {
1747-
save_cocktails_cocktails_Entry(
1743+
save_cocktails_cocktail_Entry(
17481744
title: $title,
17491745
slug: $slug,
17501746
authorId: $authorId,
1751-
ingredients: { blocks: $ingredients, sortOrder: $sortOrder }
1747+
ingredients: { entries: $ingredients, sortOrder: $sortOrder }
17521748
) {
17531749
title
17541750
slug
17551751
authorId
17561752
dateCreated @formatDateTime (format: "Y-m-d")
17571753
ingredients {
17581754
__typename
1759-
...on MatrixBlockInterface {
1760-
id
1761-
}
1762-
... on ingredients_spirit_BlockType {
1763-
spiritName
1764-
ounces
1765-
}
1766-
... on ingredients_mixer_BlockType {
1767-
mixerName
1768-
ounces
1769-
}
1770-
... on ingredients_garnish_BlockType {
1771-
garnishName
1772-
}
1773-
}
1755+
1756+
...on EntryInterface {
1757+
id
1758+
}
1759+
1760+
... on spirit_entry {
1761+
spiritName
1762+
ounces
1763+
}
1764+
1765+
... on mixer_Entry {
1766+
mixerName
1767+
ounces
1768+
}
1769+
1770+
... on garnish_Entry {
1771+
garnishName
1772+
}
1773+
}
17741774
}
17751775
}
17761776

@@ -1814,32 +1814,32 @@ mutation saveEntry(
18141814
```json JSON Response
18151815
{
18161816
"data": {
1817-
"save_cocktails_cocktails_Entry": {
1817+
"save_cocktails_cocktail_Entry": {
18181818
"title": "Gin and Tonic",
18191819
"slug": "gin-tonic",
18201820
"authorId": 1,
18211821
"dateCreated": "2021-03-04",
18221822
"ingredients": [
18231823
{
1824-
"__typename": "ingredients_spirit_BlockType",
1824+
"__typename": "spirit_Entry",
18251825
"id": "9",
18261826
"spiritName": "Gin",
18271827
"ounces": 2
18281828
},
18291829
{
1830-
"__typename": "ingredients_mixer_BlockType",
1830+
"__typename": "mixer_Entry",
18311831
"id": "10",
18321832
"mixerName": "Tonic",
18331833
"ounces": 4
18341834
},
18351835
{
1836-
"__typename": "ingredients_mixer_BlockType",
1836+
"__typename": "mixer_Entry",
18371837
"id": "11",
18381838
"mixerName": "Fresh Lime Juice",
18391839
"ounces": 0.25
18401840
},
18411841
{
1842-
"__typename": "ingredients_garnish_BlockType",
1842+
"__typename": "garnish_Entry",
18431843
"id": "12",
18441844
"garnishName": "Lime Wedge or Twist"
18451845
}
@@ -1850,17 +1850,11 @@ mutation saveEntry(
18501850
```
18511851
:::
18521852

1853-
What field on those objects would contain data would determine the final block type.
1854-
1855-
::: warning
1856-
If more than one of the block types are defined, only the block type that is listed first will be considered.
1857-
:::
1858-
18591853
### Saving Files via Mutations
18601854

1861-
You can provide files for Assets as either base64-encoded data, or a URL that Craft will download.
1855+
You can provide files for assets as either base64-encoded data, or a URL that Craft will download.
18621856

1863-
Either way you’ll use the `FileInput` GraphQL input type, which has the following fields:
1857+
Either way, you’ll use the `FileInput` GraphQL input type, which has the following fields:
18641858

18651859
| Field | Description
18661860
| ---------- | -----------
@@ -1872,7 +1866,11 @@ Either way you’ll use the `FileInput` GraphQL input type, which has the follow
18721866

18731867
#### Saving an Entry
18741868

1875-
To save an [entry](../reference/element-types/entries.md), use the entry type-specific mutation which will have the name in the form of `save_<sectionHandle>_<entryTypeHandle>_Entry`:
1869+
[Entries](../reference/element-types/entries.md) are created and updated with mutations named after the combination of the target section and entry type, like `save_{sectionHandle}_{typeHandle}_Entry`:
1870+
1871+
::: tip
1872+
See the section on [Matrix mutations](#matrix-fields-in-mutations) for more information about saving nested entries.
1873+
:::
18761874

18771875
<!-- BEGIN ENTRY MUTATION ARGS -->
18781876

@@ -1894,7 +1892,7 @@ To save an [entry](../reference/element-types/entries.md), use the entry type-sp
18941892
The `id`, `uid` and `authorId` arguments do not exist for single entries. This is because single entries have no authors and are identified already by the exact mutation. In a similar fashion, there are additional arguments available for structured entries. For more information, refer to [mutating structure data](#mutating-structure-data).
18951893

18961894
::: tip
1897-
After saving an entry, Craft runs queue jobs for updating revisions and search indexes. If you’re using Craft headlessly or infrequently accessing the control panel, consider disabling <config5:runQueueAutomatically> and [establishing an always-running daemon](https://nystudio107.com/blog/robust-queue-job-handling-in-craft-cms) to keep revisions and search indexes up to date.
1895+
After saving an entry, Craft runs queue jobs for updating revisions and search indexes. If you’re using Craft headlessly or infrequently accessing the control panel, consider disabling <config5:runQueueAutomatically> and [establishing an always-running daemon](../system/queue.md#daemon) to keep revisions and search indexes up to date.
18981896
:::
18991897

19001898
#### Editing Existing Entries
@@ -1903,7 +1901,7 @@ You can modify existing entries by passing the populated `id` argument to your m
19031901

19041902
#### Saving a Draft
19051903

1906-
To save a draft for an entry, use the entry type-specific mutation which will have the name in the form of `save_<sectionHandle>_<entryTypeHandle>_Draft`:
1904+
Entry _drafts_ are created and updated with mutations named after the combination of the target section and entry type, like `save_{sectionHandle}_{typeHandle}_Draft`:
19071905

19081906
<!-- BEGIN DRAFT MUTATION ARGS -->
19091907

@@ -1925,9 +1923,43 @@ To save a draft for an entry, use the entry type-specific mutation which will ha
19251923

19261924
#### Creating or Publishing a Draft
19271925

1928-
You can use the `createDraft` mutation to save a new draft. It requires the `id` of the draft’s parent entry and returns the ID of the newly-saved draft.
1926+
You can use the generic `createDraft` mutation to create a new draft. It requires the `id` of the draft’s canonical entry and returns the ID of the newly-saved draft:
1927+
1928+
::: code
1929+
```gql Query
1930+
mutation MyNewDraft {
1931+
createDraft(id: 1234)
1932+
}
1933+
```
1934+
```json Response
1935+
{
1936+
"data": {
1937+
"createDraft": "5678"
1938+
}
1939+
}
1940+
```
1941+
:::
1942+
1943+
Additional (optional) arguments include a `name` for the draft, `notes`, a `creatorId` (if the draft should be created on behalf of a specific user), and a `provisional` flag. Provisional drafts (referred to in the control panel as auto-saved changes)
1944+
1945+
_Applying_ a draft is handled in the same way, but with the `publishDraft` mutation. It requires the `id` of the draft to be published and returns the ID of the updated canonical entry:
1946+
1947+
::: code
1948+
```gql Query
1949+
mutation PublishMyDraft {
1950+
publishDraft(id: 5678)
1951+
}
1952+
```
1953+
```json Response
1954+
{
1955+
"data": {
1956+
"publishDraft": "1234"
1957+
}
1958+
}
1959+
```
1960+
:::
19291961

1930-
You can publishing a draft using the `publishDraft` mutation, which requires the `id` of the draft to be published and returns the ID of the updated parent entry.
1962+
Neither mutation accepts properties or custom field values—use the appropriate [entry mutation](#saving-an-entry) to update a draft after it has been created. To work with drafts, the [schema](#define-your-schemas) must allow creating and saving entries in the canonical entry’s section; unlike user permissions, schemas do not have discrete permissions for draft creation and canonical entry mutations.
19311963

19321964
#### Deleting an Entry
19331965

0 commit comments

Comments
 (0)