Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Magento 2 REST API - Updating a single category also updates other attributes to not use the default value #39498

Open
1 of 5 tasks
JoryHogeveen opened this issue Dec 20, 2024 · 3 comments
Assignees
Labels
Issue: ready for confirmation Reported on 2.4.7-p3 Indicates original Magento version for the Issue report.

Comments

@JoryHogeveen
Copy link

JoryHogeveen commented Dec 20, 2024

Preconditions and environment

  • Magento version: 2.4.7-p3
  • Anything else that would help a developer reproduce the bug

I've already posted this on StackExchange:
https://magento.stackexchange.com/questions/375887/magento-2-rest-api-updating-a-single-category-also-updates-other-attributes-to

Due to the nature of this issue I really think it's a bug. And if not, an documentation issue.

Steps to reproduce

  1. Create product with default values like name etc.
  2. Update Product for a store_code only using REST API and only provide the data for a single custom attribute.
  3. The updated product now has overrides on many other attributes even though this data was not provided by the API

Expected result

The API should only update the data you send to it.

Actual result

The API updates a lot of other attributes like name, visibility etc.

Even though this will update that particular attribute just fine, it will also set several other attributes to overwrite the default value.

See example return under additional information. All attributes seen in the response below are not set to default anymore. Note that many other attributes, also store-view attributes among them like "page_layout", are still set to default...

I have no explanation as to why some attributes are switched to not use the default anymore and some others are not. Hope someone can help me with this as I am totally lost after hours of testing.

Additional information

API request:

POST: /store_view_code/V1/products/

{
    "product": {
        "sku": "testSku",
        "custom_attributes": [
            {
                "attribute_code": "text_attribute like description or something else",
                "value": "the translated value"
            }
        ]
   }
}

API response:

{
   "id":123, // global
   "sku":"testSku", // global
   "name":"The Product title",  // Not set to default anymore.
   "attribute_set_id":4, // global
   "price":123, // Not set to default anymore.
   "status":0, // Not set to default anymore.
   "visibility":4, // Not set to default anymore.
   "type_id":"simple", // global
   "created_at":"2024-12-17 18:35:19",
   "updated_at":"2024-12-18 22:29:10",
   "extension_attributes":{
      "website_ids":[
          // Hopefully not overwritten, did not test this yet.
      ],
      "stock_item":{
          // Full stock item, not store view related.
      }
   },
   "options":[
      
   ],
   "media_gallery_entries":[
      // Hopefully not overwritten, did not test this yet.
   ],
   "custom_attributes":[

      // All attributes below not set to default anymore.
      // Note that many other attributes, also store-view attributes among them like "page_layout", are still set to default...

      {
         "attribute_code": "text_attribute like description or something else",
         "value": "the translated value" // This is ok! And should be the only attribute that was changed.
      }
      {
         "attribute_code":"url_key",
         "value":"the-product-url-key" // Not set to default anymore.
      },
      {
         "attribute_code":"options_container",
         "value":"container2" // Not set to default anymore.
      },
      {
         "attribute_code":"tax_class_id",
         "value":"2" // Not set to default anymore. (website scope)
      },
      {
         "attribute_code":"required_options",
         "value":"0" // No idea.
      },
      {
         "attribute_code":"has_options",
         "value":"0" // No idea.
      },
      {
         "attribute_code":"category_ids",
         "value":[
            // Hopefully not overwritten, did not test this yet.
         ]
      }
   ]
}

Release note

I've set this to severity S0 as with the current state it will override important attributes like visibility, status and name without intent. This can create big issues on live instances where users could suddenly see hidden products in the catalog or even products with incorrect data.

Triage and priority

  • Severity: S0 - Affects critical data or functionality and leaves users without workaround.
  • Severity: S1 - Affects critical data or functionality and forces users to employ a workaround.
  • Severity: S2 - Affects non-critical data or functionality and forces users to employ a workaround.
  • Severity: S3 - Affects non-critical data or functionality and does not force users to employ a workaround.
  • Severity: S4 - Affects aesthetics, professional look and feel, “quality” or “usability”.
Copy link

m2-assistant bot commented Dec 20, 2024

Hi @JoryHogeveen. Thank you for your report.
To speed up processing of this issue, make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce.


Join Magento Community Engineering Slack and ask your questions in #github channel.
⚠️ According to the Magento Contribution requirements, all issues must go through the Community Contributions Triage process. Community Contributions Triage is a public meeting.
🕙 You can find the schedule on the Magento Community Calendar page.
📞 The triage of issues happens in the queue order. If you want to speed up the delivery of your contribution, join the Community Contributions Triage session to discuss the appropriate ticket.

Copy link

m2-assistant bot commented Dec 20, 2024

Hi @engcom-Bravo. Thank you for working on this issue.
In order to make sure that issue has enough information and ready for development, please read and check the following instruction: 👇

  • 1. Verify that issue has all the required information. (Preconditions, Steps to reproduce, Expected result, Actual result).
  • 2. Verify that issue has a meaningful description and provides enough information to reproduce the issue.
  • 3. Add Area: XXXXX label to the ticket, indicating the functional areas it may be related to.
  • 4. Verify that the issue is reproducible on 2.4-develop branch
    Details- If the issue is reproducible on 2.4-develop branch, please, add the label Reproduced on 2.4.x.
    - If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and stop verification process here!
  • 5. Add label Issue: Confirmed once verification is complete.
  • 6. Make sure that automatic system confirms that report has been added to the backlog.

@engcom-Bravo engcom-Bravo added the Reported on 2.4.7-p3 Indicates original Magento version for the Issue report. label Dec 20, 2024
@micro112
Copy link

In Magento 2, when you use the REST API to update a category, sometimes updating a single attribute causes other attributes to be overwritten or marked as non-default. This behavior can be frustrating if you're only trying to update one attribute.

Here’s an explanation of why this happens and how to avoid it:

Why does this happen?
When you send a PUT request to update a category through the REST API, Magento updates all attributes of the category with the data provided in the request. If any attribute is not specified in the request, Magento assumes you want to update it and set the value to the non-default value. This can result in default values being overwritten or other attributes being changed unintentionally.

Example:
Let’s say you only want to update the name of a category, but you send a request like this:

json
Copy code
{
"category": {
"id": 10,
"name": "New Category Name"
}
}
In this case, Magento will update only the name, but it may also unintentionally overwrite other attributes (like description, custom attributes, etc.) to null or the specified value.

How to Update Only a Single Attribute:
Partial Update: Unfortunately, Magento's REST API does not support partial updates out-of-the-box (as of version 2.x). The API expects you to provide the full category data, and it will update any attributes sent, including those you may not intend to change.

Default Values Handling: If you only need to modify a single attribute (e.g., the name), make sure to include all other attributes in your request with their current values. This way, the values you don't want to change will not be overwritten.

Step-by-step approach:

First, retrieve the current category data using the GET request to the /V1/categories/{categoryId} endpoint.
Then, build your update request including all attributes, but only modify the ones you actually want to update.
Example:

GET request to retrieve category data:

bash
Copy code
GET /V1/categories/10
Response:

json
Copy code
{
"id": 10,
"name": "Old Category Name",
"description": "Old description",
"is_active": true,
"parent_id": 2,
"meta_title": "Old Meta Title",
...
}
PUT request to update category: Now you can send the updated category data including all the attributes:

json
Copy code
{
"category": {
"id": 10,
"name": "New Category Name",
"description": "Old description",
"is_active": true,
"parent_id": 2,
"meta_title": "Old Meta Title"
}
}
Use a Custom API Endpoint: If you need a more flexible approach (for example, updating just one attribute without affecting others), you might need to create a custom API endpoint. In this case, you could create a custom Magento module that allows you to selectively update a single category attribute.

Using Magento's GraphQL as an Alternative:
If you’re working with Magento 2.3 or higher, GraphQL might be a better alternative for partial updates. Magento's GraphQL API supports more granular operations, and you can update only the necessary fields without impacting others.

For instance, updating a category using GraphQL:

graphql
Copy code
mutation {
updateCategory(
input: {
id: 10
name: "New Category Name"
}
) {
category {
id
name
}
}
}
Summary:
Default value changes: When updating a category through Magento's REST API, the lack of partial updates means that missing attributes can be set to null or non-default values. To avoid this, ensure you include all attributes when performing a PUT request.
Custom API or GraphQL: Consider using a custom API or GraphQL for more flexibility in handling category updates.
If you need any further help or have specific concerns about your Magento setup, feel free to provide more details!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue: ready for confirmation Reported on 2.4.7-p3 Indicates original Magento version for the Issue report.
Projects
Status: Ready for Confirmation
Development

No branches or pull requests

3 participants