I am creating an API method that I want to send an array of custom JSON items to. I don't want to have a database model behind my JSON object. The JSON is just a way of sending transient data to my API method, and it's not directly backed by any database tables.
Here is the JSON data I'm posting:
{
"stockItems": [
{
"sku": "SKU-1234",
"qty": 15
},
{
"sku": "SKU-5678",
"qty": 25
}
]
}
Here is my custom model and interface:
StockItemInterface.php
namespace MyCompany\CatalogInventory\Api\Data;
/**
* @api
*/
interface StockItemInterface
{
/**
* @return float
*/
public function getQty();
/**
* @return string
*/
public function getSku();
/**
* @param float $qty
* @return $this
*/
public function setQty($qty);
/**
* @param string $sku
* @return $this
*/
public function setSku($sku);
}
Item.php
namespace MyCompany\CatalogInventory\Model\Stock;
use MyCompany\CatalogInventory\Api\Data\StockItemInterface;
class Item implements StockItemInterface
{
protected $sku;
protected $qty;
/**
* @param array $data
*/
public function __construct(array $data = [])
{
}
/**
* @return float
*/
public function getQty()
{
return $this->qty;
}
/**
* @return string
*/
public function getSku()
{
return $this->sku;
}
/**
* @param float $qty
* @return $this
*/
public function setQty($qty)
{
$this->qty = $qty;
}
/**
* @param string $sku
* @return $this
*/
public function setSku($sku)
{
$this->sku = $sku;
}
}
Here's my API method
StockRegistryInterface.php
namespace MyCompany\CatalogInventory\Api;
/**
* Interface StockRegistryInterface
* @api
*/
interface StockRegistryInterface
{
/**
* @param \MyCompany\CatalogInventory\Api\Data\StockItemInterface[] $stockItems
* @return int
*/
public function updateStockItems(array $stockItems);
}
StockRegistry
namespace MyCompany\CatalogInventory\Model;
use Magento\Catalog\Model\ProductFactory;
use Magento\CatalogInventory\Api\Data\StockItemInterface;
use Magento\CatalogInventory\Api\StockConfigurationInterface;
use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory;
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
use Magento\CatalogInventory\Model\Spi\StockRegistryProviderInterface;
use MyCompany\CatalogInventory\Api\StockRegistryInterface;
/**
* Class StockRegistry
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class StockRegistry extends \Magento\CatalogInventory\Model\StockRegistry implements StockRegistryInterface
{
/**
* @param StockConfigurationInterface $stockConfiguration
* @param StockRegistryProviderInterface $stockRegistryProvider
* @param StockItemRepositoryInterface $stockItemRepository
* @param StockItemCriteriaInterfaceFactory $criteriaFactory
* @param ProductFactory $productFactory
*/
public function __construct(
StockConfigurationInterface $stockConfiguration,
StockRegistryProviderInterface $stockRegistryProvider,
StockItemRepositoryInterface $stockItemRepository,
StockItemCriteriaInterfaceFactory $criteriaFactory,
ProductFactory $productFactory
) {
parent::__construct($stockConfiguration, $stockRegistryProvider, $stockItemRepository, $criteriaFactory, $productFactory);
}
/**
* @inheritdoc
*/
public function updateStockItems(array $stockItems)
{
// do stuff
}
}
When I post to my API method, I get this error
"Fatal Error: 'Uncaught Error: Cannot instantiate interface MyCompany\\CatalogInventory\\Api\\Data\\StockItemInterface in
\/var\/www\/magento2\/lib\/internal\/Magento\/Framework\/ObjectManager\/Factory\/AbstractFactory.php:111
Stack trace:
#0 \/var\/www\/magento2\/lib\/internal\/Magento\/Framework\/ObjectManager\/Factory\/Compiled.php(108):
Magento\\Framework\\ObjectManager\\Factory\\AbstractFactory->createObject('MyCompany\\\\CatalogI...', Array)
#1 \/var\/www\/magento2\/lib\/internal\/Magento\/Framework\/ObjectManager\/ObjectManager.php(56):
Magento\\Framework\\ObjectManager\\Factory\\Compiled->create('MyCompany\\\\CatalogI...', Array)
#2 \/var\/www\/magento2\/lib\/internal\/Magento\/Framework\/Webapi\/ServiceInputProcessor.php(166):
Magento\\Framework\\ObjectManager\\ObjectManager->create('\\\\MyCompany\\\\Catalog...')
#3 \/var\/www\/magento2\/lib\/internal\/Magento\/Framework\/Webapi\/ServiceInputProcessor.php(399):
Magento\\Framework\\Webapi\\ServiceInputProcessor->_createFromArray('\\\\MyCompany\\\\Catalog...', Array)
#4 \/var\/www\/magento2\/lib\/internal\/Magento\/Framework\/Webapi\/ServiceInputProcessor.php(332):
' in '\/var\/www\/magento2\/lib\/internal\/Magento\/Framework\/ObjectManager\/Factory\/AbstractFactory.php' on line 111"
The exception is happening in AbstractFactory.createObject
:
protected function createObject($type, $args)
{
return new $type(...array_values($args));
}
The problem is that $args
is an empty array, so array_values
throws an exception.
How do I write my Item
class so that Magento can construct it successfully, and without having a backing database model?