Magento 2 - get categories by using interfaces in API
-
09-10-2020 - |
Question
In Magento 2, you're supposed to use the interfaces in Magento's API. So, when you want to fetch product(s), you'd use \Magento\Catalog\Api\ProductRepositoryInterface
. That works great and it's very convenient.
Now when I want to get a list of categories, based on my search criteria. What's the best way to approach this? I don't really see the options, because:
\Magento\Catalog\Api\CategoryRepositoryInterface
only supports a single entity, nogetList()
or something like that.\Magento\Catalog\Model\ResourceModel\Category\Collection\Factory
is used a lot from what I've seen from community code. However, this class is deprecated, which clearly means it shouldn't be used.\Magento\Catalog\Model\CategoryFactory
is also used a lot. It's a dynamically generated factory. Developers would use this factory to create a category model and get it's collection. That seems really awful to me, but it's a way to go I guess..
Solution
About a year later, Magento naturally has evolved and the Magento\Catalog\Api\CategoryListInterface
can now be used.
It works great, I can do stuff like this:
/**
* @var CategoryListInterface
*/
private $categoryListRepository;
/**
* @var SearchCriteriaBuilder
*/
private $searchCriteriaBuilder;
/**
* CategoryList constructor.
* @param CategoryListInterface $categoryList
* @param SearchCriteriaBuilder $searchCriteriaBuilder
* @SuppressWarnings(PHPMD.LongVariableNames)
*/
public function __construct(
CategoryListInterface $categoryListRepository,
SearchCriteriaBuilder $searchCriteriaBuilder
) {
$this->categoryListRepository = $categoryListRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
}
/**
* @param int $parentId
* @return CategoryInterface[]
*/
public function getCategories(int $parentId): array
{
$this->searchCriteriaBuilder->addFilter('parent_id', $parentId);
$searchCriteria = $this->searchCriteriaBuilder->create();
$results = $this->categoryListRepository->getList($searchCriteria);
return $results->getItems();
}
mpw's answer is useful as well and is supported by Magento, but my question was aiming for a service contract method.
OTHER TIPS
Since Magento\Catalog\Model\ResourceModel\Category\Collection
has an @api
annotation (as of 2.2), it appears that Magento has officially sanctioned the old style.
Rather than use the deprecated \Magento\Catalog\Model\ResourceModel\Category\Collection\Factory
, I believe Magento would prefer usage of \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory
, which is generated and has no deprecation.