3

I want to create custom API module that will return the same thing as: /V1/products REST API endpoint.

In order to do that I created the following custom endpoint:

public function __construct(
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
        \Magento\Catalog\Api\Data\ProductSearchResultsInterfaceFactory $searchResultsFactory,
        \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor) {

    $this->productCollection = $productCollectionFactory;
    $this->searchResultsFactory = $searchResultsFactory;
    $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
}

/**
 * Return the sum of the two numbers.
 *
 * @api
 * @param string $query.
 * @return \Magento\Framework\Api\SearchResults
 */
public function products($query) {

        $collection = $this->productCollection->create();
        $this->extensionAttributesJoinProcessor->process($collection);

        $collection->addAttributeToSelect('*');
        $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
        $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');

        $collection->setCurPage(1);
        $collection->setPageSize(100);
        $collection->load();

        $searchResult = $this->searchResultsFactory->create();
        $searchResult->setItems($collection->getItems());
        $searchResult->setTotalCount($collection->getSize());

    return $searchResult;
}

I created it with analogy to core /V1/products/getList:

public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
{
    /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */
    $collection = $this->collectionFactory->create();
    $this->extensionAttributesJoinProcessor->process($collection);

    foreach ($this->metadataService->getList($this->searchCriteriaBuilder->create())->getItems() as $metadata) {
        $collection->addAttributeToSelect($metadata->getAttributeCode());
    }
    $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
    $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');

    //Add filters from root filter group to the collection
    foreach ($searchCriteria->getFilterGroups() as $group) {
        $this->addFilterGroupToCollection($group, $collection);
    }
    /** @var SortOrder $sortOrder */
    foreach ((array)$searchCriteria->getSortOrders() as $sortOrder) {
        $field = $sortOrder->getField();
        $collection->addOrder(
            $field,
            ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
        );
    }
    $collection->setCurPage($searchCriteria->getCurrentPage());
    $collection->setPageSize($searchCriteria->getPageSize());
    $collection->load();

    $searchResult = $this->searchResultsFactory->create();
    $searchResult->setSearchCriteria($searchCriteria);
    $searchResult->setItems($collection->getItems());
    $searchResult->setTotalCount($collection->getSize());
    return $searchResult;
}

Nevertheless, my solution return only custom_attributes (no name, no price etc.). It does not return them even if I do so: $collection->addAttributeToSelect('name');

Do you know what can be the reason? I will be really grateful for any help.

Additionally I upload my di.xml file:

<preference for="tommyjs\Products\Api\ProductsInterface"
            type="tommyjs\Products\Model\ProductsEndpoint" />

<type name="tommyjs\Products\Model\ProductsEndpoint">
    <arguments>
        <argument name="productCollectionFactory" xsi:type="object">\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory</argument>
    </arguments>
</type>


SOLUTION

I resolved the problem by replacing:

/**
 * Return the sum of the two numbers.
 *
 * @api
 * @param string $query.
 * @return \Magento\Framework\Api\SearchResults
 */
public function products($query) {

with

/**
 * Return the sum of the two numbers.
 *
 * @api
 * @param string $query.
 * @return \Magento\Catalog\Api\Data\ProductSearchResultsInterface
 */
public function products($query) {

1 Answer 1

0

I have implement like you and success. Here you can compare and get result:

#vendor/magento/module-catalog/etc/webapi.xml

<route url="/V1/products1/:query" method="GET">
    <service class="Magento\Catalog\Api\ProductRepositoryInterface" method="products1"/>
    <resources>
        <resource ref="anonymous" />
    </resources>
</route>


#vendor/magento/module-catalog/Api/ProductRepositoryInterface.php

/**
 * Return the sum of the two numbers.
 *
 * @api
 * @param string $query|null.
 * @return \Magento\Framework\Api\SearchResults
 */
public function products1($query);


# vendor/magento/module-catalog/Model/ProductRepository.php

public function products1($query) {
    #\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollection
    $collection = $this->productCollection->create();
    $this->extensionAttributesJoinProcessor->process($collection);

    $collection->addAttributeToSelect('*');
    $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
    $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');

    $collection->setCurPage(1);
    $collection->setPageSize(100);
    $collection->load();

    $searchResult = $this->searchResultsFactory->create();
    $searchResult->setItems($collection->getItems());
    $searchResult->setTotalCount($collection->getSize());

    return $searchResult;
}

When I call the command: curl http://mage2ee.local/index.php/rest/V1/products1/1

It's work. In this case query = 1.

Remember always: Remove var folder and flush cache If you edit some .xml file.

1
  • I see that you added changes to the following core folder: vendor/magento. What I try to do is to create something similar, but as a custom module, so your answer is not exactly what I need.
    – old_user
    Jul 11, 2016 at 12:56

Your Answer

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

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