Skip to content

Instantly share code, notes, and snippets.

@paliarush
Last active February 15, 2023 14:36
Show Gist options
  • Save paliarush/dda94121eb19bf09b20ff366aa7e597d to your computer and use it in GitHub Desktop.
Save paliarush/dda94121eb19bf09b20ff366aa7e597d to your computer and use it in GitHub Desktop.

[POLL] Custom attributes in Magento GraphQL Schema

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.

Option 1: Custom attributes container

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

Option 2: Custom attributes in flat structure under the entity object

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment