Question

I build a custom module with a stores repository that I query using the following webapi.xml:

<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
    <!-- Store Locator Service-->
    <route url="/V1/storeLocator/stores" method="GET">
        <service class="IOD\StoreLocator\Api\StoreRepositoryInterface" method="getList"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

I configured the di.xml to load the right model in the following way:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="IOD\StoreLocator\Api\StoreRepositoryInterface" type="IOD\StoreLocator\Model\StoreRepository" />
</config>

My getList function is defined in my Model\StoreRepository folder and is correctly called when invoking the API:

public function getList(SearchCriteriaInterface $criteria)
    {
        $searchResults = $this->searchResultsFactory->create();
        $searchResults->setSearchCriteria($criteria);
        $collection = $this->collectionFactory->create();
        foreach ($criteria->getFilterGroups() as $filterGroup) {
            $fields = [];
            $conditions = [];
            foreach ($filterGroup->getFilters() as $filter) {
                $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq';
                $fields[] = $filter->getField();
                $conditions[] = [$condition => $filter->getValue()];
            }
            if ($fields) {
                $collection->addFieldToFilter($fields, $conditions);
            }
        }
        $searchResults->setTotalCount($collection->getSize());
        $sortOrders = $criteria->getSortOrders();
        if ($sortOrders) {
            /** @var SortOrder $sortOrder */
            foreach ($sortOrders as $sortOrder) {
                $collection->addOrder(
                    $sortOrder->getField(),
                    ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
                );
            }
        }
        $collection->setCurPage($criteria->getCurrentPage());
        $collection->setPageSize($criteria->getPageSize());
        $objects = [];
        foreach ($collection as $objectModel) {
            $objects[] = $objectModel;
        }

        $searchResults->setItems($objects);

        return $searchResults;
    }

Now when I dump the final $objects or $searchResults I correctly see a array of three models with the full data that I want to appear in the API response however when querying the API directly using:

curl http://magento/rest/V1/storeLocator/stores?criteria=all

The response is an array of 3 empty elements. It looks like there is problem in the way magento convert my model objet into a json response. Here is the full response I get:

{"items":[[],[],[]],"search_criteria":{"filter_groups":[]},"total_count":3}

Était-ce utile?

La solution

as mentioned in the comments, the @return annotations to the getList function were Magento\Framework\Api\SearchResultsInterface. Creating a new interface extending from SearchResultsInterface as follow solved the issue:

<?php

namespace IOD\StoreLocator\Api\Data;

use Magento\Framework\Api\SearchResultsInterface;

/**
* @api
* @since 100.0.2
*/
interface StoreSearchResultsInterface extends SearchResultsInterface
{
/**
* Get attributes list.
*
* @return StoreInterface[]
*/
public function getItems();

/**
* Set attributes list.
*
* @param StoreInterface[] $items
* @return $this
*/
public function setItems(array $items);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top