Magento2 - rest API on custom module “items” object is not populated
-
15-03-2021 - |
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}
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);
}