Create custom REST API for Magento 2

Posted on 8 June, 2019

In this technical note, we are going to learn how to create and configure custom API (Application Program Interface) in our module. Magento is by default providing all the API like Product API, Order API, Customer data API, etc. These all API has multiple methods like GET, PUT, POST, etc. But if we add any custom fields or want to manage different data, then Magento API does not fulfill our requirement. So for that, we need to create our custom API through which we can manage our custom data and fields.

Before we create API, we need admin Access Token for accessing Magento. You can directly create your new Access Token from this path:

System > Extensions > Integrations

Now, follow the below steps to create a Custom API module:

Step 1: Create the registration.php file in /app/code/Emipro/Customapi folder and paste the below code:

1
2
3
4
5
6
7
8
9
10
<?php
/**
 * Copyright © Emipro Technologies Pvt Ltd. All rights reserved.
 */
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Emipro_Customapi',
    __DIR__
);

Step 2: Create the module.xml file in /app/code/Emipro/Customapi/etc folder and paste the below code:

1
2
3
4
5
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="Emipro_Customapi" setup_version="1.0.0" active="true">
    </module>
</config>

Follow the below steps for GET method API:

Step 1: Create the webapi.xml file in the /app/code/Emipro/Customapi/etc folder and paste the below code:

1
2
3
4
5
6
7
8
9
<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
    <route url="/V1/gethighlight/:sku" method="GET">
        <service class="Emipro\Customapi\Api\Gethighlight" method="gethighlightdata"/>
        <resources>
            <resource ref="admin"/>
        </resources>
    </route>
</routes>

Step 2: Create the di.xml file in /app/code/Emipro/Customapi/etc/ for API Interface file. So, paste the below code:

1
2
3
4
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <preference for="Emipro\Customapi\Api\Gethighlight" type="Emipro\Customapi\Model\Gethighlightdata" />
</config>

Step 3: Define gethighlightdata() method in the interface file. Create Gethighlight.php file in the /app/code/Emipro/Customapi/Api/ folder and paste the below code:

1
2
3
4
5
6
7
8
9
10
11
<?php
namespace Emipro\Customapi\Api;
interface Gethighlight
{
    /**
     * @api
     * @param string $sku
     * @return array
     */
    public function gethighlightdata($sku);
}

Define new functions in the API file and create that function in the model file.

Step 4: Define gethighlightdata() in model file. Create Gethighlightdata.php file in the /app/code/Emipro/Customapi/Model/ folder and paste the below code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
namespace Emipro\Customapi\Model;
use Emipro\Customapi\Api\Gethighlight;
use Magento\Catalog\Model\ProductFactory;
class Gethighlightdata implements Gethighlight
{
    protected $productFactory;
    public function __construct(
        ProductFactory $productFactory
    ) {
        $this->productFactory = $productFactory;
    }
    public function gethighlightdata($sku)
    {
        $productId = $this->resolveProductId($sku);
        if (is_numeric($productId)) {
            $mainarray = [];
            $ary_response = [];
            $valid = [
                "code" => "200",
                "sku" => $sku,
                "product_id" => $productId
            ];
            $ary_response[] = $valid;
        } else {
            $ary_response[] = $productId;
        }
        return $ary_response;
    }
    /**
     * @param string $productSku
     * @return int
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    protected function resolveProductId($productSku)
    {
        $product = $this->productFactory->create();
        $productId = $product->getIdBySku($productSku);
        if (!$productId) {
            $invalid = ["code" => '301', "message" => "SKU " . $productSku . " Not Found On Magento"];
            return $invalid;
        }
        return $productId;
    }
}

NOTE: To test this API, Configure appropriate data in Postman like:

URL: BASE_URL/rest/V1/gethighlight/{SKU}

Method: GET

Headers:
Authorization => Bearer "YOUR ACCESS TOKEN"
Content-Type => application/json

The expected result in body is as below. I am using {SKU} = 24-MB01

1
2
3
4
5
6
7
[
    {
        "code": "200",
        "sku": "24-MB01",
        "product_id": "1"
    }
]

If there is any error or product does not exist, then you will get below result. I am using {SKU} = 24-B06.

1
2
3
4
5
6
[
    {
        "code": "301",
        "message": "SKU 24-B06 Not Found On Magento"
    }
]

Follow the below steps for POST method API:

Step 1: Create the webapi.xml file in the /app/code/Emipro/Customapi/etc/ folder and paste the below code:

1
2
3
4
5
6
7
8
9
<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
    <route url="/V1/highlight" method="POST">
        <service class="Emipro\Customapi\Api\Highlight" method="update"/>
        <resources>
            <resource ref="admin"/>
        </resources>
    </route>
</routes>

Step 2: Create the di.xml file in /app/code/Emipro/Customapi/etc/ for API Interface file and paste the below code:

1
2
3
4
5
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <preference for="Emipro\Customapi\Api\Highlight" type="Emipro\Customapi\Model\Highlightadd" />
    <preference for="Emipro\Customapi\Api\Data\Highlight" type="Emipro\Customapi\Model\Highlightdata" />
</config>

Step 3: Define update() method in the interface file. Create Gethighlight.php file in the /app/code/Emipro/Customapi/Model/ folder and paste the below code.

1
2
3
4
5
6
7
8
9
10
11
<?php
namespace Emipro\Customapi\Api;
interface Highlight
{
    /**
     * @api
     * @param \Emipro\Customapi\Api\Data\Highlight[] $highlightData
     * @return array
     */
    public function update($highlightData);
}

Step 4: Define update() in model file. Create Highlightadd.php file in the /app/code/Emipro/Customapi/Model/ folder and paste the below code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
namespace Emipro\Customapi\Model;
use Emipro\Customapi\Api\Highlight;
use Magento\Catalog\Model\ProductFactory;
class Highlightadd implements Highlight
{
    protected $productFactory;
    public function __construct(
        ProductFactory $productFactory
    ) {
        $this->productFactory = $productFactory;
    }
    public function update($highlightData)
    {
        $ary_response = [];
        foreach ($highlightData as $value) {
            $productSku = $value->getSku();
            $productId = $this->resolveProductId($productSku);
            if (is_numeric($productId)) {
                $valid = [
                    "code" => "200",
                    "message" => "Record saved successfully.",
                    "sku" => $productSku,
                    "title" => $value->getTitle(),
                ];
                $ary_response[] = $valid;
            } else {
                $ary_response[] = $productId;
            }
        }
        return $ary_response;
    }
    /**
     * @param string $productSku
     * @return int
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    protected function resolveProductId($productSku)
    {
        $product = $this->productFactory->create();
        $productId = $product->getIdBySku($productSku);
        if (!$productId) {
            $invalid = ["code" => '301', "message" => "SKU " . $productSku . " Not Found On Magento"];
            return $invalid;
        }
        return $productId;
    }
}

Step 5: In /app/code/Emipro/Customapi/Api/Data/Highlight.php  place the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
namespace Emipro\Customapi\Api\Data;
interface Highlight
{
    const SKU = 'sku';
    const TITLE = 'title';
    /**
     * Gets the sku.
     *
     * @api
     * @return string
     */
    public function setSku($sku);
    /**
     * Gets the sku.
     *
     * @api
     * @return string
     */
    public function getSku();
    /**
     * Gets the title.
     *
     * @api
     * @return string
     */
    public function setTitle($title);
    /**
     * Gets the title.
     *
     * @api
     * @return string
     */
    public function getTitle();
}

Step 6: In /app/code/Emipro/Customapi/Model/Highlightdata.php place the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
namespace Emipro\Customapi\Model;
class Highlightdata implements \Emipro\Customapi\Api\Data\Highlight
{
    protected $sku;
    protected $title;
    /**
     * Gets the sku.
     *
     * @api
     * @return string
     */
    public function setSku($sku)
    {
        $this->sku = $sku;
    }
    /**
     * Gets the sku.
     *
     * @api
     * @return string
     */
    public function getSku()
    {
        return $this->sku;
    }
    /**
     * Gets the title.
     *
     * @api
     * @return string
     */
    public function setTitle($title)
    {
        $this->title = $title;
    }
    /**
     * Gets the title.
     *
     * @api
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    }
}

NOTE: Now, to test this API, Configure appropriate data in Postman.

URL: BASE_URL/rest//V1/highlight

Method: POST

Headers:
Authorization => Bearer "YOUR ACCESS TOKEN"
Content-Type => application/json

Body:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
    "highlightData":
    [
        {
            "sku":"24-MB04",
            "title":"title - 1"
        },
        {
            "sku":"24-WB04",
            "title":"title - 2"
        }
    ]
}

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
    {
        "code": "200",
        "message": "Record saved successfully.",
        "sku": "24-MB04",
        "title": "title - 1"
    },
    {
        "code": "200",
        "message": "Record saved successfully.",
        "sku": "24-WB04",
        "title": "title - 2"
    }
]

NOTE: You will get all the data in update(), which you added in Body. You will get that data as an array format. So after getting all the data, you can do any process on that data. Add your logic there, and it will fulfill your requirement.

I hope this Magento technical note helped you to understand API in Magento 2. If you have any questions or comments, feel free to post in the comment section.


Angel Patel , eCommerce Engineer

Magento Technical Notes

About Emipro

Being an emerging leader in IT market since 2011, Emipro Technologies Pvt. Ltd. has been providing a wide range of business solutions in Odoo & Magento. We are pleased to have a large pool of contented customers with our meticulous work in the domain of ERP & e-Commerce. Our customers are companies of all sizes ranging from startups to large enterprises who realize that they need a professional internet solution to generate revenue streams, establish proper communication channels, to achieve desired goals and streamline business operations. [....] Read More

Our writings seems informative ?

Subscribe for our Magento Technical Notes and get more amazing stuff directly to your inbox!

Post Your Review

X

Your Review has been posted

2 Comment(s)

Praveen Chelumalla

Posted on 20 August, 2019

Nice article for rest API thank you.

Rakesh

Posted on 23 July, 2019

Very helpful!!! Regards,