How to expose a custom field from the sales_order table to the rest api?

Suppose you have a custom field delivery_type in the sales_order table.  You are accessing order using rest Api but this field is not present in the response.

Requested API: http://localhost/default/rest/default/V1/orders/{order_id}

You can get it working for individual orders. Though if you want to show this attribute in order collection as well you have to modify getList the method also.

You have to create a custom module. 

etc/extension_attributes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Sales\Api\Data\OrderInterface">
        <attribute code="delivery_type" type="string" />
    </extension_attributes>
</config>

etc/webapi_rest/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">
    <type name="Magento\Sales\Api\OrderRepositoryInterface">
        <plugin name="orderInformationUpdate" type="Vendor\Module\Plugin\Api\OrderRepository" />
    </type>
</config>

Plugin/Api/OrderRepository.php

?php
 
namespace Vendor\Module\Plugin\api;
 
use Magento\Sales\Api\Data\OrderExtensionFactory;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Api\Data\OrderSearchResultInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
 
 
class OrderRepository
{
 
    const DELIVERY_TYPE = 'delivery_type';
 
    /**
     * Order Extension Attributes Factory
     *
     * @var OrderExtensionFactory
     */
    protected $extensionFactory;
 
    /**
     * OrderRepositoryPlugin constructor
     *
     * @param OrderExtensionFactory $extensionFactory
     */
    public function __construct(OrderExtensionFactory $extensionFactory)
    {
        $this->extensionFactory = $extensionFactory;
    }
 
    /**
     * Add "delivery_type" extension attribute to order data object to make it accessible in API data
     *
     * @param OrderRepositoryInterface $subject
     * @param OrderInterface $order
     *
     * @return OrderInterface
     */
    public function afterGet(OrderRepositoryInterface $subject, OrderInterface $order)
    {
        $deliveryType = $order->getData(self::DELIVERY_TYPE);
        $extensionAttributes = $order->getExtensionAttributes();
        $extensionAttributes = $extensionAttributes ? $extensionAttributes : $this->extensionFactory->create();
        $extensionAttributes->setDeliveryType($deliveryType);
        $order->setExtensionAttributes($extensionAttributes);
 
        return $order;
    }
 
    /**
     * Add "delivery_type" extension attribute to order data object to make it accessible in API data
     *
     * @param OrderRepositoryInterface $subject
     * @param OrderSearchResultInterface $searchResult
     *
     * @return OrderSearchResultInterface
     */
    public function afterGetList(OrderRepositoryInterface $subject, OrderSearchResultInterface $searchResult)
    {
        $orders = $searchResult->getItems();
 
        foreach ($orders as &$order) {
            $deliveryType = $order->getData(self::DELIVERY_TYPE);
            $extensionAttributes = $order->getExtensionAttributes();
            $extensionAttributes = $extensionAttributes ? $extensionAttributes : $this->extensionFactory->create();
            $extensionAttributes->setDeliveryType($deliveryType);
            $order->setExtensionAttributes($extensionAttributes);
        }
 
        return $searchResult;
    }
}

Through this custom module, the custom field on the sales order table will be available on the order rest API.

Thak you.

Leave a comment

Your email address will not be published. Required fields are marked *