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.
- 
 There is no such functionality out of the box. You'll have to write custom API.Sinisa Nedeljkovic– Sinisa Nedeljkovic2017年02月28日 20:19:06 +00:00Commented Feb 28, 2017 at 20:19
3 Answers 3
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="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);
}
Create your model Model\ProductRepository.php :
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/placeholder/.jpg'
- 
 I think this might work better with the\Magento\Catalog\Api\ProductRepositoryInterfaceFactoryinstead of\Magento\Catalog\Model\ProductFactory, since you can callget()on theproductRepositryobject with the SKU directly. At least, that's what I'm using now.thaddeusmt– thaddeusmt2017年03月16日 20:47:27 +00:00Commented Mar 16, 2017 at 20:47
- 
 We don't encourage to provide own ProductRepositoryInterface , because there is one provided by Catalog module. And we suppose that you will customize existing one if needed. Because ideally all the clients which dependent on Catalog's ProductRepositoryInterface should not be affected with your change. There are two possible solution for currect issue: 1. Add URL as a part of ProductInterface as extension attribute 2. Introuce dedicated URL resolver service. The first solution doesn't fit current architecture of Service contract, because this attribute should be read-only.Igor Minyaylo– Igor Minyaylo2017年04月24日 10:46:25 +00:00Commented Apr 24, 2017 at 10:46
- 
 Indeed, this answer is to put in evidence a possible workaround of this issue. The best solution is to add a dedicated URL resolver service and to based on the native catalog API.Franck Garnier– Franck Garnier2017年04月24日 11:38:12 +00:00Commented Apr 24, 2017 at 11:38
- 
 hi @franck Garnier i am getting an error as shown in this screenshot prntscr.com/g5q4ak how to solve please suggest me thanks?Nagaraju Kasa– Nagaraju Kasa2017年08月08日 05:40:40 +00:00Commented Aug 8, 2017 at 5:40
- 
 You error is explicit, the function do not exist. I just give you a code example, but you need to adapt it with your needs. For example implement the getCacheKey function such as like here :vendor/magento/module-catalog/Model/ProductRepository.php:258Franck Garnier– Franck Garnier2017年08月08日 08:35:33 +00:00Commented Aug 8, 2017 at 8:35
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
- 
 1When does a such URL resolver service will be available out of the box ?Franck Garnier– Franck Garnier2017年11月02日 15:34:05 +00:00Commented Nov 2, 2017 at 15:34
- 
 The answer is from 2017. Has this been added in Magenta 2.1.x 2.2.x or 2.3.x since then?Marcus Wolschon– Marcus Wolschon2018年09月13日 05:52:25 +00:00Commented Sep 13, 2018 at 5:52
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>
- 
 cache/1/thumbnail/88x110/beff4985b56e3afdbeabfc89641a4582/m/b/mb02-blue-0.jpg this is the thumbnail location. is there a way to get this?Mohammed Shameem– Mohammed Shameem2016年07月23日 16:20:27 +00:00Commented Jul 23, 2016 at 16:20
- 
 /V1/products/{sku}/media and /rest/V1/products/{sku} gives the same result the former gives the media alone and the later gives all the other information as well.Mohammed Shameem– Mohammed Shameem2016年07月23日 16:27:26 +00:00Commented Jul 23, 2016 at 16:27
- 
 @MohammedShameem have you find any working solution?torayeff– torayeff2016年08月01日 17:22:20 +00:00Commented Aug 1, 2016 at 17:22
- 
 @torayeff not yet. I guess will have to write one. Do you have any suggessions?Mohammed Shameem– Mohammed Shameem2016年08月03日 09:17:07 +00:00Commented Aug 3, 2016 at 9:17
Explore related questions
See similar questions with these tags.