<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: llermaly</title>
    <description>The latest articles on DEV Community by llermaly (@llermaly).</description>
    <link>https://dev.to/llermaly</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F454472%2F3ca594a9-318a-415c-9836-32c9baf8a3b0.png</url>
      <title>DEV Community: llermaly</title>
      <link>https://dev.to/llermaly</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/llermaly"/>
    <language>en</language>
    <item>
      <title>Body parsing in App Search</title>
      <dc:creator>llermaly</dc:creator>
      <pubDate>Thu, 07 Jul 2022 23:20:15 +0000</pubDate>
      <link>https://dev.to/llermaly/body-parsing-in-app-search-4ckc</link>
      <guid>https://dev.to/llermaly/body-parsing-in-app-search-4ckc</guid>
      <description>&lt;p&gt;A feature some people (including me) miss from Swiftype Site Search is being able to parse content using CSS selectors.&lt;/p&gt;

&lt;h2&gt;
  
  
  The body parsing problem
&lt;/h2&gt;

&lt;p&gt;The App Search crawler will extract all the content from the website you specify and spread it in fields depending on the HTML tags it finds.&lt;/p&gt;

&lt;p&gt;Text within title tags will be assumed as title field; anchor tags as links, and body will be parsed as one giant field with everything else.&lt;/p&gt;

&lt;p&gt;What if a website has a custom structure we want to capture? For example, product pages. We want to capture things like color, size, and price in specific fields and not as part of a single body field.&lt;/p&gt;

&lt;p&gt;App Search allows you to add &lt;a href="https://www.elastic.co/guide/en/app-search/current/web-crawler-reference.html#web-crawler-reference-meta-tags-content-extraction" rel="noopener noreferrer"&gt;Meta Tags&lt;/a&gt; to your website to create custom fields, but sometimes making changes on the website is too complicated (red tape) or just not possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The body parsing solution
&lt;/h2&gt;

&lt;p&gt;This post will explore a way of creating a proxy between the crawler and the actual website that does the extraction, creates the needed Meta Tags, and then inject these in the new response so App Search can grab these tags and use them.&lt;/p&gt;

&lt;p&gt;To keep this short, I will not be doing a step-by-step guide and only showing the key parts of the script.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, what are we doing?
&lt;/h2&gt;

&lt;p&gt;We are going to create a NodeJS server that hosts a product page and a proxy that stands in front. This will receive the crawler request, hit the product page, inject the meta tags, and then return the page to the crawler.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6235eaukt3tnpm7bhlq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6235eaukt3tnpm7bhlq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how we add custom fields using meta tags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"elastic"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"product_price"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"99.99"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;data-elastic-name=&lt;/span&gt;&lt;span class="s"&gt;"product_name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Printer&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Nodejs (to create example page and proxy)&lt;/li&gt;
&lt;li&gt;Ngrok (to expose local proxy to the internet)&lt;/li&gt;
&lt;li&gt;App Search (to crawl the page)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The page
&lt;/h2&gt;

&lt;p&gt;Following the example we will serve a page that emulates a product page for a printer.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;index.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Printer Page&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Printer&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"price-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Price&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"value"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;2.99&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;server.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1337&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Application started and Listening on port 1337&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Afterwards, we use App Search to crawl the page and—as expected—the data we want to have as fields (like the price) was just put inside the body content field:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkugcbtfvvdqfn39f61rp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkugcbtfvvdqfn39f61rp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, we will create a proxy capable of recognizing this data, and injecting a meta tag to the response, so App Search can recognize this is a field.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;proxy.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;httpProxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http-proxy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;_write&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;write&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;_write&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;data&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;class="value"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;class="value" data-elastic-name="price"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;web&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8013&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;proxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;httpProxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createProxyServer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:1337&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http proxy server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; started &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;on port &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8013&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we can start our server and proxy to expose the proxy with Ngrok and use it in App Search.&lt;/p&gt;

&lt;p&gt;Voilà! We now have the price as a separate field:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3jx2e35p0e3yde2pt62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3jx2e35p0e3yde2pt62.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can go as fancy as we want using the middleware that transforms the body response to add meta tags based on existent classes, but also based on the content itself.&lt;/p&gt;

&lt;p&gt;This is a simple example, but I hope you get the gist.&lt;/p&gt;

</description>
      <category>elasticsearch</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Qué es una API y por qué todos deberían conocerlas</title>
      <dc:creator>llermaly</dc:creator>
      <pubDate>Tue, 22 Jun 2021 19:02:46 +0000</pubDate>
      <link>https://dev.to/llermaly/que-es-una-api-y-por-que-todos-deberian-conocerlas-116i</link>
      <guid>https://dev.to/llermaly/que-es-una-api-y-por-que-todos-deberian-conocerlas-116i</guid>
      <description>&lt;p&gt;Me he dado cuenta de que en algunos aspectos hemos avanzado mucho y en otros no tanto en lo que respecta al uso de la tecnología.&lt;/p&gt;

&lt;p&gt;Adultos que hace un par de años no tenían correo hoy en día están en todas las redes sociales, compran online y hasta nos enseñan uno que otro truquillo a veces.&lt;/p&gt;

&lt;p&gt;Los más jóvenes en cambio, si no están relacionados con la tecnología por sus carreras no están muy lejos de estos valientes padres y abuelitos en cuanto al uso de herramientas tecnológicas a en el día a día, hablo de las personas de entre 25 y 45 años.&lt;/p&gt;

&lt;p&gt;Ya es hora de dar el siguiente paso y conocer las &lt;strong&gt;API&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿ Qué es una API ?
&lt;/h2&gt;

&lt;p&gt;Una &lt;strong&gt;&lt;a href="https://es.wikipedia.org/wiki/Interfaz_de_programaci%C3%B3n_de_aplicaciones"&gt;API&lt;/a&gt;&lt;/strong&gt; (application programming interface) es un estándar de comunicación entre sistemas. De esta forma un sistema en internet puede utilizar datos de otro sin necesidad de hacer un esfuerzo adicional por conseguir esa comunicación, es un lenguaje común entre máquinas.&lt;/p&gt;

&lt;p&gt;Por ejemplo, un sitio web se ve así: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B_mEi4H---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9smxdysaeqaa27zu359.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B_mEi4H---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9smxdysaeqaa27zu359.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Y la respuesta de una llamada a su API se vería así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "quote": "The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking",
    "author": "Albert Einstein",
    "tags": ["change", "deep-thoughts", "thinking", "world"]
  }
...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto permite que cualquier otro sitio web o persona pueda obtener los datos de manera estructurada y procesarlos de la forma que necesite.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿ Y eso qué ?
&lt;/h3&gt;

&lt;p&gt;Si aun no se te ocurre en qué te afecta esto a ti, te lo explico de otra manera: Las API son a los sitios web, como las planillas de Excel son a los documentos word/PDF.&lt;/p&gt;

&lt;p&gt;Un documento PDF está muy bien para leer información sumarizada, pero no nos permite trabajar con los datos que se usaron para llegar a ese resultado. En cambio una planilla Excel nos permite hacer muchas cosas, tales como realizar cálculos, visualizar gráficos, convertir la planilla en una base de datos, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Y Cómo consulto una API ?
&lt;/h3&gt;

&lt;p&gt;La forma más simple es mediante tu navegador, en este caso la API tiene que ser pública y usar el verbo GET. No quiero entrar en detalles al respecto porque no es el fin de este post.&lt;/p&gt;

&lt;p&gt;Pincha este link : &lt;a href="https://mindicador.cl/api"&gt;https://mindicador.cl/api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esa es una API que entrega indicadores económicos, pero las hay de absolutamente todo tipo. Al final del post agregaré fuentes de distintas APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿ Y qué hago yo con esa respuesta ?
&lt;/h3&gt;

&lt;p&gt;Como puedes ver la respuesta que te entregó viene el mismo formato del ejemplo de las frases, se llama &lt;a href="https://es.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Si quieres convertir una lista de objetos JSON a un CSV (excel) puedes utilizar esta página: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.convertcsv.com/json-to-csv.htm"&gt;https://www.convertcsv.com/json-to-csv.htm&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pero meterme a la página del banco central es lo mismo y hasta más bonito ...
&lt;/h3&gt;

&lt;p&gt;Es lo mismo siempre y cuando seas tú el que realice la acción, pero, ¿y si una máquina la ejecuta por tí?. Mi último proyecto se llama &lt;strong&gt;gustabot&lt;/strong&gt; y es un asistente de Whatsapp que funciona como intermediario entre tú y la API, y te permite por ejemplo escribir !uf 200 al bot, y el bot irá a la API y te entregará el valor total de 200UF. Así te ahorras entrar a la página del banco central, abrir la calculadora, y hacer el cálculo.&lt;/p&gt;

&lt;p&gt;¿ Me vas siguiendo ahora ?. Existen infinidad de actividades que se pueden hacer de forma más eficiente utilizando APIs, sin contar el tema de la libertad de los datos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vs3Tlzd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ezec7h0lg0t1329iut0d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vs3Tlzd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ezec7h0lg0t1329iut0d.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  La libertad de los datos
&lt;/h2&gt;

&lt;p&gt;Volviendo a la analogía del Excel y el Word. Deberíamos confiar ciegamente en los gráficos que se nos muestran a la hora de tratar temas importantes?, o deberíamos ir directo al Excel a mirar los datos duros?. Lógicamente deberíamos ir directamente a los datos y visualizarlos como más nos convenga a nosotros, y no a quien nos expuso los gráficos.&lt;/p&gt;

&lt;p&gt;Con las API ocurre lo mismo. En muchos casos las páginas web mostrarán los datos según intereses que no necesariamente se van a alinear con los nuestros. Con las API este problema desaparece. Puedes acudir a esta, descargar los datos y procesarlos a gusto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Y por qué tan poca gente las conoce ?
&lt;/h2&gt;

&lt;p&gt;El concepto de API existe hace mucho, sin embargo el gran responsable de que no sean un tema es que en Chile al menos hay muy pocos sistemas con APIs disponibles para las personas. &lt;/p&gt;

&lt;p&gt;Algunos chilenos de gran corazón han hecho APIs "a la mala",  es decir, crearon un software que descarga la página web y luego disponibiliza una API con resultados estructurados para que otros la usen.&lt;/p&gt;

&lt;p&gt;Ejemplo: API para ver sismos en Chile &lt;a href="https://api.xor.cl/sismo/"&gt;https://api.xor.cl/sismo/&lt;/a&gt; , las instrucciones de uso en este link &lt;a href="https://xor.cl/api/sismo/"&gt;https://xor.cl/api/sismo/&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Este tipo de iniciativas permiten que cualquier persona pueda recolectar datos para estudios, o para generar nuevas plataformas que los utilicen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Y por qué es importante?
&lt;/h2&gt;

&lt;p&gt;La existencia y uso de las APIs por parte de la ciudadanía es importante porque distribuye el poder de la información, y permite que los mismos ciudadanos puedan realizar tareas de forma más eficiente.&lt;/p&gt;

&lt;p&gt;Dicha generación de conocimiento a su vez impulsa el desarrollo tecnológico y presiona la existencia de más APIs para los datos que se publican como "abiertos y transparentes" y que por la carencia de APIS muy poco se puede hacer para explorarlos.&lt;/p&gt;

&lt;p&gt;Ahora puede sonar raro, pero igual de raro sonaba hace años que alguien te dijera "anota tus gastos en un Excel y los vas mirando todos los meses" cuando el Excel era un software para trabajar exclusivamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resumen
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Una API es un estándar de comunicación entre máquinas&lt;/li&gt;
&lt;li&gt;Las personas pueden usarlas para mejorar su eficiencia y procesar los datos a gusto&lt;/li&gt;
&lt;li&gt;Existen sistemas intermediarios para facilitar su uso&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links de interés
&lt;/h2&gt;

&lt;p&gt;Faltó mucho más por cubrir, pero queda de tarea que entiendan mejor cómo consultar las distintas APIs disponibles, les dejo un punto de partida.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.postman.com/"&gt;https://www.postman.com/&lt;/a&gt; : Software para consultar APIs que no se pueden consultar con el navegador&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://xor.cl/"&gt;https://xor.cl/&lt;/a&gt; : Algunas APIs chilenas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.convertcsv.com/json-to-csv.htm"&gt;https://www.convertcsv.com/json-to-csv.htm&lt;/a&gt; : Convertidor JSON a CSV&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/public-apis/public-apis"&gt;https://github.com/public-apis/public-apis&lt;/a&gt; : Listado de APIs por categorías (inglés)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>gustabot</category>
      <category>espanol</category>
    </item>
  </channel>
</rss>
