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;
interface CustomApiInterface
{
public function getAllPosts(): array ;
}
|
Now create CustomApi Model class implementing the CustomApiInterface: Vendor\Module\Model\CustomApi.php
<?php
namespace Vendor\Module\Model;
class CustomApi implements \Vendor\Module\Api\CustomApiInterface
{
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" ?>
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" ?>
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.
{
...
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:
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.
So Let us change GET to POST and retry request, we will get the correct results.
The output will be:
Download source code from here