<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rest Api - Moses Dinakaran</title>
	<atom:link href="https://mosesdinakaran.in/category/tutorials/rest-api/feed/" rel="self" type="application/rss+xml" />
	<link>https://mosesdinakaran.in</link>
	<description>Tutorials and Documentations on Magento</description>
	<lastBuildDate>Fri, 21 Oct 2022 03:51:03 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>Magento 2 - How Rest API Response data is Generated</title>
		<link>https://mosesdinakaran.in/magento-2-how-rest-api-response-data-is-generated/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=magento-2-how-rest-api-response-data-is-generated</link>
					<comments>https://mosesdinakaran.in/magento-2-how-rest-api-response-data-is-generated/#respond</comments>
		
		<dc:creator><![CDATA[mosesdinakaran@gmail.com]]></dc:creator>
		<pubDate>Fri, 21 Oct 2022 03:51:01 +0000</pubDate>
				<category><![CDATA[Rest Api]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://mosesdinakaran.in/?p=1486</guid>

					<description><![CDATA[<p>In this blog we will look in to how Magento generates the data for the rest API. When you think of building a Rest API the thing that comes in our mind is generally the below. Url Endpoint Input parameters Json Return Data and the implementation would be some think like the below Create A [&#8230;]</p>
<p>The post <a href="https://mosesdinakaran.in/magento-2-how-rest-api-response-data-is-generated/">Magento 2 - How Rest API Response data is Generated</a> first appeared on <a href="https://mosesdinakaran.in">Moses Dinakaran</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>In this blog we will look in to how Magento generates the data for the rest API.</p>



<p>When you think of building a Rest API the thing that comes in our mind is generally the below.</p>



<ul class="wp-block-list"><li>Url Endpoint</li><li>Input parameters</li><li>Json Return Data</li></ul>



<p>and the implementation would be some think like the below</p>



<ul class="wp-block-list"><li>Create A Route / Controller</li><li>Call the respective Model to get all the data</li><li>Build an array with the relevant data and return as json Response</li></ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
$userID = &quot;Get the Request Parameter Value&quot;;
$user = $userInstane-&gt;getUser($userID);
$userAddresses = $userAddressInstane-&gt;getAddresses($userID);

$data = &#x5B;
    &#039;name&#039; =&gt; $user-&gt;getName(),
    &#039;email&#039; =&gt; $user-&gt;getEmail(),
    &#039;addresses&#039; =&gt; $userAddresses
]

echo json_decode($data);
</pre></div>


<p>With Magento 2, Things are done in a little different manner.</p>



<p>Instead of we gathering the data and echoing the data, We just return a Object.</p>



<p>This returned object will be a usually a API Data Interface where we will have getters and setters method. When this object is returned  Magento calls all the getter methods automatically and returns the data.</p>



<p>For ex, In the below class we have 4 getters, So in the output we will have upto 4 data depends upon what data is set.</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://mosesdinakaran.files.wordpress.com/2022/08/image.png?w=1024" alt="" class="wp-image-87"/></figure>



<p> So to look more in to how Magento 2 does this, First lets create a simple web api.</p>



<h3 class="wp-block-heading">Creating a Web API Involves the Below Steps</h3>



<ol class="wp-block-list"><li>Define the API Endpoint</li><li>Create API Service Class, Usually a repository or the Management Class</li></ol>



<p></p>



<figure class="wp-block-image size-large is-resized"><img fetchpriority="high" decoding="async" src="https://mosesdinakaran.files.wordpress.com/2022/08/image-1.png?w=1024" alt="" class="wp-image-89" width="767" height="262"/></figure>



<p></p>



<h5 class="wp-block-heading">Define the API endpoint</h5>



<p>The Api endpoint is defined in the etc/webapi.xml file</p>



<p>Here we can would define the below details</p>



<ul class="wp-block-list"><li>API Url along with its parameter</li><li>The Service Class which will be initiated on this api call</li><li>ACL</li><li>Api Method</li></ul>



<p>When this rest api url is called, Magento will call the getUser method where we create the instance of the API interface and return the object.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: xml; highlight: [2]; title: ; notranslate">
&lt;route url=&quot;/V1/mosesrest/:userId/user&quot; method=&quot;GET&quot;&gt;
    &lt;service class=&quot;Moses\Rest\Api\UserManagementInterface&quot; method=&quot;getUser&quot;/&gt;
    &lt;resources&gt;
        &lt;resource ref=&quot;anonymous&quot;/&gt;
    &lt;/resources&gt;
&lt;/route&gt;
</pre></div>


<pre class="wp-block-preformatted"></pre>



<h5 class="wp-block-heading">Create Api Interface</h5>



<p>Every rest api will return an object of an api interface. When you create the getter methods of this api class we need to pay attention to 2 things</p>



<h6 class="wp-block-heading"><strong>Method Arguments</strong></h6>



<p>If you need to pass a argument in your api call, Method arguments are used. i.e the method arguments will be automatically mapped to api parameters</p>



<p>In this url "/V1/mosesrest/:userId/user" the data that is passed as :userId will be available as $userId in the getUser method.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
public function getUser(int $userId)
</pre></div>


<h6 class="wp-block-heading">Method return Value and Importance of Doc Block</h6>



<p>Every getter method should define the comment block with the @return param such as</p>



<p>/**<br>* @return string<br>*/</p>



<p>Using the reflection class, Magento uses this definition to decide what kind of data that needs to be returned for that specific getter.</p>



<p>Lets consider the below class that contains 4 getters and setters</p>



<ul class="wp-block-list"><li>Name</li><li>Email</li><li>UserGroups</li><li>Id</li></ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php


namespace Moses\Rest\Api\Data;

/**
 * @api
 * @since 100.0.2
 */
interface UserInterface
{
    const KEY_ID = &#039;id&#039;;
    const KEY_NAME = &#039;name&#039;;
    const KEY_EMAIL = &#039;email&#039;;
    const KEY_USER_GROUPS = &#039;user_groups&#039;;

    /**
     * @return int|null
     */
    public function getId();

    /**
     * @return string|null
     */
    public function getEmail();

    /**
     * @return string
     */
    public function getName();

    /**
     * @return array
     */
    public function getUserGroups();

    /**
     * @param $name
     * @return $this
     */
    public function setName($name);

    /**
     * @param $email
     * @return $this
     */
    public function setEmail($email);

    /**
     * @param $userGroups
     * @return $this
     */
    public function setUserGroups($userGroups);

    /**
     * Set User id
     *
     * @param int $id
     * @return $this
     */
    public function setId($id);
}

</pre></div>


<p>The method that is mapped in the webapi xml creates the object of this class and returns the data to the end user.</p>



<p>Once the api "/rest/V1/mosesrest/1/user" is called, This class \Moses\User\Model\UserManagement::getUser will get called.</p>



<p>Consider we are not setting any data, but just creating the api instance object and returning the object and lets see how the output is</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%"><div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
// Just returning the API interface object not setting any value
public function getUser(int $userId)
{
	$user = $this-&gt;userInterfaceFactory-&gt;create();
	return $user;
}
</pre></div></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%"><div class="wp-block-syntaxhighlighter-code "><pre class="brush: css; title: ; notranslate">
Output:
{
    &quot;name&quot;: null,
    &quot;user_groups&quot;: null
}
</pre></div></div>
</div>



<p>If you notice the output here, Though our object contains four properties we are getting only two properties. The email and id property are missing.</p>



<p>The reason is, because of the DocBlock Definition, In our block definition for getEmail and getId methods we defined "@return int|null" which indicates that this method can return null value also in that case the in the api response output we will not have this keys if the value is not set.</p>



<p>But there may be a scenario where we need to return the email property as null if we are not setting it, So to do it we just need to change the doc block of the Email Method @return as the below</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
/**
 * @return string
 */
public function getEmail();
</pre></div>


<p>The | null is removed.</p>



<p>After changing the doc value, you need to clear the reflection cache</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
php bin/magento cache:clean reflection
</pre></div>


<p>Let have a look closely on how this data is processed</p>



<p>The API Processing starts with </p>



<figure class="wp-block-table"><table><tbody><tr><td><strong>File Path</strong></td><td><strong>Comments</strong></td></tr><tr><td>\Magento\Framework\App\Http::launch<br>$result = $frontController-&gt;dispatch($this-&gt;_request);</td><td><em>Run application</em></td></tr><tr><td>\Magento\Webapi\Controller\Rest::dispatch<br>$processor = $this-&gt;requestProcessorPool-&gt;getProcessor($this-&gt;_request);<br></td><td><em>Handle REST request</em><br><br><em>Based on request decide is it schema request or API request and process accordingly.</em><br><br></td></tr><tr><td>\Magento\Webapi\Controller\Rest\RequestProcessorPool::getProcessor<br><code>foreach ($this-&gt;requestProcessors as $processor) {<br>if ($processor-&gt;canProcess($request)) {<br>return $processor;<br>}<br>}</code><br>Here the Processer for the api is identified based on the api method, type etc</td><td><img decoding="async" src="https://mosesdinakaran.files.wordpress.com/2021/11/image.png?w=1009" alt=""><br><br><img decoding="async" src="https://mosesdinakaran.in/wp-content/uploads/2022/10/image-43.png" alt=""></td></tr><tr><td>For our call, the below method will get initiated <br>\Magento\Webapi\Controller\Rest\SynchronousRequestProcessor::process<br>The Input parameters of the URL are resolved here and the respective service class is identified<br></td><td><br><img decoding="async" src="https://mosesdinakaran.in/wp-content/uploads/2022/10/image-45.png" alt=""></td></tr><tr><td>\Magento\Webapi\Controller\Rest\SynchronousRequestProcessor::process<br>Once the service API class is identified the respective method getUser is called<br><br><br></td><td>$service = Moses\User\Model\UserManagement<br>$$serviceMethodName = getUser<br>$inputParams = {array} [1]<br>0 = {int} 1<br>The input parameter "1" is passed in the api url<br><br><br></td></tr><tr><td>// $service = Moses\Rest\Api\UserManagementInterface<br>// $serviceMethodName = getUser<br>$outputData = call_user_func_array([$service, $serviceMethodName], $inputParams);<br>At this point the $outputData contains the data what exactly we set.<br>We set only id and user_groups and the output is as expected.<br><br>But if you see the final api response we see name:null is returned.<br><br>We didnt set email and name but why only name is returned as null and not email ?<br>This is because of the respective methods return doctype declaration and this is handled in the below method.<br>ServiceOutputProcessor::process<br><br><br>\Magento\Framework\Webapi\ServiceInputProcessor::process<br>Then the Service Method is called<br><br><br></td><td><img decoding="async" src="https://mosesdinakaran.in/wp-content/uploads/2022/10/image-47.png" alt=""></td></tr><tr><td>The above $outputData is passed to <br>\Magento\Framework\Webapi\ServiceOutputProcessor::process<br>$outputData = $this-&gt;serviceOutputProcessor-&gt;process(<br>$outputData,<br>$serviceClassName,<br>$serviceMethodName<br>);<br></td><td>This method does the following<br>Converts the incoming data into scalar or an array of scalars format.<br>If the data provided is null, then an empty array is returned.<br>Otherwise, if the data is an object, it is assumed to be a Data Object and converted to an associative array with keys representing the properties of the<br>Data Object.<br>Nested Data Objects are also converted. If the data provided is itself an array, then we iterate through the contents and convert each piece individually.<br>In our case the Data is Object which is further processed.<br><img decoding="async" src="https://mosesdinakaran.in/wp-content/uploads/2022/10/image-48.png" alt=""><br></td></tr><tr><td>return $this-&gt;processDataObject(<br>$this-&gt;dataObjectProcessor-&gt;buildOutputDataArray($data, $type)<br>);</td><td>In our case the Data is Object which is further processed.</td></tr><tr><td>\Magento\Framework\Reflection\DataObjectProcessor::buildOutputDataArray</td><td><img decoding="async" src="https://mosesdinakaran.in/wp-content/uploads/2022/10/image-49.png" alt=""></td></tr><tr><td>Here we do 2 checks<br>If the method value is NULL<br>If !$isMethodReturnValueRequired<br>In our case, The getEmail will be NULL so let look in to $isMethodReturnValueRequired</td><td><br><br><img decoding="async" src="https://mosesdinakaran.in/wp-content/uploads/2022/10/image-50.png" alt=""></td></tr><tr><td><br><br>Based on just the DOC Block you can see that the isRequired flag is set to true or false<br>and this value determines if we need to return the key "email" in the return value or not.<br></td><td><img decoding="async" src="https://mosesdinakaran.in/wp-content/uploads/2022/10/image-51.png" alt=""></td></tr></tbody></table></figure>



<p></p><p>The post <a href="https://mosesdinakaran.in/magento-2-how-rest-api-response-data-is-generated/">Magento 2 - How Rest API Response data is Generated</a> first appeared on <a href="https://mosesdinakaran.in">Moses Dinakaran</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://mosesdinakaran.in/magento-2-how-rest-api-response-data-is-generated/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
