Magento GraphQL endpoints must support EAV entities such as Products. GraphQL specification requires all complex types eventually to be represented as structures of scalar types. Mixed/any types are not supported.
We have couple options to choose from and would be glad to hear your opinion on that.
Schema
NOTE: Parts of the schema which are identical in both options are omitted.
interface CustomAttribute {
attribute_code: String!
}
type StringAttribute implements Attribute {
attribute_code: String!
attribute_value: String!
}
type IntAttribute implements Attribute {
attribute_code: String!
attribute_value: Int!
}
type BooleanAttribute implements Attribute {
attribute_code: String!
attribute_value: Boolean!
}
type FloatAttribute implements Attribute {
attribute_code: String!
attribute_value: Float!
}
type MediaAttribute implements Attribute {
attribute_code: String!
attribute_value: MediaAttributeValue!
}
type MediaAttributeValue {
size: String!
path: String!
}
type Product {
id: Int
sku: String
custom_attributes(attribute_code: String!): [CustomAttribute]!
}
Query
product(filter: {
or: {
sku: {like:"%_2%"}
or: {
custom_attributes: [
{
code: “some_custom_attribute”,
value: “0”,
condition: “eq”
}
]
}
}
}
pageSize: 1
currentPage:1
) {
items{
id
sku
custom_attributes(attribute_code: "some_custom_attribute,another_custom_attribute") {
attribute_code
... on StringAttribute {
atribute_value
}
... on FloatAttribute {
atribute_value
}
... on BooleanAttribute {
atribute_value
}
... on IntAttribute {
atribute_value
}
... on MediaAttribute
{
atribute_value {
size
path
}
}
}
}
}
Pros
- Bag of attributes is a good OOP abstraction on the entities dynamically defined in the run-time
- Simple way to represent attribute sets
Cons
- Nested structure for custom attributes filters (filter name, condition, value). No auto-complete for attribute names in filter and sorting.
- More complicated client code, requires GraphQL fragment declaration for every possible custom attribute value type.
- Requires special syntax for requesting specific attributes
- It is impossible to see all attributes available on the storefront in GraphQL schema, No auto-completion available in IDEs like Graphiql
In case when requested custom attributes are not defined for the resulting product, the values of such attributes will be set to null.
Schema
type SimpleProduct implements Product {
some_custom_attribute: Boolean
another_custom_attribute: MediaAttributeValue
id: Int
sku: String
…
}
type MediaAttributeValue {
size: String!
path: String!
}
Query
product(filter: {
or: {
sku: {like:"%_2%"}
or: {
some_custom_attribute: {eq: “0”}
}
}
}
pageSize: 1
currentPage:1
) {
items{
some_custom_attribute
another_custom_attribute
{
size,
path
}
id
sku
}
}
Pros
- Good semantics for filters
- You can see all available attributes in GraphQL schema
- Auto-complete works in query, filter and sorting
Cons
- Request must be generated (using Magento client library)
- Custom options are still represented as an array. Do we need to request specific custom options or use them in filters?
- It is possible to request attributes un-related to the requested product's attribute set. The values will be set to NULL in the response
- Schema cache must be invalidated on every change to custom attributes (CRUD on EAV attributes). Minor issue since cache invalidation must be implemented anyway