I create a custom entity and repository. All work well, but the POST API route does not create new entities. But if I call the PUT API route to change a property, it works well. Why my custom repository doesn't create new entities?
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">
<route url="/V1/shipment_methods" method="GET">
<service class="MyVendorName\MyModuleName\Api\ShipmentMethodRepositoryInterface" method="getList"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
<route url="/V1/shipment_methods/:code" method="GET">
<service class="MyVendorName\MyModuleName\Api\ShipmentMethodRepositoryInterface" method="getByCode"/>
<resources>
<resource ref="MyVendorName_MyModuleName::shipment_method"/>
</resources>
</route>
<route url="/V1/shipment_methods" method="POST">
<service class="MyVendorName\MyModuleName\Api\ShipmentMethodRepositoryInterface" method="save"/>
<resources>
<resource ref="MyVendorName_MyModuleName::shipment_method_save"/>
</resources>
</route>
<route url="/V1/shipment_methods/:code" method="PUT">
<service class="MyVendorName\MyModuleName\Api\ShipmentMethodRepositoryInterface" method="save"/>
<resources>
<resource ref="MyVendorName_MyModuleName::shipment_method_save"/>
</resources>
</route>
<route url="/V1/shipment_methods" method="DELETE">
<service class="MyVendorName\MyModuleName\Api\ShipmentMethodRepositoryInterface" method="delete"/>
<resources>
<resource ref="MyVendorName_MyModuleName::shipment_method_delete"/>
</resources>
</route>
<route url="/V1/shipment_methods/:code" method="DELETE">
<service class="MyVendorName\MyModuleName\Api\ShipmentMethodRepositoryInterface" method="deleteByCode"/>
<resources>
<resource ref="MyVendorName_MyModuleName::shipment_method_delete"/>
</resources>
</route>
</routes>
ShipmentMethodRepository
<?php
declare(strict_types=1);
namespace MyVendorName\MyModuleName\Model;
use MyVendorName\MyModuleName\Api\Data\ShipmentMethodInterface;
use MyVendorName\MyModuleName\Api\Data\ShipmentMethodSearchResultsInterface;
use MyVendorName\MyModuleName\Api\ShipmentMethodRepositoryInterface;
use MyVendorName\MyModuleName\Model\ResourceModel\ShipmentMethod as ShipmentMethodResourceModel;
use Magento\Framework\Api\SearchCriteriaInterface;
use Magento\Framework\Exception\CouldNotDeleteException;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\NoSuchEntityException;
class ShipmentMethodRepository implements ShipmentMethodRepositoryInterface
{
/**
* @var ShipmentMethodFactory
*/
private $shipmentMethodFactory;
/**
* @var ShipmentMethodResourceModel
*/
private $shipmentMethodResourceModel;
/**
* ShipmentMethodRepository constructor.
* @param ShipmentMethodFactory $shipmentMethodFactory
* @param ShipmentMethodResourceModel $shipmentMethodResourceModel
*/
public function __construct(
ShipmentMethodFactory $shipmentMethodFactory,
ShipmentMethodResourceModel $shipmentMethodResourceModel
) {
$this->shipmentMethodFactory = $shipmentMethodFactory;
$this->shipmentMethodResourceModel = $shipmentMethodResourceModel;
}
/**
* Retrieve shipment methods which match a specified criteria
* @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
* @return \MyVendorName\MyModuleName\Api\Data\ShipmentMethodSearchResultsInterface
*/
public function getList(SearchCriteriaInterface $searchCriteria): ShipmentMethodSearchResultsInterface
{
// TODO: Implement getList() method.
}
/**
* Get shipment method by code
* @param string $code
* @return \MyVendorName\MyModuleName\Api\Data\ShipmentMethodInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function getByCode(string $code): ShipmentMethodInterface
{
$shipmentMethod = $this->shipmentMethodFactory->create();
$this->shipmentMethodResourceModel->load($shipmentMethod, $code);
if (!$shipmentMethod->getCode()) {
throw new NoSuchEntityException(__('Shipment method with code %1 does not exist.', $code));
}
return $shipmentMethod;
}
/**
* Create or update a shipment method
* @param \MyVendorName\MyModuleName\Api\Data\ShipmentMethodInterface $shipmentMethod
* @return \MyVendorName\MyModuleName\Api\Data\ShipmentMethodInterface
* @throws \Magento\Framework\Exception\CouldNotSaveException
*/
public function save(ShipmentMethodInterface $shipmentMethod): ShipmentMethodInterface
{
try {
$this->shipmentMethodResourceModel->save($shipmentMethod);
} catch (\Exception $e) {
throw new CouldNotSaveException(__($e->getMessage()));
}
return $shipmentMethod;
}
/**
* Delete shipment method
* @param \MyVendorName\MyModuleName\Api\Data\ShipmentMethodInterface $shipmentMethod
* @return bool
* @throws \Magento\Framework\Exception\CouldNotDeleteException
*/
public function delete(ShipmentMethodInterface $shipmentMethod): bool
{
try {
$this->shipmentMethodResourceModel->delete($shipmentMethod);
} catch (\Exception $e) {
throw new CouldNotDeleteException(__($e->getMessage()));
}
return true;
}
/**
* Delete shipment method by code
* @param string $code
* @return bool
* @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \Magento\Framework\Exception\CouldNotDeleteException
*/
public function deleteByCode(string $code): bool
{
return $this->delete($this->getByCode($code));
}
}
di.xml
<preference for="MyVendorName\MyModuleName\Api\Data\ShipmentMethodInterface" type="MyVendorName\MyModuleName\Model\ShipmentMethod"/>
<preference for="MyVendorName\MyModuleName\Api\ShipmentMethodRepositoryInterface" type="MyVendorName\MyModuleName\Model\ShipmentMethodRepository"/>
Model\ShipmentMethod
<?php
declare(strict_types=1);
namespace MyVendorName\MyModuleName\Model;
use MyVendorName\MyModuleName\Api\Data\ShipmentMethodInterface;
use MyVendorName\MyModuleName\Model\ResourceModel\ShipmentMethod as ShipmentMethodResourceModel;
use Magento\Framework\Model\AbstractModel;
class ShipmentMethod extends AbstractModel implements ShipmentMethodInterface
{
/**
* {@inheritDoc}
*/
protected function _construct(): void
{
$this->_init(ShipmentMethodResourceModel::class);
}
/**
* {@inheritDoc}
*/
public function getCode(): string
{
return (string)$this->getData(self::CODE);
}
/**
* {@inheritDoc}
*/
public function setCode(string $code): ShipmentMethodInterface
{
$this->setData(self::CODE, $code);
return $this;
}
/**
* {@inheritDoc}
*/
public function getDescription(): string
{
return (string)$this->getData(self::DESCRIPTION);
}
/**
* {@inheritDoc}
*/
public function setDescription(string $description): ShipmentMethodInterface
{
$this->setData(self::DESCRIPTION, $description);
return $this;
}
/**
* {@inheritDoc}
*/
public function getCourierCode(): string
{
return (string)$this->getData(self::COURIER_CODE);
}
/**
* {@inheritDoc}
*/
public function setCourierCode(string $courierCode): ShipmentMethodInterface
{
$this->setData(self::COURIER_CODE, $courierCode);
return $this;
}
/**
* {@inheritDoc}
*/
public function getServiceCode(): string
{
return (string)$this->getData(self::SERVICE_CODE);
}
/**
* {@inheritDoc}
*/
public function setServiceCode(string $serviceCode): ShipmentMethodInterface
{
$this->setData(self::SERVICE_CODE, $serviceCode);
return $this;
}
/**
* {@inheritDoc}
*/
public function getIsExpress(): bool
{
return (bool)$this->getData(self::IS_EXPRESS);
}
/**
* {@inheritDoc}
*/
public function setIsExpress(bool $isExpress): ShipmentMethodInterface
{
$this->setData(self::IS_EXPRESS, $isExpress);
return $this;
}
/**
* {@inheritDoc}
*/
public function getTiming(): string
{
return (string)$this->getData(self::TIMING);
}
/**
* {@inheritDoc}
*/
public function setTiming(string $timing): ShipmentMethodInterface
{
$this->setData(self::TIMING, $timing);
return $this;
}
}
Model\ResourceModel\ShipmentMethod
<?php
declare(strict_types=1);
namespace MyVendorName\MyModuleName\Shipment\Model\ResourceModel;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
class ShipmentMethod extends AbstractDb
{
public const TABLE_NAME = 'my_shipment_method';
/**
* {@inheritDoc}
*/
protected function _construct(): void
{
$this->_init(self::TABLE_NAME, 'code');
}
}
ShipmentMethod
object that I return after try-catch. I checked the logs, and there aren't any errors