3

I have a custom field delivery_type in sales_order table. I am accessing order using rest api but this field is not present in response.

Requested api: http://localhost/default/rest/default/V1/orders/2

As suggested here I have added etc/api2.xml with following content in a custom module but it is not making any difference to order response.

<?xml version="1.0"?>
<config>
    <api2>
        <resources>
            <order>
                <attributes>
                    <delivery_type>Delivery Type</delivery_type>
                </attributes>
            </order>
        </resources>
    </api2>
</config>

Edit: If I add this attribute in extension_attributes.xml and sales_order_load_after event as mentioned here I'm able to get this when I load a single order at rest/default/V1/orders/2 but this attribute is not visible in order collection at /rest/default/V1/orders?<search_criteria_here>

3 Answers 3

11
+50

In Magento 2 every API depends on Interface and output of API depends on another interface

in vendor/magento/module-sales/Api/OrderRepositoryInterface.php you can see have a method get which return \Magento\Sales\Api\Data\OrderInterface when you open that file has a method getExtensionAttributes() if that method available then you can add your any attribute in API. So explain step by step

Step 1: You need to create a file in your custom module app/code/Auriga/Addon/etc/extension_attributes.xml (you can implement in your any module)

<?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="custom_attribute" type="string" />
    </extension_attributes>
</config>

Step 2: need to create a file in app/code/Auriga/Addon/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="Auriga\Addon\Plugin\Api\OrderRepository" />
    </type>
</config>

Step 3:as declared in di.xml we need to create a file in OrderRepository.php in /var/www/html/choppingboard/app/code/Auriga/Addon/Plugin/Api/OrderRepository.php

<?php namespace Auriga\Addon\Plugin\Api; class OrderRepository {

public function __construct(\Auriga\Addon\Model\CartCalculation $cartCalculation) {
    $this->cartCalculation = $cartCalculation;
}

public function afterGet(\Magento\Sales\Api\OrderRepositoryInterface $subject, $entity) {

    $extensionAttributes = $entity->getExtensionAttributes ();

    
    if ($extensionAttributes) {
        $extensionAttributes->setCustomAttribute ( 'custom_value' );
        $entity->setExtensionAttributes ( $extensionAttributes );
    }
    return $entity;
}}

Step 4 : need to run "php bin/magento setup:upgrade"

And you can check a customer_attribute node is avablible in result Now open BASE_URL/rest/default/V1/orders/2

enter image description here

3
  • Hi Prince, it's visible when I load a particular order but not visible when I load the order collection using search criteria. Please check question edit.
    – amitshree
    Jul 30, 2018 at 8:41
  • Hi amitshree, that's correct its working or not. Can you send complete URL of search order collection and I have a query may be you know about how can version control of API in Magento 2 Jul 30, 2018 at 17:06
  • Hi Prince, I have added the solution. Please check my answer. I had to extend getList method for order collection.
    – amitshree
    Jul 30, 2018 at 17:39
9

I was able to get it working as Prince suggested here for individual order. Though if you want to show this attribute in order collection as well you have to modify getList method also. Here is the complete solution:

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;
    }
}
4
0

You have to add the attribute to this file in your extension (extension_attributes.xml)

after that you have to sales_order_load_order_attribute event to set the attribute value

there is an article with more details in this blog

https://www.wikicoode.com/magento2/add-order-attribute-custom-attributes-magento-2-rest-api

1
  • I have followed that process. Extension attribute is visible when I load one order but when I load order collection that attribute is not visible. Do you know how I can make it visible in order collection?
    – amitshree
    Jul 29, 2018 at 12:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.