4

Does anyone have an idea about how to get a product with slash through the rest api ?

I have a product with sku 100/1. The closest I have gotten is to call:

get /rest/V1/products/100%252f1

But it returns {"message":"Requested product doesn't exist"}

Any idea ?

/Thomas

1
  • why magento even allows forward slash in sku if it does not support fetching products with it Commented Jun 4, 2021 at 3:54

5 Answers 5

6

I was hoping there where a well known workaround for this, but for now I solved it by writing plugins.

To get and put product, I plugged in before the get and save function in \Magento\Catalog\Api\ProductRepositoryInterface

<?php

namespace Vendor\Module\Plugin\Product;

class RestSkuFix
{
    /**
     * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
     * @param string $sku
     * @param bool $editMode
     * @param int|null $storeId
     * @param bool $forceReload
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     * @return array
     */
    public function beforeGet($productRepository, $sku, $editMode = false, $storeId = null, $forceReload = false)
    {
        $sku = urldecode($sku);
        return [$sku, $editMode, $storeId, $forceReload];
    }

    /**
     * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
     * @param \Magento\Catalog\Api\Data\ProductInterface $product
     * @param bool $saveOptions
     * @return array
     * @throws \Magento\Framework\Exception\InputException
     * @throws \Magento\Framework\Exception\StateException
     * @throws \Magento\Framework\Exception\CouldNotSaveException
     */
    public function beforeSave($productRepository, \Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false)
    {
        $product->setSku(urldecode($product->getSku()));
    }
}

And this I did only in rest webapi by registering the plugin in Vendor/Module/etc/webapi_rest/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">
    <type name="Magento\Catalog\Model\ProductRepository">
        <plugin name="ProductRepositoryRestSkuFix" type="\Vendor\Module\Plugin\Product\RestSkuFix" />
    </type>
</config>

Now I can get and put product with slash by

get /rest/V1/products/100%252f1

and

put /rest/V1/products/100%252f1
1
  • Absolutely. This makes sense if you see technically the concept of encode/decode. Thanks for the further clarity Commented Apr 8, 2022 at 11:29
4

Here is better workaround, no need to rewrite anything. Just create module containing only this webapi.xml file. Or just simply add to any existing module you have in project (even faster but not recommended).

<?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/{name-it-as-you-wish}" method="POST">
        <service class="Magento\Catalog\Api\ProductRepositoryInterface" method="get"/>
        <resources>
            <resource ref="Magento_Catalog::products" />
        </resources>
    </route>
</routes>

Now you can get product sending SKU via POST:

curl -g -X POST "$base_url/index.php/rest/V1/{name-it-as-you-wish}" \
-H "Authorization: Bearer $token" \
-H "Content-Type:application/json" \
-d '{"sku":"YOUR/SLASHED/SKU"}'
2
  • This is actually a great solution. It worked well for me and required little modification.
    – Corgalore
    Commented Jul 19, 2018 at 19:31
  • For people who are looking for the least invasive solution to this issue, this is the best choice. Commented Feb 15 at 13:58
2

To extend the answer by TNordkvist - there are additional APIs that require this correction.

<?xml version="1.0" ?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!-- ... -->
    <type name="Magento\CatalogInventory\Model\StockRegistry">
        <plugin name="ProductRepositoryRestSkuFix" type="SmithAndAssociates\Fixes\Plugin\Product\RestSkuFix" />
    </type>
</config>

And in the RestSkuFix.php:

<?php
namespace Vendor\Module\Plugin\Product;
class RestSkuFix
{

//...

/**
 * @param \Magento\CatalogInventory\Model\StockRegistry $stockRegistry
 * @param string $productSku
 * @param int $scopeId
 * @return \Magento\CatalogInventory\Api\Data\StockItemInterface
 * @throws \Magento\Framework\Exception\NoSuchEntityException
 */
public function beforeGetStockItemBySku($stockRegistry, $productSku, $scopeId = null)
{
    $productSku = urldecode($productSku);
    return [$productSku, $scopeId];
}

/**
 * @param \Magento\CatalogInventory\Model\StockRegistry $stockRegistry
 * @param string $productSku
 * @param int $scopeId
 * @throws \Magento\Framework\Exception\NoSuchEntityException
 * @return array
 */
public function beforeGetStockStatusBySku($stockRegistry, $productSku, $scopeId = null)
{
    $productSku = urldecode($productSku);
    return [$productSku, $scopeId];
}

/**
 * @param \Magento\CatalogInventory\Model\StockRegistry $stockRegistry
 * @param string $productSku
 * @param int $scopeId
 * @throws \Magento\Framework\Exception\NoSuchEntityException
 * @return array
 */
public function beforeGetProductStockStatusBySku($stockRegistry, $productSku, $scopeId = null)
{
    $productSku = urldecode($productSku);
    return [$productSku, $scopeId];
}

/**
 * @param \Magento\CatalogInventory\Model\StockRegistry $stockRegistry
 * @param string $productSku
 * @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem
 * @throws \Magento\Framework\Exception\NoSuchEntityException
 * @return array
 */
public function beforeUpdateStockItemBySku($stockRegistry, $productSku, \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem)
{
    $productSku = urldecode($productSku);
    return [$productSku, $stockItem];
}
}
0

There's currently no solution to this. The only workaround is to rename the sku.

0

Apply AllowEncodedSlashes directive in Apache

go to http.conf (or any conf file in sites-available)

<VirtualHost *:80>
   ...
   AllowEncodedSlashes On
   ...
</VirtualHost>
1
  • +1 for this answer as this is also required to be done along with the solution provided above to write before plugins. Without this change it will give you 404. So thanks! Commented Apr 8, 2022 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.