If you want to return the result as a JSON object via a rest API call, you must use data objects with appropriate interfaces. Your method (testMethod()
) should return, say, CustomerDataInterface
, whereas CustomerDataInterface
should have a getAddress
method that returns AddressDataInterface
. The Rest API has some limitations, and one of them is the inability to return simple arrays.
Example:
app/code/Dev/RestApi/Api/Data/AddressInterface.php
namespace Dev\RestApi\Api\Data;
interface AddressInterface
{
/**
* Get street.
*
* @return string|null
*/
public function getStreet(): ?string;
/**
* Get city.
*
* @return string|null
*/
public function getCity(): ?string;
/**
* Get zip code.
*
* @return string|null
*/
public function getZip(): ?string;
}
app/code/Dev/RestApi/Model/Address.php
namespace Dev\RestApi\Model;
use Dev\RestApi\Api\Data\AddressInterface;
class Address implements AddressInterface
{
/**
* @var string|null
*/
private $street;
/**
* @var string|null
*/
private $city;
/**
* @var string|null
*/
private $zip;
/**
* Set street.
*
* @param string|null $street
* @return AddressInterface
*/
public function setStreet(?string $street): AddressInterface
{
$this->street = $street;
return $this;
}
/**
* Set city.
*
* @param string|null $city
* @return AddressInterface
*/
public function setCity(?string $city): AddressInterface
{
$this->city = $city;
return $this;
}
/**
* Set zip code.
*
* @param string|null $zip
* @return AddressInterface
*/
public function setZip(?string $zip): AddressInterface
{
$this->zip = $zip;
return $this;
}
/**
* Get street.
*
* @return string|null
*/
public function getStreet(): ?string
{
return $this->street;
}
/**
* Get city.
*
* @return string|null
*/
public function getCity(): ?string
{
return $this->city;
}
/**
* Get zip code.
*
* @return string|null
*/
public function getZip(): ?string
{
return $this->zip;
}
}
app/code/Dev/RestApi/Api/Data/MainDataInterface.php
namespace Dev\RestApi\Api\Data;
interface MainDataInterface
{
/**
* Get name.
*
* @return string|null
*/
public function getName(): ?string;
/**
* Get age.
*
* @return int|null
*/
public function getAge(): ?int;
/**
* Get car.
*
* @return string|null
*/
public function getCar(): ?string;
/**
* Get some.
*
* @return string|null
*/
public function getSome(): ?string;
/**
* Get address.
*
* @return \Dev\RestApi\Api\Data\AddressInterface
*/
public function getAddress(): AddressInterface;
}
app/code/Dev/RestApi/Model/MainData.php
namespace Dev\RestApi\Model;
use Dev\RestApi\Api\Data\MainDataInterface;
use Dev\RestApi\Api\Data\AddressInterface;
class MainData implements MainDataInterface
{
/**
* @var string|null
*/
private $name;
/**
* @var int|null
*/
private $age;
/**
* @var string|null
*/
private $car;
/**
* @var string|null
*/
private $some;
/**
* @var AddressInterface
*/
private $address;
public function __construct(AddressInterface $address)
{
$this->address = $address;
}
/**
* Set name.
*
* @param string|null $name
* @return MainDataInterface
*/
public function setName(?string $name): MainDataInterface
{
$this->name = $name;
return $this;
}
/**
* Set age.
*
* @param int|null $age
* @return MainDataInterface
*/
public function setAge(?int $age): MainDataInterface
{
$this->age = $age;
return $this;
}
/**
* Set car.
*
* @param string|null $car
* @return MainDataInterface
*/
public function setCar(?string $car): MainDataInterface
{
$this->car = $car;
return $this;
}
/**
* Set some.
*
* @param string|null $some
* @return MainDataInterface
*/
public function setSome(?string $some): MainDataInterface
{
$this->some = $some;
return $this;
}
/**
* Get name.
*
* @return string|null
*/
public function getName(): ?string
{
return $this->name;
}
/**
* Get age.
*
* @return int|null
*/
public function getAge(): ?int
{
return $this->age;
}
/**
* Get car.
*
* @return string|null
*/
public function getCar(): ?string
{
return $this->car;
}
/**
* Get some.
*
* @return string|null
*/
public function getSome(): ?string
{
return $this->some;
}
/**
* Get address.
*
* @return \Dev\RestApi\Api\Data\AddressInterface
*/
public function getAddress(): AddressInterface
{
return $this->address;
}
}
Update preferences in the di.xml
:
app/code/Dev/RestApi/etc/di.xml
<?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="Dev\RestApi\Api\Data\MainDataInterface" type="Dev\RestApi\Model\MainData" />
<preference for="Dev\RestApi\Api\Data\AddressInterface" type="Dev\RestApi\Model\Address" />
</config>
Update your main interface and model:
app/code/Dev/RestApi/Api/TestInterface.php
namespace Dev\RestApi\Api;
use Dev\RestApi\Api\Data\MainDataInterface;
interface TestInterface
{
/**
* @return MainDataInterface
*/
public function testMethod(): MainDataInterface;
}
app/code/Dev/RestApi/Model/TestModel.php
namespace Dev\RestApi\Model;
use Dev\RestApi\Api\TestInterface;
use Dev\RestApi\Api\Data\MainDataInterface;
use Dev\RestApi\Model\MainData; // Assuming you have MainData class
class TestModel implements TestInterface
{
public function testMethod(): MainDataInterface
{
$mainData = new MainData();
$mainData
->setName('John')
->setAge(30)
->setCar(null)
->setSome(null);
$address = new Address();
$address
->setStreet('123 Main St')
->setCity('Anytown')
->setZip('12345');
$mainData->setAddress($address);
return $mainData;
}
}
PS: This is just a quickly generated sample code, you should update it to suit your needs and best practices!
JSON_PRETTY_PRINT
if you don’t want the formatting in the result?