EAV and extension attributes
Magento provides two types of attributes that integrators can use to extend the functionality provided out-of-the-box:
-
Custom and EAV (Entity-Attribute-Value) attributes. Custom attributes are those added on behalf of a merchant. For example, a merchant might need to add attributes to describe products, such as shape or volume. A merchant can add these attributes on the admin panel, and these attributes can be displayed. See the merchant documentation for information about information about managing custom attributes.
Custom attributes are a subset of EAV attributes. Objects that use EAV attributes typically store values in several MySQL tables. The
Customer
andCatalog
modules have the primary models that use EAV attributes. Other modules, such asConfigurableProduct
,GiftMessage
, andTax
, use the EAV functionality forCatalog
. -
Extension attributes. Extension attributes are new in Magento 2. They are used to extend functionality and often use more complex data types than custom attributes. These attributes do not appear on the GUI.
EAV and custom attributes
CustomAttributesDataInterface
defines the methods that are called to get and set custom attributes, including getCustomAttributes()
.
A module has a set of built-in attributes that are always available. The Catalog
module has several attributes that are defined as EAV attributes, but are treated as built-in attributes. These attributes include:
- attribute_set_id
- created_at
- group_price
- media_gallery
- name
- price
- sku
- status
- store_id
- tier_price
- type_id
- updated_at
- visibility
- weight
In this case, when getCustomAttributes()
is called, the system returns only custom attributes that are not in this list.
The Customer
module does not treat its EAV attributes in a special manner. As a result, the getCustomAttributes()
method returns all EAV attributes.
Extension attributes
Use ExtensibleDataInterface
to implement extension attributes. In your code, you must define getExtensionAttributes()
and setExtensionAttributes(*ExtensionInterface param)
.
public function getExtensionAttributes();
Most likely, you鈥檒l want to extend interfaces defined in the Api/Data
directory of an Magento module.
Declare extension attributes
You must create an <Module>/etc/extension_attributes.xml
file to define the extension attributes for a module:
<config>
<extension_attributes for="Path\To\Interface">
<attribute code="name_of_attribute" type="datatype">
<resources>
<resource ref="permission"/>
</resources>
<join reference_table="" reference_field="" join_on_field="">
<field>fieldname</field>
</join>
</attribute>
</extension_attributes>
</config>
where:
Keyword | Description | Example |
---|---|---|
for |
The fully-qualified type name with the namespace that processes the extensions. The value much be a type that implements `ExtensibleDataInterface`. The interface can be in a different module. |
Magento\Quote\Api\Data\TotalsInterface |
code |
The name of the attribute. The attribute name should be in snake case (the first letter in each word should be in lowercase, with each word separated by an underscore). |
gift_cards_amount_used |
type |
The data type. This can be a simple data type, such as string or integer, or complex type, such as an interface. |
float |
ref |
Optional. Restricts access to the extension attribute to users with the specified permission. |
Magento_CatalogInventory::cataloginventory |
reference_table |
The table involved in a join operation. See Searching extension attributes for details. |
admin_user |
reference_field |
Column in the reference_table |
user_id |
join_on_field |
The column of the table associated with the interface specified in the |
store_id |
field |
One or more fields present in the interface specified in the You can specify the |
<field>firstname</field> |
Searching extension attributes
The system uses a join directive to add external attributes to a collection and to make the collection filterable. The join
element in the extension_attributes.xml
file defines which object fields and the database table/column to use as the source of a search.
In the following example, an attribute named stock_item
of type Magento\CatalogInventory\Api\Data\StockItemInterface
added to the Magento\Catalog\Api\Data\ProductInterface
.
<extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
<attribute code="stock_item" type="Magento\CatalogInventory\Api\Data\StockItemInterface">
<join reference_table="cataloginventory_stock_item" reference_field="product_id" join_on_field="entity_id">
<field>qty</field>
</join>
</attribute>
</extension_attributes>
When getList()
is called, it returns a list of ProductInterface
s. When it does this, the code populates the stock_item
with a joined operation in which the StockItemInterface
鈥檚 qty
property come from the cataloginventory_stock_item
table where the Product
鈥檚 entity_Id
is joined with the cataloginventory_stock_item.product_id
column.
Extension attribute authentication
Individual fields that are defined as extension attributes can be restricted, based on existing permissions. This feature allows extension developers to restrict access to data. See Web API authentication overview for general information about authentication in Magento.
The following code sample defines stock_item
as an extension attribute of the CatalogInventory
module. CatalogInventory
is treated as a 鈥渢hird-party extension鈥. Access to the inventory data is restricted because the quantity of in-stock item may be competitive information.
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
<attribute code="stock_item" type="Magento\CatalogInventory\Api\Data\StockItemInterface">
<resources>
<resource ref="Magento_CatalogInventory::cataloginventory"/>
</resources>
</attribute>
</extension_attributes>
</config>
In this example, the stock_item
attribute is restricted to only the users who have the Magento_CatalogInventory::cataloginventory
permission. As a result, an anonymous or unauthenticated user issuing a GET http://<magento_base_url>/rest/V1/products/<sku>
request will receive product information similar to the following:
{
"sku": 鈥渢shirt1鈥,
鈥減rice鈥: 鈥20.00鈥,
鈥渄escription鈥: 鈥淣ew JSmith design鈥,
鈥渆xtension_attributes鈥: {
鈥渓ogo size鈥: 鈥渟mall鈥
},
鈥渃ustom_attributes鈥: {
鈥渁rtist鈥: 鈥淛ames Smith鈥
}
}
However, an authenticated user with the permission Magento_CatalogInventory::cataloginventory
receives the additional stock_item
field:
{
"sku": 鈥渢shirt1鈥,
鈥減rice鈥: 鈥20.00鈥,
鈥渄escription鈥: 鈥淣ew JSmith design鈥,
鈥渆xtension_attributes鈥: {
鈥渓ogo size鈥: 鈥渟mall鈥,
鈥渟tock_item鈥 : {
鈥渟tatus鈥 : 鈥渋n_stock鈥
鈥渜uantity鈥: 70
}
},
鈥渃ustom_attributes鈥: {
鈥渁rtist鈥: 鈥淛ames Smith鈥
}
}
This only works for extension attributes (those attributes defined in an extension_attributes.xml
file). There are no permission restrictions on the rest of the returned data. For example, there is no way to restrict custom_attributes
.
ExtensionInterfaces
An ExtensionInterface
will be empty if no extension attributes have been added. In the following example, in an unmodified installation, CustomerExtensionInterface
will be generated, but will be empty:
interface CustomerExtensionInterface extends \Magento\Framework\Api\ExtensionAttributesInterface
{
}
However, if an extension similar to the following has been defined, the interface will not be empty.
<extension_attributes for=鈥淢agento\Customer\Api\Data\CustomerInterface">
<attribute code=鈥渁ttributeName" type=鈥淢agento\Some\Type[]" />
</extension_attributes>
Find us on