Magento2 How to create a custom rest API

Magento2 How to create a custom rest API

Today we will talk about creating a custom REST API for your magento store. Before proceeding we assume you have already created a module and familiar with the magento basics.

Let us begin by creating an interface Vendor\Module\Api\CustomApiInterface.php and add a method getAllPosts() to it.

<?php
namespace Vendor\Module\Api;

/**
 * Custom Api Interface
 */
interface CustomApiInterface
{
    /**
     * Get All Posts.
     *
     * @return array
     */
    public function getAllPosts(): array;
}

Now create CustomApi Model class implementing the CustomApiInterface: Vendor\Module\Model\CustomApi.php

<?php
namespace Vendor\Module\Model;

/**
 * Custom Api Model.
 */
class CustomApi implements \Vendor\Module\Api\CustomApiInterface
{
    /**
     * @inheritDoc
     */
    public function getAllPosts(): array
    {
        return [
            [
                "id" => 1,
                "title" => "My Post 1",
                "categories" => ["my posts", "custom posts"],
                "description" => "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
            ],
            [
                "id" => 2,
                "title" => __("My Post 2"),
                "categories" => ["my posts", "custom post2"],
                "description" => "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
            ],
        ];
    }
}

Now we need to define the preference using di.xml: Vendor\Module\etc\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">
    <preference for="Vendor\Module\Api\CustomApiInterface" type="Vendor\Module\Model\CustomApi" />
</config>

Now our final step will be creating webapi.xml, where we will define our webservice and declare a url to it. Vendor\Module\etc\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 method="GET" url="/V1/custom-api/posts">
        <service class="Vendor\Module\Api\CustomApiInterface" method="getAllPosts"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

The route url will be our path to access the api. Now try accessing it with {base_url}/rest/V1/custom-api/posts. It will list all your posts.

[
    {
        "id": 1,
        "title": "My Post 1",
        "categories": [
            "my posts",
            "custom posts"
        ],
        "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
    },
    {
        "id": 2,
        "title": "My Post 2",
        "categories": [
            "my posts",
            "custom post2"
        ],
        "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
    }
]

Let us get a single post using an id parameter in our request. Declare a new method to the interface and define it inside the model.

{ 
...

    /**
     * Get a post by id
     *
     * @param int $id
     * @return array
     */
    public function getPost(int $id): array;

...
}

You should add PHPDoc annotations in order to follow the DocBlock standards. Read here more about DocBlock standards

Add getPost(int $id) definition inside Vendor\Module\Model\CustomApi.php

{
...

    public function getPost(int $id): array
    {
        $allposts = $this->getAllPosts();
        $post = [];
        foreach ($allposts as $item) {
            if ($id == $item['id']) {
                $post[] = $item;
                break;
            }
        }

        return $post;
    }

...
}

Now add the post route inside Vendor/Module/etc/webapi.xml

...
    <route method="GET" url="/V1/custom-api/post/:id">
        <service class="Vendor\Module\Api\CustomApiInterface" method="getPost"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
...

According to the route url we are specifying id with colon(:) which shows that it is a required parameter and must match with the method parameter. Now the request looks like this:

{base_url}/rest/V1/custom-api/post/1

Here 1 is the value of id parameter. If this value is not provided in request, the url will not match any route.

Below is the output to our new request:

Get Post by Id output

 

We can also change the method type from GET to POST. We usually require POST method to send form input.

Now add a new route using Post method for same service method Vendor/Module/etc/webapi.xml:

...
    <route method="POST" url="/V1/custom-api/get-post/:id">
        <service class="Vendor\Module\Api\CustomApiInterface" method="getPost"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
...

If we try requesting {base_url}/rest/V1/custom-api/get-post/1 using GET or directly from browser, a no route error will be returned by api.

No route found

So Let us change GET to POST and retry request, we will get the correct results.

URL with POST request

The output will be:

POST output

 

Download source code from here

Leave a Reply

Your email address will not be published.