Bulk Attribute Import
This feature was introduced in Saleor 3.15.
This feature is in the Feature Preview stage, which means that it is available for experimentation and feedback. However, it is still undergoing development and is subject to modifications.
Introduction
This guide describes a mutation allowing users to create and update multiple attributes in Saleor. The purpose of these mutations could be to import attributes from other systems.
Mutations use the same data inputs as attributeCreate
and attributeUpdate
to keep it consistent between single and bulk mutations, but deprecated
fields from AttributeCreateInput
, AttributeUpdateInput
, AttributeValueCreateInput
and AttributeValueUpdateInput
are not supported in bulk mutations and using them will result in an error.
Those fields are:
filterableInStorefront
availableInGrid
storefrontSearchPosition
richText
plainText
Permissions
To edit and create attributes, a user needs to have the following permissions, depending on the attribute type:
MANAGE_PRODUCT_TYPES_AND_ATTRIBUTES
if the attribute type isPRODUCT_TYPE
MANAGE_PAGE_TYPES_AND_ATTRIBUTES
if the attribute type isPAGE_TYPE
Error Policy
attributeBulkCreate
and attributeBulkUpdate
mutation as well as other new bulk mutations accepts errorPolicy
argument, which determines how to handle errors.
attributeBulkCreate
Mutation example:
mutation AttributeBulkCreate(
$attributes: [AttributeCreateInput!]!
$errorPolicy: ErrorPolicyEnum
) {
attributeBulkCreate(attributes: $attributes, errorPolicy: $errorPolicy) {
results {
errors {
path
message
code
}
attribute {
id
name
externalReference
slug
choices(first: 10) {
edges {
node {
id
name
externalReference
slug
value
file {
url
contentType
}
}
}
}
}
}
count
}
}
Input example:
{
"attributes": [
{
"name": "Attribute 1",
"externalReference": "attribute-1-external-reference",
"type": "PRODUCT_TYPE",
"inputType": "DROPDOWN",
"values": [
{
"name": "Value 1",
"externalReference": "value-1-external-reference"
},
{ "name": "Value 2", "externalReference": "value-2-external-reference" }
]
},
{
"name": "Attribute 2",
"externalReference": "attribute-2-external-reference",
"type": "PRODUCT_TYPE",
"inputType": "DROPDOWN",
"values": [
{ "name": "Value 3", "externalReference": "value-3-external-reference" }
]
}
]
}
Expected response:
{
"data": {
"attributeBulkCreate": {
"results": [
{
"errors": [],
"attribute": {
"id": "QXR0cmlidXRlOjQ4",
"name": "Attribute 1",
"externalReference": "attribute-1-external-reference",
"slug": "attribute-1",
"choices": {
"edges": [
{
"node": {
"id": "QXR0cmlidXRlVmFsdWU6MTQ4",
"name": "Value 1",
"externalReference": "value-1-external-reference",
"slug": "value-1",
"value": "",
"file": null
}
},
{
"node": {
"id": "QXR0cmlidXRlVmFsdWU6MTQ5",
"name": "Value 2",
"externalReference": "value-2-external-reference",
"slug": "value-2",
"value": "",
"file": null
}
}
]
}
}
},
{
"errors": [],
"attribute": {
"id": "QXR0cmlidXRlOjQ5",
"name": "Attribute 2",
"externalReference": "attribute-2-external-reference",
"slug": "attribute-2",
"choices": {
"edges": [
{
"node": {
"id": "QXR0cmlidXRlVmFsdWU6MTUw",
"name": "Value 3",
"externalReference": "value-3-external-reference",
"slug": "value-3",
"value": "",
"file": null
}
}
]
}
}
}
],
"count": 2
}
},
"extensions": {
"cost": {
"requestedQueryCost": 10,
"maximumAvailable": 50000
}
}
}
Webhooks
The mutation will emit ATTRIBUTE_CREATED
event for every successfully created attribute.
attributeBulkUpdate
To update attributes one of the following fields is required: id
or externalReference
.
Mutation example:
mutation AttributeBulkUpdate(
$attributes: [AttributeBulkUpdateInput!]!
$errorPolicy: ErrorPolicyEnum
) {
attributeBulkUpdate(attributes: $attributes, errorPolicy: $errorPolicy) {
results {
errors {
path
message
code
}
attribute {
id
name
externalReference
slug
choices(first: 10) {
edges {
node {
id
name
externalReference
slug
value
file {
url
contentType
}
}
}
}
}
}
count
}
}
Input example:
{
"attributes": [
{
"id": "QXR0cmlidXRlOjQ4",
"fields": {
"name": "Attribute 1 New Name",
"removeValues": ["QXR0cmlidXRlVmFsdWU6MTQ5"]
}
},
{
"externalReference": "attribute-2-external-reference",
"fields": {
"addValues": [
{
"name": "Value 4",
"externalReference": "value-4-external-reference"
}
]
}
}
]
}
Expected response:
{
"data": {
"attributeBulkUpdate": {
"results": [
{
"errors": [],
"attribute": {
"id": "QXR0cmlidXRlOjQ4",
"name": "Attribute 1 New Name",
"externalReference": "attribute-1-external-reference",
"slug": "attribute-1",
"choices": {
"edges": [
{
"node": {
"id": "QXR0cmlidXRlVmFsdWU6MTQ4",
"name": "Value 1",
"externalReference": "value-1-external-reference",
"slug": "value-1",
"value": "",
"file": null
}
}
]
}
}
},
{
"errors": [],
"attribute": {
"id": "QXR0cmlidXRlOjQ5",
"name": "Attribute 2",
"externalReference": "attribute-2-external-reference",
"slug": "attribute-2",
"choices": {
"edges": [
{
"node": {
"id": "QXR0cmlidXRlVmFsdWU6MTUw",
"name": "Value 3",
"externalReference": "value-3-external-reference",
"slug": "value-3",
"value": "",
"file": null
}
},
{
"node": {
"id": "QXR0cmlidXRlVmFsdWU6MTUx",
"name": "Value 4",
"externalReference": "value-4-external-reference",
"slug": "value-4",
"value": "",
"file": null
}
}
]
}
}
}
],
"count": 2
}
},
"extensions": {
"cost": {
"requestedQueryCost": 10,
"maximumAvailable": 50000
}
}
}
Webhooks
The mutation will emit ATTRIBUTE_UPDATED
event for every successfully updated attribute or when value is added or removed.
Optionally ATTRIBUTE_VALUE_CREATED
and ATTRIBUTE_VALUE_DELETED
will be emitted when value is added or removed.