Skip to content

Commit be534c3

Browse files
authored
Merge pull request #282 from magento-architects/graphql-custom-attributes-container
GraphQL custom attributes container proposal
2 parents 1331ff1 + c9bf47c commit be534c3

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
## Problem statement
2+
3+
Some Magento installations may have tens of thousands of custom (EAV) product attributes. This is possible when the merchant is selling thousands of different product types with unique attribute sets.
4+
5+
Custom attributes in GraphQL schema are presented in flat structure, which may be a problem for the client application when performing search in catalog. GraphQL requires all needed fields to be explicitly listed in the query, "get all fields" queries are not supported. At the same time Magento is expected to return all EAV attributes applicable to each product.
6+
7+
One workaround for "getting all fields" is based on schema introspection, it allows to get names of all fields in `ProductInterface` including EAV attributes. Even with the described workaround client application will have to explicitly list tens of thousands of attributes in the search query because it does not know in advance products belonging to which attribute sets will be returned in search result.
8+
9+
# Proposed solution
10+
11+
To account for dynamic nature of EAV attributes and the need of "getting all fields" in product search queries, `custom_attributes: [CustomAttribute]!` container will be introduced.
12+
13+
```graphql
14+
type CustomAttribute {
15+
code: String!
16+
value: String!
17+
}
18+
```
19+
20+
Here `value` is JSON-encoded value of the custom attribute.
21+
22+
Flat representation of custom attributes in `ProductInterface` (and other EAV entities like `Category`, `Customer` etc) will remain intact. The client will a have choice to query custom fields explicitly and have validation of the response against GraphQL schema or to "get all" custom attributes using `custom_attributes` container.
23+
24+
It is necessary to keep in mind that with `custom_attributes` it is not possible to query product EAV attributes selectively, which may lead to performance degradation.
25+
26+
### Sample queries
27+
28+
Current implementation allows the following query
29+
```graphql
30+
{
31+
products(search: "test") {
32+
items {
33+
name
34+
sku
35+
color
36+
manufacturer
37+
size
38+
}
39+
}
40+
}
41+
```
42+
43+
Let's assume the response will be
44+
45+
```graphql
46+
{
47+
"data": {
48+
"products": {
49+
"items": [
50+
{
51+
"name": "Test Simple Product",
52+
"sku": "testSimpleProduct",
53+
"color": "Red",
54+
"manufacturer": "Company A"
55+
"size": null
56+
},
57+
{
58+
"name": "Test Configurable Product",
59+
"sku": "testConfigProduct",
60+
"color": null,
61+
"manufacturer": "Company B"
62+
"size": "XXL"
63+
}
64+
]
65+
}
66+
}
67+
}
68+
```
69+
70+
With the proposed changes the above mentioned queries will still be supported. In addition, the following query will become possible
71+
72+
```graphql
73+
{
74+
products(search: "test") {
75+
items {
76+
name
77+
sku
78+
custom_attributes {
79+
code
80+
value
81+
}
82+
}
83+
}
84+
}
85+
```
86+
Note that color and size are not applicable to some products in the search result. In the previous example they were returned as `null`. In the following example they are not returned at all
87+
88+
```graphql
89+
{
90+
"data": {
91+
"products": {
92+
"items": [
93+
{
94+
"name": "Test Simple Product",
95+
"sku": "testSimpleProduct",
96+
"custom_attributes": [
97+
{
98+
"code": "color"
99+
"value": "Red"
100+
},
101+
{
102+
"code": "manufacturer"
103+
"value": "Company A"
104+
}
105+
]
106+
},
107+
{
108+
"name": "Test Configurable Product",
109+
"sku": "testConfigProduct",
110+
"custom_attributes": [
111+
{
112+
"code": "manufacturer"
113+
"value": "Company B"
114+
},
115+
{
116+
"code": "size"
117+
"value": "XXL"
118+
}
119+
]
120+
},
121+
]
122+
}
123+
}
124+
}
125+
```
126+
127+
# Alternatives considered
128+
129+
1. [Persisted queries](https://github.com/magento/graphql-ce/issues/781) can be leveraged to mitigate described issue with the increased size of the request.
130+
1. To improve flexibility and allow support of complex structures, `type` can be added to the definition of `CustomAttribute` in the future, if there are valid use cases.
131+
1. `value` of the `CustomAttribute` can have different format other than JSON, potentially more strict one.
132+
1. It is possible to eliminate rendering of custom attributes in flat structure from `ProductInterface` (and other EAV entities) and completely rely on containers. We believe this will cause developer experience degradation and does not bring any significant benefits for production deployments.

0 commit comments

Comments
 (0)