<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/r-plus-magento-2-rest-api-revisited-part-1-authentication-and-universal-search/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://levashov.biz/r-plus-magento-2-rest-api-revisited-authentication-and-universal-search-part-one/"> R – Alex Levashov – eCommerce Consultant (Melbourne, Australia)</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>I wrote a <a rel="nofollow" href="https://levashov.biz/accessing-magento-2-rest-api-r/" target="_blank">post</a> about getting Magento 2 data to R using REST API last year. Now I provide more examples of use and a wrapper over API that you can re-use to get data from Magento 2 to R in a bit more convenient way.</p>
<h2>Prerequisites</h2>
<h3>Magento 2</h3>
<p>I assume you have admin access to Magento 2 store where you want to pull data from. You’ll need to create API user with access to the resources you plan to query.  You need to write down:</p>
<ul>
<li>Store URL (top level, where Magento app sits)</li>
<li>API user username</li>
<li>API user password</li>
</ul>
<h3>R</h3>
<p>We used the next R packages:</p>
<ul>
<li>httr – essential for work with API</li>
<li>jsonlite -to work with JSON data</li>
<li>dplyr – for some data manipulation in samples later (not in this post). Not essential one, if you prefer to use something else, but nice to have</li>
</ul>
<h2>Authentication</h2>
<p>For ease of reuse let’s define a function that will get a token. We have to pass that token with most API requests.</p>
<p><code>getm2authtoken &lt;- function (url, username, password){<br>
myquery = list (username=username, password=password)<br>
url &lt;- paste0(urlbase, &quot;index.php/rest/V1/integration/admin/token&quot;)<br>
myqueryj = toJSON(myquery, pretty = TRUE, auto_unbox = TRUE)<br>
req &lt;- POST(url, add_headers (&quot;Content-Type&quot; = &quot;application/json&quot;),  body = myquery, encode = &quot;json&quot;)<br>
token &lt;-rawToChar(req$content[2:33])<br>
auth &lt;- paste0(&quot;Bearer &quot;, token)<br>
return (auth)<br>
}</code></p>
<p>Define your Magento API connection</p>
<p><code>urlbase &lt;- &quot;https://yourdomain.com.au/&quot;<br>
username &lt;- &quot;user&quot;<br>
password &lt;- &quot;password&quot;</code></p>
<p>Now we can call the function and save the token for future use</p>
<p><code>auth &lt;- getm2authtoken (urlbase, username, password)</code></p>
<p>If you print <em>auth</em> you should get something like <code>[1] &quot;Bearer 9r8ish02l5zz372ivp7rt8tzndd123yk&quot;</code> as a value if it works correctly.</p>
<h2>Universal search</h2>
<p>Now define function that does universal search in Magento 2 data.</p>
<p><code>getm2objects &lt;- function(urlbase, endpoint, query, auth){<br>
url &lt;- paste0(urlbase, endpoint, &quot;?&quot;)<br>
request &lt;- GET(url, add_headers (&quot;Content-Type&quot; = &quot;application/json&quot;, &quot;Authorization&quot; = auth), query = query)<br>
object &lt;- content(request, as =&quot;parsed&quot;)<br>
return (object)<br>
}</code></p>
<p>The function has the next parameters:</p>
<ul>
<li><strong>urlbase</strong> – base URL of your Magento store, similar with you used for authentication function. Typically your domain. Important to have trailing slash!</li>
<li><strong>endpoint</strong> – specific Magento 2 REST API endpoint.  Skip first slash in the endpoint. You may find some endpoints in the examples below, all of them available in <a rel="nofollow" href="https://devdocs.magento.com/guides/v2.2/rest/list.html" target="_blank">Magento  2 Documentation</a></li>
<li><strong>query</strong> – your search query. It is list of triplets and pairs of parameters, which is explained below and in the examples</li>
<li><strong>auth</strong> is authentication token we’ve already got and saved</li>
</ul>
<h3>Query</h3>
<p>The simplest case of query is a list with 3 name-value pairs:</p>
<p><code>myquery &lt;- list(&quot;searchCriteria[filter_groups][0][filters][0][field]&quot;=&quot;created_at&quot;,<br>
&quot;searchCriteria[filter_groups][0][filters][0][value]&quot;=&quot;2017-01-01 00:00:00&quot;,<br>
&quot;searchCriteria[filter_groups][0][filters][0][condition_type]&quot;=&quot;gt&quot;)</code></p>
<p>The query above look for all data created later than specified date (01-01-2017).</p>
<p>Third pair is condition, where ‘gt’ means ‘greater than’</p>
<p>You may find all possible conditions and sample use in general (not R specific) in <a rel="nofollow" href="https://devdocs.magento.com/guides/v2.2/rest/performing-searches.html" target="_blank">Magento Documentation</a>.</p>
<h3>Examples of using universal search</h3>
<h4>Simple search – invoices issued after given date/time</h4>
<p>Define parameters, here and later we assume that authentication is stored in ‘auth’ variable.</p>
<p><code>endpoint &lt;- &quot;rest/V1/invoices&quot;<br>
# query<br>
myquery &lt;- list(&quot;searchCriteria[filter_groups][0][filters][0][field]&quot;=&quot;created_at&quot;,<br>
&quot;searchCriteria[filter_groups][0][filters][0][value]&quot;=&quot;2017-01-01 00:00:00&quot;,<br>
&quot;searchCriteria[filter_groups][0][filters][0][condition_type]&quot;=&quot;gt&quot;)</code></p>
<p>Calling function</p>
<p><code>invoices &lt;- getm2objects(urlbase = urlbase, endpoint = endpoint, query = myquery, auth=auth)</code></p>
<p>The resulting object is a complex list with many levels of nesting that stores data from many Magento 2 database tables.</p>
<p><img sizes="(max-width: 532px) 100vw, 532px" src="https://i0.wp.com/levashov.biz/wp-content/uploads/2018/11/invoices.png?w=450&ssl=1" alt="Magento Invoices as R list screenshot" class="wp-image-790" data-wp-pid="790" data-recalc-dims="1"></p>
<p>It looks complex enought and there is no surprise. But having all this data in one object is <strong>one of the reason to use API over direct query to SQL</strong>. If you have tried the latter you know that it may be extremely complex because Magento has hundreds of tables with complex relationships.</p>
<h4>Search with OR logic and wildcard use in products</h4>
<p>In this example we’ll use 2 search conditions – look for products those name include either ‘Dress’ or ‘Throw’</p>
<p><code>endpoint &lt;- &quot;rest/V1/products&quot;<br>
myquery &lt;- list(&quot;searchCriteria[filter_groups][0][filters][0][field]&quot;=&quot;name&quot;,<br>
&quot;searchCriteria[filter_groups][0][filters][0][value]&quot;=&quot;%Dress%&quot;,<br>
&quot;searchCriteria[filter_groups][0][filters][0][condition_type]&quot;=&quot;like&quot;,<br>
&quot;searchCriteria[filter_groups][0][filters][1][field]&quot;=&quot;name&quot;,<br>
&quot;searchCriteria[filter_groups][0][filters][1][value]&quot;=&quot;%Throw%&quot;,<br>
&quot;searchCriteria[filter_groups][0][filters][1][condition_type]&quot;=&quot;like&quot;)</code></p>
<p>Note that we have 2 triplets of criteria, one per product name and the second has 1 in search criteria group.</p>
<p>Also percentage char used to indicate that there may be any number of characters before and after both terms. That syntax comes from SQL and other SQL wildcards can be used</p>
<p>Now call the function</p>
<p><code>products &lt;- getm2objects(urlbase = urlbase, endpoint = endpoint, query = myquery, auth=auth)</code></p>
<p>The resulting list contains all the products with either “Dress” or “Throw” in name. Register ignored.</p>
<p>To quickly check how many results in the list use the next command</p>
<p><code>products[[&quot;total_count&quot;]]</code></p>
<p>It returns number of search results founds.</p>
<h4>Logical AND and OR search with invoices</h4>
<p>Let’s get invoices for certain period of time and for specific grand total amounts above OR below certain thresholds</p>
<p><code># get invoices for 2013 year and for any time with grand total under $100 OR over $1000<br>
endpoint &lt;- &quot;rest/V1/invoices&quot;<br>
myquery &lt;- list(&quot;searchCriteria[filter_groups][0][filters][0][field]&quot;=&quot;created_at&quot;,<br>
&quot;searchCriteria[filter_groups][0][filters][0][value]&quot;=&quot;2013-01-01 00:00:00&quot;,<br>
&quot;searchCriteria[filter_groups][0][filters][0][condition_type]&quot;=&quot;gt&quot;,<br>
&quot;searchCriteria[filter_groups][1][filters][0][field]&quot;=&quot;created_at&quot;,<br>
&quot;searchCriteria[filter_groups][1][filters][0][value]&quot;=&quot;2014-01-01 00:00:00&quot;,<br>
&quot;searchCriteria[filter_groups][1][filters][0][condition_type]&quot;=&quot;lt&quot;,<br>
&quot;searchCriteria[filter_groups][2][filters][0][field]&quot;=&quot;base_grand_total&quot;,<br>
&quot;searchCriteria[filter_groups][2][filters][0][value]&quot;=&quot;1000&quot;,<br>
&quot;searchCriteria[filter_groups][2][filters][0][condition_type]&quot;=&quot;gt&quot;,<br>
&quot;searchCriteria[filter_groups][2][filters][1][field]&quot;=&quot;base_grand_total&quot;,<br>
&quot;searchCriteria[filter_groups][2][filters][1][value]&quot;=&quot;100&quot;,<br>
&quot;searchCriteria[filter_groups][2][filters][1][condition_type]&quot;=&quot;lt&quot;)</code><br>
Note that here we have 3 filter groups that stands for AND condition. The last group has 2 conditions (filters) that are connected as OR.<br>
Calling the function<br>
<code>invoices2 &lt;- getm2objects(urlbase = urlbase, endpoint = endpoint, query = myquery, auth=auth)</code><br>
Let’s also check how big is our invoice in average</p>
<p><code>object.size(invoices2)/invoices2[[&quot;total_count&quot;]] </code></p>
<p>In my case one invoice in average was over 17 KB. It isn’t a problem for limited data, but if you have massive number of objects it may end up not good.</p>
<h2>Hence a word of caution!</h2>
<p><strong>Be mindful with your API requests</strong>, especially if you query production Magento 2 instance. Getting too wild may slow it down significantly and you can run out of memory on your local machine.</p>
<p>That is it for now. In the next post or two, I’ll write about getting filtered results. It is useful if you don’t need all the data, only part of it and don’t want to consume more than necessary resources, which may be important in many situations. Stay tuned!</p>
<p><a rel="nofollow" href="https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Flevashov.biz%2Fr-plus-magento-2-rest-api-revisited-authentication-and-universal-search-part-one%2F&linkname=R%20plus%20Magento%202%20REST%20API%20revisited%3A%20part%201-%20authentication%20and%20universal%20search" title="Facebook" target="_blank"></a><a rel="nofollow" href="https://www.addtoany.com/add_to/twitter?linkurl=https%3A%2F%2Flevashov.biz%2Fr-plus-magento-2-rest-api-revisited-authentication-and-universal-search-part-one%2F&linkname=R%20plus%20Magento%202%20REST%20API%20revisited%3A%20part%201-%20authentication%20and%20universal%20search" title="Twitter" target="_blank"></a><a rel="nofollow" href="https://www.addtoany.com/add_to/google_plus?linkurl=https%3A%2F%2Flevashov.biz%2Fr-plus-magento-2-rest-api-revisited-authentication-and-universal-search-part-one%2F&linkname=R%20plus%20Magento%202%20REST%20API%20revisited%3A%20part%201-%20authentication%20and%20universal%20search" title="Google+" target="_blank"></a><a rel="nofollow" href="https://www.addtoany.com/add_to/linkedin?linkurl=https%3A%2F%2Flevashov.biz%2Fr-plus-magento-2-rest-api-revisited-authentication-and-universal-search-part-one%2F&linkname=R%20plus%20Magento%202%20REST%20API%20revisited%3A%20part%201-%20authentication%20and%20universal%20search" title="LinkedIn" target="_blank"></a><a rel="nofollow" href="https://www.addtoany.com/add_to/reddit?linkurl=https%3A%2F%2Flevashov.biz%2Fr-plus-magento-2-rest-api-revisited-authentication-and-universal-search-part-one%2F&linkname=R%20plus%20Magento%202%20REST%20API%20revisited%3A%20part%201-%20authentication%20and%20universal%20search" title="Reddit" target="_blank"></a><a data-a2a-title="R plus Magento 2 REST API revisited: part 1- authentication and universal search" rel="nofollow" href="https://www.addtoany.com/share#url=https%3A%2F%2Flevashov.biz%2Fr-plus-magento-2-rest-api-revisited-authentication-and-universal-search-part-one%2F&amp;%23038;title=R%20plus%20Magento%202%20REST%20API%20revisited%3A%20part%201-%20authentication%20and%20universal%20search" data-a2a-url="https://levashov.biz/r-plus-magento-2-rest-api-revisited-authentication-and-universal-search-part-one/" target="_blank"></a></p>
<p>The post <a rel="nofollow" href="https://levashov.biz/r-plus-magento-2-rest-api-revisited-authentication-and-universal-search-part-one/" target="_blank">R plus Magento 2 REST API revisited: part 1- authentication and universal search</a> appeared first on <a rel="nofollow" href="https://levashov.biz/" target="_blank">Alex Levashov – eCommerce Consultant (Melbourne, Australia)</a>.</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://levashov.biz/r-plus-magento-2-rest-api-revisited-authentication-and-universal-search-part-one/"> R – Alex Levashov – eCommerce Consultant (Melbourne, Australia)</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/vtPMUciHkoI" height="1"></a></div>