i have my custom api which will return multi dimension array , which will have key pair value, where key and value are dynamic from database in that case how to achieve in rest api of magento2
3 Answers
to achieve multi dimension array where key and value are dynamic we can follow below steps but magento discourage this solution if any better solution please let me know out put
{
"name": "Test Name"
"key": "value"
"key2": "value2"
"multi": {
"name": "Test Name"
"key": "value"
"key2": "value2"
}-
}
where key and value are from db or dynamic
to create custom api follow my post in How do I get a response from REST API in JSON format in Magento 2?
and do the below changes
in di.xml
<?xml version="1.0"?>
<!--
/**
* Copyright 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<preference for="Magento\Framework\Webapi\ServiceOutputProcessor" type="Sugarcode\Customapi\Model\ServiceOutputProcessor" />
<preference for="Sugarcode\Customapi\Api\TestInterface"
type="Sugarcode\Customapi\Model\Test" />
<preference for="Sugarcode\Customapi\Api\Data\TestdataInterface" type="Sugarcode\Customapi\Model\Testmodel" />
</config>
app\code\Sugarcode\Customapi\Api\TestInterface.php
use @return array (which i not allowed in magento2 default ) that is
<?php
namespace Sugarcode\Customapi\Api;
use Sugarcode\Customapi\Api\Data\TestdataInterface;
interface TestInterface
{
/**
* Retrieve list of info
*
* @throws \Magento\Framework\Exception\NoSuchEntityException If ID is not found
* @return array
*/
public function getinfo();
}
app\code\Sugarcode\Customapi\Model\Test.php
public function getinfo() {
$page_object = $this->dataFactory->create();
$page_object->setName('eee');
$page_object->setExtData(['key'=>'value', 'key2'=>'value2']);
//return $page_object;
return ['name'=>'Test Name','key'=>'value', 'key2'=>'value2',
'multi'=>['name'=>'Test Name','key'=>'value', 'key2'=>'value2']
];
}
app\code\Sugarcode\Customapi\Model\ServiceOutputProcessor.php
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Sugarcode\Customapi\Model;;
/**
* Data object converter for REST
*/
class ServiceOutputProcessor extends \Magento\Framework\Webapi\ServiceOutputProcessor
{
*/
public function process($data, $serviceClassName, $serviceMethodName)
{
/** @var string $dataType */
$dataType = $this->methodsMapProcessor->getMethodReturnType($serviceClassName, $serviceMethodName);
if($dataType == 'array'){
return $data;
}else{
return $this->convertValue($data, $dataType);
}
}
}
if any better solution guy please post
-
Use
mixed
return type instead of introducing newarray
type with custom processing, result should be the same. Commented Dec 22, 2015 at 9:23 -
@ale:- there i no mixed type if i used mixed then through error Commented Dec 22, 2015 at 10:36
-
There is, and it is even used in core already, see
\Magento\Sales\Api\Data\TransactionInterface::setAdditionalInformation
. Also check\Magento\Framework\Reflection\TypeProcessor::ANY_TYPE
. The only difference, in your case it is as@return
, not@param
. Try to specify it for some param, to verify if it works for you in this case. Commented Dec 22, 2015 at 10:39 -
-
2Try
mixed[]
for now. Also consider creating pull request with the proposed improvement on Magento 2 github (\Magento\Framework\Reflection\TypeProcessor::processSimpleAndAnyType
is a good starting point for improving current behavior) Commented Dec 22, 2015 at 11:28
I am using mixed for the time being. It takes an array of objects just fine. I did not need to use the bracket notation indicating an array of things.
@param mixed
-
This actually does not seem to work any more in Magento 2.2. Instead it seems to do a json_encode on your return type to return a string..– ErfanCommented Oct 17, 2017 at 8:30
Although this question is quite old, I was stumbling across the same issue. I solved it by using a new class and define that class in the annotations of the method in the interface.
So ...
Create a new Interface like the file Sugarcode\Customapi\Api\Data\MainDataInterface\InfoListInterface
<?php
namespace Sugarcode\Customapi\Api\Data\MainDataInterface;
interface InfoListInterface
{
/**
* @return string
*/
public function getName();
/**
* @return string
*/
public function getValue();
}
Then your main interface for the data object of the response should look like:
<?php
namespace Sugarcode\Customapi\Api\Data;
interface MainDataInterface
{
/**
* Retrieve list of info
*
* @return \Sugarcode\Customapi\Api\Data\MainDataInterface\InfoListInterface[]
*/
public function getInfo();
/**
* @param array
*/
public function setInfo(array $infoList);
}
Create classes that implement those interfaces.
In your script to populate the data-objects, there should be something like ... (of course that can be realised through various methods)
...
public function receiveInfos() {
...
$infoListArr[] = $infoListFactory->create()
->setData('name','name1')
->setData('value','value1');
$infoListArr[] = $infoListFactory->create()
->setData('name','name2')
->setData('value','value2');
$mainData = $MainDataFactory->create();
$mainData->setInfo($infoListArr);
...
return $mainData;
}
Then for the api-request, you will receive:
{
"info": [
{
"name","name1"
"value","value1"
},
{
"name","name2"
"value","value2"
}
]
}
With this method, you also have a correct swagger documentation, when going on www.yourmagentoshop.com/swagger