1

question of interest.

We are using the PUT command for updating our products, but the data in custom attributes are not cleared when not sending in the body: rest/store_view/V1/products/sku

Is that expected behavior from Magento? We expect that a POST or PATCH is updating only the selected attributes and that a PUT would clear all attributes which are not sent in the PUT request.

2
  • Thanks for answering, we are living by this definition of a put.. PUT is a method of modifying resource where the client sends data that updates the entire resource . PATCH is a method of modifying resources where the client sends partial data that is to be updated without modifying the entire data Commented May 18, 2022 at 6:45
  • I understand. You'll need to modify your expectations for working with Magento's web API framework. Acceptable HTTP methods are defined in vendor/magento/module-webapi/etc/webapi_base.xsd, and are limited to GET, PUT, POST, and DELETE.
    – kookaburra
    Commented May 18, 2022 at 13:16

2 Answers 2

0

The behaviour you describe would probably cause a lot of trouble, as many shops use a bunch of custom attributes. So I'd say it's expected.

0

This is expected behavior.

Here's the TLDR for anyone else who comes across this question. Your API endpoint is defined in vendor/magento/module-catalog/etc/webapi.xml. The PUT method with this endpoint calls the ProductRepositoryInterface's save method:

<route url="/V1/products/:sku" method="PUT">
    <service class="Magento\Catalog\Api\ProductRepositoryInterface" method="save" />
    <resources>
        <resource ref="Magento_Catalog::products" />
    </resources>
</route>

This interface is implemented by \Magento\Catalog\Model\ProductRepository, and its save method expects a ProductInterface parameter which, critically, you have not provided, and cannot provide, in your API call:

public function save(ProductInterface $product, $saveOptions = false)
{
    $assignToCategories = false;
    $tierPrices = $product->getData('tier_price');
    $productDataToChange = $product->getData();
    // other things happen
}

So where does the $product parameter come from? In Magento's API system, parameters provided to API service classes are created using reflection:

Because of this, Magento uses reflection to automatically create these classes and sets data that you have submitted in JSON or HTTP array syntax onto an instance of the expected PHP class when calling the service method.

I don't know the deep magic of reflection well enough to point you to the place that it happens; but I expect that by providing the SKU, you tell Magento to create the $product parameter from the existing product identified by that SKU.

By the time you hit the save method, then, your $product object exists with all the data you'd expect an existing product to have. The repository will treat it just like it would any other product you're saving to repo: namely, saving new data without overwriting existing data you haven't explicitly changed.

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.