Magento 2 – Implementing getExtensionAttributes() Correctly

best practiceeavextension-attributesmagento-2.1magento2

I was wondering, what's the right way to implement an extensible EAV model.

I see that in Magento\Catalog\Model\Product, the method getExtensionAttributes() is implemented like this:

public function getExtensionAttributes()
{
    $extensionAttributes = $this->_getExtensionAttributes();
    if (!$extensionAttributes) {
        return $this->extensionAttributesFactory->create('Magento\Catalog\Api\Data\ProductInterface');
    }
    return $extensionAttributes;
}

But in others, like the customer or category models it's just

public function getExtensionAttributes()
{
    return $this->_getExtensionAttributes();
}

which can lead to a NULL result, if the extension_attributes key has not been set before.

Pragmatically, I would prefer the first one. This way I can always be sure to get an instance of Magento\Framework\Api\ExtensionAttributesInterface, even if the model has just been instantiated.

But why is it not used in other modules then? Is it against the new separation of data models that we see in the customer module? If so, how are we supposed to initialize the extension attributes?

Best Answer

Magento updated the AbstractExtensibleObject::_getExtensionAttributes method to generate a empty object if it has no extension attributes https://github.com/magento/magento2/commit/375132a81b95fafa4a03a17b72dbacdc90afa745#diff-56d044692f579051647a8284ff39cc0eR165 so it will never return null. They do still need to update the API annotation though, e.g. in vendor/magento/module-customer/Model/Data/Customer.php

 /**
 * {@inheritdoc}
 *
 * @return \Magento\Customer\Api\Data\CustomerExtensionInterface|null
 */
public function getExtensionAttributes()
{
    return $this->_getExtensionAttributes();
}