Magento 2 Rest Api get Thumbnail Image url

The question:

How do we get the url to thumbnail image of of a product through rest API.

/V1/products/{sku}/media
would get us the relative url such as "/m/b/mb01-blue-0.jpg"

and the image url would be baseurl/catalog/product/m/b/mb01-blue-0.jpg

This works fine. But how do we get the thumbnail which usually resides in the cache folder.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

If you need the complete path of the thumbnail image with Magento 2 cache system through API, you can create your custom API based on the native ProductRepository class.

Create a new module. (explained in other posts)

Create a etc/webapi.xml file :

<?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/custom/products/{sku}" method="GET">
        <service class="VendorModuleNameApiProductRepositoryInterface" method="get"/>
        <resources>
            <resource ref="Magento_Catalog::products"/>
        </resources>
    </route>
</routes>

Create a etc/di.xml file :

<?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="VendorModuleNameApiProductRepositoryInterface" type="VendorModuleNameModelProductRepository" />
</config>

Create your interface ApiProductRepositoryInterface.php :

namespace VendorModuleNameApi;

/**
 * @api
 */
interface ProductRepositoryInterface
{
    /**
     * Get info about product by product SKU
     *
     * @param string $sku
     * @param bool $editMode
     * @param int|null $storeId
     * @param bool $forceReload
     * @return MagentoCatalogApiDataProductInterface
     * @throws MagentoFrameworkExceptionNoSuchEntityException
     */
    public function get($sku, $editMode = false, $storeId = null, $forceReload = false);
}

Create your model ModelProductRepository.php :

namespace VendorModuleNameModel;


class ProductRepository implements MagentoCatalogApiProductRepositoryInterface
{
    /**
     * @var MagentoCatalogModelProductFactory
     */
    protected $productFactory;

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

    /**
     * @var MagentoCatalogModelResourceModelProduct
     */
    protected $resourceModel;

    /**
     * @var MagentoStoreModelStoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var MagentoCatalogHelperImageFactory
     */
    protected $helperFactory;

    /**
     * @var MagentoStoreModelAppEmulation
     */
    protected $appEmulation;

    /**
     * ProductRepository constructor.
     * @param MagentoCatalogModelProductFactory $productFactory
     * @param MagentoCatalogModelResourceModelProduct $resourceModel
     * @param MagentoStoreModelStoreManagerInterface $storeManager
     */
    public function __construct(
        MagentoCatalogModelProductFactory $productFactory,
        MagentoCatalogModelResourceModelProduct $resourceModel,
        MagentoStoreModelStoreManagerInterface $storeManager,
        MagentoStoreModelAppEmulation $appEmulation,
        MagentoCatalogHelperImageFactory $helperFactory
    ) {
        $this->productFactory = $productFactory;
        $this->storeManager = $storeManager;
        $this->resourceModel = $resourceModel;
        $this->helperFactory = $helperFactory;
        $this->appEmulation = $appEmulation;
    }


    /**
     * {@inheritdoc}
     */
    public function get($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 {
                // Start Custom code here

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

            $this->appEmulation->startEnvironmentEmulation($storeId, MagentoFrameworkAppArea::AREA_FRONTEND, true);

            $imageUrl = $this->getImage($product, 'product_thumbnail_image')->getUrl();

            $customAttribute = $product->setCustomAttribute('thumbnail', $imageUrl);

            $this->appEmulation->stopEnvironmentEmulation();

            // End Custom code here

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

    /**
     * Retrieve product image
     *
     * @param MagentoCatalogModelProduct $product
     * @param string $imageId
     * @param array $attributes
     * @return MagentoCatalogBlockProductImage
     */
    public function getImage($product, $imageId, $attributes = [])
    {
        $image = $this->helperFactory->create()->init($product, $imageId)
            ->constrainOnly(true)
            ->keepAspectRatio(true)
            ->keepTransparency(true)
            ->keepFrame(false)
            ->resize(75, 75);

        return $image;
    }

}

Access

Go to /rest/V1/custom/products/{sku}

You should retrieve the thumbnail image with the image frontend URL cached :

<custom_attributes>
    <item>
        <attribute_code>thumbnail</attribute_code>
        <value>http://{domain}/media/catalog/product/cache/1/thumbnail/75x75/e9c3970ab036de70892d86c6d221abfe/s/r/{imageName}.jpg</value>
    </item>
</custom_attributes>

Comments :

The third parameter of the function startEnvironmentEmulation is used to force the use of frontend area if you are already on the same storeId. (usefull for API area)

I do not test this custom API, you may adapt the code but the logic is correct but I already tested the part to retrieve the image URL in other custom API.

This workaround avoid you to have this kind of errors :

http://XXXX.com/pub/static/webapi_rest/_view/en_US/Magento_Catalog/images/product/placeholder/.jpg

Uncaught MagentoFrameworkViewAssetFileNotFoundException: Unable to resolve the source file for 'adminhtml/_view/en_US/Magento_Catalog/images/product/placeh‌​older/.jpg'

Method 2

The reasons why Magento doesn’t provide this functionality out of the box are next:

  • To return image thumbnail URL as a part of Product with attribute or extension attribute that will mean to introduce support of Read-Only (non-modifiable) attributes in Data Objects. Because URL is a representation of some data. Data taken from different sources, as domain name belongs to system configuration, but path belongs to Catalog module.
  • For now Magento doesn’t support read-only attributes or service for Query API.

As a long term solution – Query APIs should address this question, as they will provide an ability for read-only and computed fields.
As a solution we could provide for community nearest time – we could implement/introduce dedicated URL resolver service which will return URL for specific entity types (like Product, Category, Image etc.)

For the same reason we don’t provide Product URL as a part of ProductInterface

Here is my response devoted to this issue (Product URL):
https://community.magento.com/t5/Programming-Questions/Retrieving-the-product-URL-for-the-current-store-from-a/m-p/55387/highlight/true#M1400

Method 3

It should be possible with the following url: /rest/V1/products/{sku}

This will return the product and there should be a node for custom_attributes which contains a thumbnail link

<custom_attributes>
    <item>
        <attribute_code>thumbnail</attribute_code>
        <value>/m/b/mb01-blue-0.jpg</value>
    </item>
</custom_attributes>


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment