cancel
Showing results for 
Search instead for 
Did you mean: 

Rest API Thumbnail from cache

Rest API Thumbnail from cache

In my case Magento2 delivers to another CMS-System Product Informations via REST API. The CMS-System caches an downsized image in another caching system. This works, but if there are to many images after clearing cache, the system comes to it's limits.

 

Is there a way to get directly the cached thumbnail image from the catalog view from an API call?

e.g. /pub/media/catalog/product/cache/f073062f50e48eb0f0998593e568d857/9/7/9783532624999.png

Is this only possible with a new module extending the API? But how?

 

Thank for your help,

Martin

 

 

$requestUrl=$restbase.'/rest/V1/products/'.$sku;

 

 

[media_gallery_entries] => Array
        (
            [0] => stdClass Object
                (
                    [id] => 321
                    [media_type] => image
                    [label] => 
                    [position] => 
                    [disabled] => 
                    [types] => Array
                        (
                        )

                    [file] => /9/7/9783532624999.png
                )

            [1] => stdClass Object
                (
                    [id] => 739
                    [media_type] => image
                    [label] => 
                    [position] => 
                    [disabled] => 
                    [types] => Array
                        (
                        )

                    [file] => /9/7/9783532624999.jpg
                )

            [2] => stdClass Object
                (
                    [id] => 740
                    [media_type] => image
                    [label] => 
                    [position] => 
                    [disabled] => 
                    [types] => Array
                        (
                        )

                    [file] => /9/7/9783532624999_1.jpg
                )

            [3] => stdClass Object
                (
                    [id] => 974
                    [media_type] => image
                    [label] => 
                    [position] => 
                    [disabled] => 
                    [types] => Array
                        (
                        )

                    [file] => /9/7/9783532624999_1.png
                )

        )

 

 

1 REPLY

Re: Rest API Thumbnail from cache

Hello typotraum

 

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 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="Vendor\ModuleName\Api\ProductRepositoryInterface" 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="Vendor\ModuleName\Api\ProductRepositoryInterface" type="Vendor\ModuleName\Model\ProductRepository" />
</config>

Create your interface Api\ProductRepositoryInterface.php :

 

 

namespace Vendor\ModuleName\Api;

/**
 * @api
 */
interface ProductRepositoryInterface
{
    /**
     * 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 get($sku, $editMode = false, $storeId = null, $forceReload = false);
}

 

 

namespace Vendor\ModuleName\Model;


class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterface
{
    /**
     * @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;

    /**
     * ProductRepository constructor.
     * @param \Magento\Catalog\Model\ProductFactory $productFactory
     * @param \Magento\Catalog\Model\ResourceModel\Product $resourceModel
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     */
    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
    ) {
        $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, \Magento\Framework\App\Area::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 \Magento\Catalog\Model\Product $product
     * @param string $imageId
     * @param array $attributes
     * @return \Magento\Catalog\Block\Product\Image
     */
    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 Magento\Framework\View\Asset\File\NotFoundException: Unable to resolve the source file for 'adminhtml/_view/en_US/Magento_Catalog/images/product/placeh‌​older/.jpg'

 

hope it will help you, if works then mark as solution.