Question

Magento 2 product rest API provided custom_attributes and details provided attribute_code and value in /V1/products/:sku API. But V1/products rest API not included custom_attributes details attributes label in products.

I want to need custom_attributes in to the selected attribute value label

Method: GET

URL: http://localhost/magentosample230/rest/V1/products/sku

Actual Response:

    "custom_attributes": [
        {
            "attribute_code": "color",
            "value": "59"
        }
   ]

Expected Response:

"custom_attributes": [
    {
        "attribute_code": "color",
        "value": "59",
        "label": "white"  
    }
]

Any have idea how to get in rest API product selected attribute value "label"

Any help would be appropriated. Thanks.

Was it helpful?

Solution

I have added attribute value with label in custom_attributes products Rest API.

Also with added attribute visible_on_storefront

Follow below file path to create cusotm module and fix the requirement.

File path: magento/app/code/Vendor/AttributelabelApi/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_AttributelabelApi',
    __DIR__
);

File path: magento/app/code/Vendor/AttributelabelApi/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_AttributelabelApi" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Webapi" />
        </sequence>
    </module>
</config>

File path: magento/app/code/Vendor/AttributelabelApi/etc/webapi.xml

<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">

    <route url="/V1/products/:sku" method="GET">
        <service class="Vendor\AttributelabelApi\Api\ProductsInterface" method="getAdditional"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

File path: magento/app/code/Vendor/AttributelabelApi/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Vendor\AttributelabelApi\Api\ProductsInterface" type="Vendor\AttributelabelApi\Model\Products" />
</config>

File path: magento/app/code/Vendor/AttributelabelApi/Api/ProductsInterface.php

<?php

namespace Vendor\AttributelabelApi\Api;

interface ProductsInterface
{
     /**
     * Get info about product by product SKU
     *
     * @param string $sku
     * @param bool $editMode
     * @param int|null $storeId
     * @param bool $forceReload
     * @return \Magento\Catalog\Api\Data\ProductInterface
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getAdditional($sku, $editMode = false, $storeId = null, $forceReload = false);

}

File path: magento/app/code/Vendor/AttributelabelApi/Model/Products.php

<?php

namespace Vendor\AttributelabelApi\Model;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Vendor\AttributelabelApi\Api\ProductsInterface;
class Products implements ProductsInterface
{
   /**
     * @var \Magento\Catalog\Model\ProductFactory
     */
    protected $productFactory;

    /**
     * @var Product[]
     */
    protected $instances = [];

    /**
     * @var \Magento\Catalog\Model\ResourceModel\Product
     */
    protected $resourceModel;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var \Magento\Catalog\Helper\ImageFactory
     */
    protected $helperFactory;

    /**
     * @var \Magento\Store\Model\App\Emulation
     */
    protected $appEmulation;

    /**
     * Review model
     *
     * @var \Magento\Review\Model\ReviewFactory
     */
    protected $_reviewFactory;

     /**
     * Review resource model
     *
     * @var \Magento\Review\Model\ResourceModel\Review\CollectionFactory
     */
    protected $_reviewsColFactory;

    /**
     * @var PriceCurrencyInterface
     */
    protected $priceCurrency;

    protected $_attributeLoading;

    /**
     * ProductRepository constructor.
     * @param \Magento\Catalog\Model\ProductFactory $productFactory
     * @param \Magento\Catalog\Model\ResourceModel\Product $resourceModel
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param  \Magento\Review\Model\ReviewFactory $reviewFactory
     * @param  \Magento\Review\Model\ResourceModel\Review\CollectionFactory $collectionFactory
     * @param PriceCurrencyInterface $priceCurrency
     */
    public function __construct(
        \Magento\Catalog\Model\ProductFactory $productFactory,
        \Magento\Catalog\Model\ResourceModel\Product $resourceModel,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Store\Model\App\Emulation $appEmulation,
        \Magento\Catalog\Helper\ImageFactory $helperFactory,
        \Magento\Review\Model\ReviewFactory $reviewFactory,
        \Magento\Review\Model\ResourceModel\Review\CollectionFactory $collectionFactory,
        PriceCurrencyInterface $priceCurrency,
        \Magento\Catalog\Model\ResourceModel\ProductFactory   $attributeLoading
    ) {
        $this->productFactory       =  $productFactory;
        $this->storeManager         =  $storeManager;
        $this->resourceModel        =  $resourceModel;
        $this->helperFactory        =  $helperFactory;
        $this->appEmulation         =  $appEmulation;
        $this->_reviewFactory       =  $reviewFactory;
        $this->_reviewsColFactory   =  $collectionFactory;
        $this->priceCurrency        =  $priceCurrency;
        $this->_attributeLoading    =  $attributeLoading;
    }

    public function getAdditional($sku, $editMode = false, $storeId = null, $forceReload = false)
    {
        $cacheKey = $this->getCacheKey([$editMode, $storeId]);
        if (!isset($this->instances[$sku][$cacheKey]) || $forceReload) {
            $product = $this->productFactory->create();

            $productId = $this->resourceModel->getIdBySku($sku);
            if (!$productId) {

                throw new NoSuchEntityException(__('Requested product doesn\'t exist'));
            }
            if ($editMode) {
                $product->setData('_edit_mode', true);
            }
            if ($storeId !== null) {
                $product->setData('store_id', $storeId);
            } else {

                $storeId = $this->storeManager->getStore()->getId();
            }
            $product->load($productId);

            $excludeAttr = [];
            $attributes = $product->getAttributes();

            foreach ($attributes as $attribute) {
               $data = [];
                 if ($this->isVisibleOnFrontend($attribute, $excludeAttr))
                 {
                    $code = $attribute->getAttributeCode();
                    $value = $product->getResource()->getAttributeRawValue($product->getId(), $code, '1');
                    if ($value instanceof Phrase) {
                        $value = (string)$value;
                    } elseif ($attribute->getFrontendInput() == 'price' && is_string($value)) {
                        $value = $this->priceCurrency->convertAndFormat($value);
                    } elseif ($attribute->getFrontendInput() == 'select') {
                        $value = $attribute->getSource()->getOptionText($value);

                        $attr = $product->getResource()->getAttribute($code);
                        if ($attr->usesSource()) {
                            $optionId = $attr->getSource()->getOptionId($value);
                        }

                    } elseif ($attribute->getFrontendInput() == 'multiselect') {
                     // added if condition in order or resolve the explode issue if value is empty.
                         if($value) {
                            $multiselectOptionsArray = explode(',', $value);
                         foreach ($multiselectOptionsArray as $k => $optionKey) {
                            $multiselectOptionsArray[$k] = $attribute->getSource()->getOptionText($optionKey);
                         }
                        $value = implode(', ', $multiselectOptionsArray);
                        $multiSelectValue = explode(', ', $value);

                            foreach ($multiSelectValue as $a => $attValue) {
                                $attr = $product->getResource()->getAttribute($code);
                                if ($attr->usesSource()) {
                                    $optionIdInfo = $attr->getSource()->getOptionId($attValue);
                                    $attArray[$a] = $optionIdInfo;
                                    $optionId = implode(', ', $attArray);
                                }
                            }
                         }
                     }
                    if (is_string($value) && strlen($value)) {
                        $data[$attribute->getAttributeCode()] = [
                            'title' => $attribute->getFrontendLabel(),
                            'label' => __($value),
                            'code' => $optionId,
                            'visible_on_storefront' => $attribute->getIsVisibleOnFront()
                        ];
                    }
                    $product->setCustomAttribute($attribute->getAttributeCode(), $data);
                 }
             }

            $this->instances[$sku][$cacheKey] = $product;
            $this->instancesById[$product->getId()][$cacheKey] = $product;
        }
        return $this->instancesById[$product->getId()][$cacheKey];
   }

    /**
     * Get key for cache
     *
     * @param array $data
     * @return string
     */
    protected function getCacheKey($data)
    {
        $serializeData = [];
        foreach ($data as $key => $value) {

            if (is_object($value)) {
                $serializeData[$key] = $value->getId();
            } else {
                $serializeData[$key] = $value;
            }
        }
        return md5(serialize($serializeData));
    }

    protected function isVisibleOnFrontend(
        \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute,
        array $excludeAttr
    ) {
        return ($attribute->getIsVisibleOnFront() && !in_array($attribute->getAttributeCode(), $excludeAttr));
    }
}

OTHER TIPS

Just in case anyone needs this to be purely using the rest API, without a custom module, you can see my answer here: https://magento.stackexchange.com/a/313072/88690

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top