I am assuming that AppFactory\Core\Api\SettingInterface::get()
is a REST endpoint. In that case in phpdoc comments you need to define what this will return. Magento REST handler will take that value and process it to remove all data that are unnecessary. What's left will be encoded into JSON so in javascript you can retrieve it as already proper JS hash and not json-encoded string.
The trick about those endpoint is that you need to define very precisely what will you return. Magento will not be able to process something as general as "array" where you will set whatever you like.
In your case, in order not to try playing with array of strings, it will be easier to create an interface that your endpoint will return.
<?php
namespace AppFactory\Core\Api;
/**
* @api
*/
interface SettingsInterface
{
/**
* @return Data\SettingsInterface
*/
public function get();
}
Now when you return an instance of an object implementing that interface Magento will read its phpdocs and will process their return values.
Now create a file in AppFactory\Core\Api\Data\SettingsInterface
as follows
<?php
namespace AppFactory\Core\Api\Data;
interface SettingsInterface
{
/**
* @return int[]
**/
public function getSettings();
/**
* @return string[]
**/
public function getExtra();
}
Now when you create actual class that will implement those 2 get methods and you will return it in AppFactory\Core\Api\SettingsInterface::get()
then magento will return something like
{
"settings": [1, 2, 5],
"extra": ["my","array","of","strings"]
}
If you want another level you need to create another interface which will keep settings
structure and add it as a return value for AppFactory\Core\Api\Data\SettingsInterface::getSettings()
.
If you need to have something that will be dynamic and you do not want or can't prepare this structure interface then you can try setting json-encoded string and place @return string
for any of the fields. This way however you will have to make sure to manually decode that string after receiving the response as then your response will look like this:
{
"settings": [1, 2, 5],
"extra": "{\"test\":\"string\",\"value\":8}"
}
and in order to use response.extra.test
you will have to first do response.extra = JSON.parse(response.extra);
manually
I hope you don't have the intention to "hack" Magento core files. I recommend to create your own classes / interfaces for that!
Anyway if you are implementing a custom method updateStockItems
for a webapi which updates more stockitems with a single request you should take care of the right method signature: You are expecting an array of stock items, therefore your input parameter should be of that type.
Your interface:
/**
*
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface[] $stockItems
* @return int
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function updateStockItems(\Magento\CatalogInventory\Api\Data\StockItemInterface[] $stockItems);
Your method implementation:
/**
*
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface[] $stockItems
* @return int
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function updateStockItems(\Magento\CatalogInventory\Api\Data\StockItemInterface[] $stockItems)
{
foreach ($stockItems as $stockItem){
//do whatever with your stock item
}
};
Please take care to use only parameter in your JSON objects which match the used interfaces, in this example \Magento\CatalogInventory\Api\Data\StockItemInterface
. So putting there some key sku
doesn't make sense and should either be ignored by Magento or give you an error in the API call.
Here is the documentation about the usage of custom webservices.
https://devdocs.magento.com/guides/v2.3/extension-dev-guide/service-contracts/service-to-web-service.html
Best Answer
Problem Summary: You have a PHP Array and you want to return it as a JSON Object. When you return your PHP Array, it gets converted to a JSON Array, which does not support non-sequential keys. So your keys get ignored and you end up with a sequential array of your values.
Solution Summary: You need to return a PHP Object in order to have a JSON Object in your response.
Solution Example
Please check following example that returns a sample Components object.
/Api/Data/ComponentsInterface.php
/Api/ComponentsManagamentInterface.php
/etc/webapi.xml
/Model/Components.php
/Model/ComponentsManagement.php
/etc/di.xml
With above example, when you
GET
http://magento/rest/V1/components
it will return following JSON Object: