Skip to content

Conversation

@Codencode
Copy link
Contributor

@Codencode Codencode commented Nov 6, 2025

Questions Answers
Description?
Type? improvement
BC breaks? no
Deprecations? no
Fixed ticket?
Sponsor company Codencode snc
How to test?

How To Test - Product Category Endpoints

Create an API Client with these scopes:
product_write


Query 1 - Assign Product to Category

Method: POST
URI: /products/{productId}/assign-to-category
Example: /products/1/assign-to-category

Body

{
  "categoryId": 3
}

Response

  • HTTP 201 Created
{
  "productId": 1,
  "categories": [
    {
      "id": 3,
      "name": "Clothes",
      "displayName": "Clothes"
    }
  ]
}

Query 2 - Set Associated Product Categories

Method: POST
URI: /products/{productId}/categories
Example: /products/1/categories

Body

{
  "categoryIds": [3, 4, 5],
  "defaultCategoryId": 5
}

Response

  • HTTP 201 Created
{
  "productId": 1,
  "defaultCategoryId": 5,
  "categories": [
    {
      "id": 3,
      "name": "Clothes",
      "displayName": "Clothes"
    },
    {
      "id": 4,
      "name": "Men",
      "displayName": "Men"
    },
    {
      "id": 5,
      "name": "Women",
      "displayName": "Women"
    }
  ]
}

Query 3 - Remove All Associated Product Categories

Method: DELETE
URI: /products/{productId}/categories
Example: /product/1/categories

Body

Nessun body richiesto.

Response

  • HTTP 204 No Content

@Codencode Codencode marked this pull request as draft November 6, 2025 08:20
@Codencode Codencode force-pushed the product-category-endpoints branch 8 times, most recently from e08f39d to b29f62f Compare November 6, 2025 10:26
@Codencode Codencode marked this pull request as ready for review November 6, 2025 10:49
@github-project-automation github-project-automation bot moved this to Ready for review in PR Dashboard Nov 6, 2025
@Codencode Codencode requested a review from a team November 6, 2025 10:50
@Codencode Codencode marked this pull request as draft November 13, 2025 11:48
@Codencode Codencode force-pushed the product-category-endpoints branch 4 times, most recently from 70f37ab to 01a81dd Compare November 13, 2025 15:24
@ga-devfront ga-devfront removed the request for review from a team November 13, 2025 15:25
@ga-devfront
Copy link

While the PR is in draft, I am taking the liberty of removing the review request.

@Codencode
Copy link
Contributor Author

While the PR is in draft, I am taking the liberty of removing the review request.

Oh yes, you're right, I hadn't thought of that 🙏

@Codencode
Copy link
Contributor Author

To display the list of categories in the response, I created PrestaShop\Module\APIResources\Serializer\ProductCategoryOutputNormalizer, which enables generating a tailored response for ProductForEditing, but only for the ProductCategory API.

I implemented this control by checking the use_product_category_normalizer key defined in ProductCategory::QUERY_MAPPING.
If there's a better way to do this, please let me know.

Thank you!

@Codencode Codencode marked this pull request as ready for review November 13, 2025 15:46
@Codencode Codencode requested a review from a team November 13, 2025 15:46
Comment on lines +85 to +87
// Enables the ProductCategoryOutputNormalizer
// for serializing the response of CQRS category endpoints.
'use_product_category_normalizer' => true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The options for normalization shouldn't be in this field which is a pure PrestaShop custom field It should be in the normalization context instead

But I think we should be able to handle this use case without relying on a normalizer, but first I have one question: should this endpoint return the full product? or only the part with the categories?

Ideally, we should keep it simple and only return the list of associated categories, the thing is we don't have such a query and the API is only meant to be a bridge to the existing CQRS classes, because of this limiation the list of associated categoruies can only be fetch via GetProductForEditing

Which means the categories should be displayed in the return of this endpoint, but to do that this whole API resource should have the same fields as the PrestaShop\Module\APIResources\ApiPlatform\Resources\Product\Product resource, so it should probably extend it which can be a bit overkill

OR we can decide that this update endpoint doesn't return data and simply indicates if it succeeded by returning a no response 204, and to check the modified content we can use /products/1, if so then the missing mapping needs to be added on PrestaShop\Module\APIResources\ApiPlatform\Resources\Product\Product

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to use mapping to handle the categories properly in this PR #116

But it required another modification in the core so that I can rename the categoryId properly We could have kept the id in the sub object, but it doesn't really respect the expected convention (IDs should be prefixed with their associated resource), so I preferred to do this POC to see if we can handle it as expected

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jolelievre

But I think we should be able to handle this use case without relying on a normalizer, but first I have one question: should this endpoint return the full product? or only the part with the categories?

I believe the response should only include the part with the categories.

Which means the categories should be displayed in the return of this endpoint, but to do that this whole API resource should have the same fields as the PrestaShop\Module\APIResources\ApiPlatform\Resources\Product\Product resource, so it should probably extend it which can be a bit overkill

Yes, I think it's excessive too ;-)

OR we can decide that this update endpoint doesn't return data and simply indicates if it succeeded by returning a no response 204, and to check the modified content we can use /products/1, if so then the missing mapping needs to be added on PrestaShop\Module\APIResources\ApiPlatform\Resources\Product\Product

It's the first solution I implemented, then I added a commit with the creation of the normalizer (this was following our conversation on Slack).

I tried to use mapping to handle the categories properly in this PR #116
But it required another modification in the core so that I can rename the categoryId properly We could have kept the id in the sub object, but it doesn't really respect the expected convention (IDs should be prefixed with their associated resource), so I preferred to do this POC to see if we can handle it as expected

I couldn't understand this point, maybe I didn't translate it well or I'm having trouble following your reasoning 😅

}
}

public function testAssignProductToCategory(): void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add these endpoints earlier in the workflow, you can pass it the $productId this way you can test these changes on the newly created product instead of hard-coded ID 1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, I should make the test testAssignProductToCategory() dependent on the test testPartialUpdateProduct() in order to receive the product id as input, right?
But the category id would still be hardcoded in the method?

@ps-jarvis ps-jarvis moved this from Ready for review to Waiting for author in PR Dashboard Nov 28, 2025
@nicosomb
Copy link
Contributor

@Codencode one test is red

@Codencode
Copy link
Contributor Author

@Codencode one test is red

@nicosomb, yes I know, I asked @jolelievre because there's an issue between the documentation and the Rector Dry Run. He will decide how to proceed.

Thanks for the heads-up 😃

@jolelievre
Copy link
Contributor

Hi @Codencode

for this one you can update ApiResourceUriTemplateRector::SKIPPED_KEYWORDS and add assign-to-category in it This array contains the exceptions for words we accept as singular forms, mostly actions. But there are a few relevant singular words like cover

@Codencode Codencode force-pushed the product-category-endpoints branch from c70e27d to ced1c41 Compare November 28, 2025 16:55
@Codencode
Copy link
Contributor Author

Hi @jolelievre,

I've made the change, I hope I understood correctly 😄.

Thanks!

@kpodemski
Copy link
Contributor

Hello @Codencode

There's a conflict in services.yml that probably appeared when we merged another PR. Could you resolve it?

@Codencode Codencode force-pushed the product-category-endpoints branch from dbd4bf3 to 5717560 Compare December 17, 2025 11:46
@Codencode
Copy link
Contributor Author

Hello @kpodemski
Solved.

Thank you!

@nicosomb nicosomb moved this from Waiting for author to Ready for review in PR Dashboard Dec 18, 2025
@kpodemski kpodemski added the Invalid This doesn't seem right label Jan 23, 2026
@kpodemski
Copy link
Contributor

Hello @Codencode

Just a quick heads-up: reviews on pending Admin API PRs will start in the coming days.

We first took some time to clarify and unify the Admin API contribution rules and ADR expectations. With that work done, the team will now review existing PRs based on those updates.

Please note that, based on the updated standards described here:
https://devdocs.prestashop-project.org/9/admin-api/contribute-to-core-api/

some aspects of this PR currently do not meet the requirements. For this reason, I've added the Invalid label for now.

Someone from the team will take a closer look at the PR and provide concrete suggestions on how it can be adjusted to align with the new guidelines.

Thanks for your patience. Feedback will follow directly on the PR.

@Codencode
Copy link
Contributor Author

Hello @kpodemski,
ok, no problem. I've noticed there have been some changes in this area, and I believe this can only improve the entire ecosystem — having clear rules to follow is always better 😉!
I remain at your disposal.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Admin API Contributions Invalid This doesn't seem right

Projects

Status: Ready for review

Development

Successfully merging this pull request may close these issues.

6 participants