3.02

Types of Attributes

Deep dive into EAV and Extension attributes - understanding their differences, use cases, and implementation approaches for extending Magento entities.

Why This Matters: Attributes are one of Magento's most powerful features. Understanding the different types of attributes and when to use each is essential for extending entities properly and implementing custom functionality.

Attribute Types Overview

mindmap root((Attribute Types)) Functional Attributes Change behavior Not just data Powerful features EAV Attributes AbstractEntity Automatic save/load Scalar values Scope support Grid/form ready Extension Attributes AbstractExtensibleObject Manual save/load Complex types Custom storage WebAPI friendly

The Power of Attributes in Magento

Attributes are an important feature of Magento. Many out-of-the-box features rely on attributes heavily, and it is possible to create new attributes to implement custom functionality.

What Makes Attributes So Powerful: Attributes in Magento go far beyond mere elements of data architecture. Attributes in Magento are functional. This means you can use attributes to change a behavior of some object, rather than simply adding another property to it.

Attributes are Functional, Not Just Data

Traditional Approach

Mere Data Elements:

  • Just store information
  • No behavior changes
  • Static properties
  • Limited functionality

Magento Attributes

Functional Elements:

  • ✅ Change object behavior
  • ✅ Trigger functionality
  • ✅ Dynamic properties
  • ✅ Rich feature set

Two Primary Types of Attributes

There are two primary types of attributes in Magento:

1. EAV Attributes

Traditional Entity-Attribute-Value attributes with automatic persistence and scope support.

2. Extension Attributes

Modern, flexible attributes for complex data types with manual implementation.

Comprehensive Comparison Table

Feature EAV Attribute Extension Attribute
Applied to A Resource model that extends Magento\Eav\Model\Entity\AbstractEntity Data model that extends Magento\Framework\Api\AbstractExtensibleObject, or model that extends Magento\Framework\Model\AbstractExtensibleModel
Values stored In special tables with types *_entity_varchar, *_entity_int, and so on. For example: catalog_product_entity_int It is up to developer to decide where to store the data (custom tables, files, external APIs)
Save and load Automatically implemented in the AbstractEntity resource model. A lot of functionality is implemented in Magento_Catalog abstract resource model Manually. Developer has to load and save the data using plugins or observers
Use for custom entity Very difficult Easy
Create new attribute Requires a DataPatch Requires an entry in etc/extension_attributes.xml file
Availability in WebAPI Available as Custom Attributes Available as Extension Attributes
Scope support Out of the box for product and category attributes Does not support scope out of the box, up to developer to implement
Grid and form support Yes, out-of-the-box No, requires custom work
Typical use case Extend an entity with a new scalar property, implement some functionality when the property changes, support different values for different scopes Extending an entity with a new property, not necessarily scalar, could be an object or array. Data is stored in custom tables, files, could even be fetched by API

EAV Attributes In-Depth

Entity-Attribute-Value Architecture

EAV attributes follow the Entity-Attribute-Value pattern, where attribute values are stored separately from the main entity table.

Applied To

EAV attributes can only be applied to resource models that extend Magento\Eav\Model\Entity\AbstractEntity.

Core Entities Using EAV:

  • Products - Magento\Catalog\Model\ResourceModel\Product
  • Categories - Magento\Catalog\Model\ResourceModel\Category
  • Customers - Magento\Customer\Model\ResourceModel\Customer
  • Customer Addresses - Magento\Customer\Model\ResourceModel\Address

Storage Structure

EAV attribute values are stored in special tables based on data type:

Data Type Table Pattern Example (Product)
Text (short) *_entity_varchar catalog_product_entity_varchar
Integer *_entity_int catalog_product_entity_int
Decimal *_entity_decimal catalog_product_entity_decimal
Text (long) *_entity_text catalog_product_entity_text
Date/Time *_entity_datetime catalog_product_entity_datetime
Structure Example: Each table contains entity_id, attribute_id, store_id, and value columns for scope-aware storage.

Automatic Save and Load

One of the biggest advantages of EAV attributes is automatic persistence.

<?php
// EAV attribute - automatically saved
$product->setWarrantyPeriod(12);
$product->save(); // warranty_period is automatically saved to catalog_product_entity_int

// Later, automatically loaded
$warrantyPeriod = $product->getWarrantyPeriod(); // Automatically loaded from database
Key Benefit: All save/load logic is implemented in AbstractEntity resource model. Lots of functionality is also in Magento_Catalog abstract resource model.

Creating EAV Attributes

EAV attributes require a DataPatch to create them.

Setup/Patch/Data/AddCustomAttribute.php
<?php
namespace Vendor\Module\Setup\Patch\Data;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Catalog\Model\Product;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;

class AddCustomAttribute implements DataPatchInterface
{
    private $eavSetupFactory;
    
    public function __construct(EavSetupFactory $eavSetupFactory)
    {
        $this->eavSetupFactory = $eavSetupFactory;
    }
    
    public function apply()
    {
        $eavSetup = $this->eavSetupFactory->create();
        
        $eavSetup->addAttribute(
            Product::ENTITY,
            'warranty_period',
            [
                'type' => 'int',
                'label' => 'Warranty Period (months)',
                'input' => 'text',
                'required' => false,
                'sort_order' => 100,
                'global' => ScopedAttributeInterface::SCOPE_STORE,
                'visible' => true,
                'searchable' => false,
                'filterable' => false,
                'comparable' => false,
                'visible_on_front' => false,
                'used_in_product_listing' => true,
                'unique' => false,
                'group' => 'General'
            ]
        );
        
        return $this;
    }
    
    public static function getDependencies()
    {
        return [];
    }
    
    public function getAliases()
    {
        return [];
    }
}

Scope Support

EAV attributes for products and categories support scope out of the box.

Available Scopes:

  • SCOPE_GLOBAL - Same value across all websites and store views
  • SCOPE_WEBSITE - Different values per website
  • SCOPE_STORE - Different values per store view
<?php
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;

// In DataPatch
'global' => ScopedAttributeInterface::SCOPE_STORE,  // Store view scope
'global' => ScopedAttributeInterface::SCOPE_WEBSITE, // Website scope
'global' => ScopedAttributeInterface::SCOPE_GLOBAL,  // Global scope

Grid and Form Support

EAV attributes have built-in support for admin grids and forms.

// In DataPatch attribute configuration
'is_used_in_grid' => true,           // Can be used in admin grid
'is_visible_in_grid' => true,        // Visible in admin grid by default
'is_filterable_in_grid' => true,     // Can filter by this attribute in grid
'is_searchable_in_grid' => true,     // Can search by this attribute
Automatic Display: Attributes appear in product edit form under the specified group without additional coding.

Use for Custom Entities

⚠️ Very Difficult: Using EAV for custom entities requires:
  • Creating multiple database tables (*_entity, *_entity_int, *_entity_varchar, etc.)
  • Implementing resource model extending AbstractEntity
  • Setting up EAV entity type
  • Managing attribute sets and groups
  • Complex configuration and setup

Extension Attributes In-Depth

Flexible Extension Architecture

Extension attributes provide a flexible way to extend entities with complex data types and custom storage mechanisms.

Applied To

Extension attributes can be applied to:

  • Data models that extend Magento\Framework\Api\AbstractExtensibleObject
  • Models that extend Magento\Framework\Model\AbstractExtensibleModel

Common Extensible Entities:

  • ✅ Products, Categories, Customers (API Data interfaces)
  • ✅ Orders, Quotes, Invoices, Shipments
  • ✅ Cart items, Quote items
  • ✅ Custom entities implementing the interfaces

Storage - Developer's Choice

Unlike EAV attributes, with extension attributes the developer decides where to store the data.

Storage Options:

  • ✅ Custom database tables
  • ✅ Existing tables (additional columns)
  • ✅ File system
  • ✅ External APIs
  • ✅ Cache/Redis
  • ✅ Computed on-the-fly (no storage)

Manual Save and Load

Extension attributes require manual implementation of save and load logic using plugins.

Example: Load Extension Attribute

<?php
namespace Vendor\Module\Plugin;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\Data\ProductExtensionFactory;
use Vendor\Module\Api\RelatedBlogPostRepositoryInterface;

class ProductRepositoryPlugin
{
    private $extensionFactory;
    private $blogPostRepository;
    
    public function __construct(
        ProductExtensionFactory $extensionFactory,
        RelatedBlogPostRepositoryInterface $blogPostRepository
    ) {
        $this->extensionFactory = $extensionFactory;
        $this->blogPostRepository = $blogPostRepository;
    }
    
    public function afterGet(
        \Magento\Catalog\Api\ProductRepositoryInterface $subject,
        ProductInterface $product
    ) {
        $extensionAttributes = $product->getExtensionAttributes();
        if ($extensionAttributes === null) {
            $extensionAttributes = $this->extensionFactory->create();
        }
        
        // Load extension attribute data from custom source
        $blogPosts = $this->blogPostRepository->getByProductId($product->getId());
        $extensionAttributes->setRelatedBlogPosts($blogPosts);
        
        $product->setExtensionAttributes($extensionAttributes);
        return $product;
    }
}

Creating Extension Attributes

Extension attributes require an entry in etc/extension_attributes.xml.

etc/extension_attributes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
        <!-- Simple scalar attribute -->
        <attribute code="custom_flag" type="string" />
        
        <!-- Array of objects -->
        <attribute code="related_blog_posts" type="Vendor\Module\Api\Data\BlogPostInterface[]" />
        
        <!-- Single object -->
        <attribute code="shipping_estimate" type="Vendor\Module\Api\Data\ShippingEstimateInterface" />
    </extension_attributes>
</config>
Flexibility: Can define scalar types, objects, or arrays of objects.

WebAPI Availability

Extension attributes are automatically available in WebAPI responses as Extension Attributes.

API Response Example:

{
  "id": 123,
  "sku": "product-sku",
  "name": "Product Name",
  "custom_attributes": [
    {
      "attribute_code": "warranty_period",
      "value": "12"
    }
  ],
  "extension_attributes": {
    "custom_flag": "some_value",
    "related_blog_posts": [
      {
        "id": 1,
        "title": "Blog Post Title"
      }
    ]
  }
}
Note: EAV attributes appear as custom_attributes, extension attributes appear as extension_attributes.

Use for Custom Entities

✅ Easy: Using extension attributes for custom entities is straightforward:
  • Create your data interface extending AbstractExtensibleObject
  • Define extension attributes in XML
  • Implement load/save logic in plugins
  • No complex EAV setup required

Decision Matrix: When to Use Each Type

Use EAV Attributes When:

  • ✅ Extending products, categories, or customers
  • ✅ Adding simple scalar values (text, number, date)
  • ✅ Need automatic save/load
  • ✅ Need scope support (website/store view)
  • ✅ Want automatic grid/form display
  • ✅ Need filtering/searching in admin
  • ✅ Implementing behavior changes based on value
Example: Adding "warranty_period" to products with different values per store view.

Use Extension Attributes When:

  • ✅ Need complex data types (objects, arrays)
  • ✅ Extending non-EAV entities (orders, quotes)
  • ✅ Data from external sources (APIs, files)
  • ✅ Need custom storage control
  • ✅ Creating custom entities
  • Computed/derived data (no persistence)
  • WebAPI-focused integration
Example: Adding "related_blog_posts" array to products, fetched from external CMS.

Real-World Scenarios

Scenario 1: Product Warranty (Use EAV)

Requirement: Add warranty period to products, different per store view, filterable in admin.

Solution: EAV attribute

  • ✅ Simple integer value
  • ✅ Need scope support
  • ✅ Want admin grid filtering
  • ✅ Automatic persistence

Scenario 2: Shipping Estimates (Use Extension)

Requirement: Add real-time shipping estimates from external API to cart items.

Solution: Extension attribute

  • ✅ Complex object (carrier, cost, time)
  • ✅ Computed from external API
  • ✅ No database persistence needed
  • ✅ WebAPI integration

Scenario 3: Custom Order Notes (Use Extension)

Requirement: Store structured internal notes about orders.

Solution: Extension attribute

  • ✅ Orders don't use EAV
  • ✅ Complex structure (author, timestamp, note)
  • ✅ Custom table for storage
  • ✅ Manual save/load control

Exam Tips

Key Points to Remember

  • Attributes are functional - change behavior, not just data
  • Two primary types: EAV and Extension
  • EAV applied to: AbstractEntity resource models (products, categories, customers)
  • Extension applied to: AbstractExtensibleObject or AbstractExtensibleModel
  • EAV storage: *_entity_varchar, *_entity_int, *_entity_decimal, *_entity_text, *_entity_datetime
  • Extension storage: Developer decides (custom tables, files, APIs, computed)
  • EAV save/load: Automatic in AbstractEntity
  • Extension save/load: Manual implementation via plugins
  • EAV creation: DataPatch with EavSetup
  • Extension creation: etc/extension_attributes.xml
  • WebAPI: EAV = custom_attributes, Extension = extension_attributes
  • Scope: EAV has built-in support, Extension requires manual implementation
  • Grid/Form: EAV has built-in support, Extension requires custom work
  • Custom entities: EAV very difficult, Extension easy
  • Data types: EAV only scalar, Extension supports objects/arrays

Further Reading