<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Code Richard: The Blog]]></title><description><![CDATA[Full stack web developer from Mexico]]></description><link>https://blog.ricardomendoza.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 15 Sep 2026 15:58:51 GMT</lastBuildDate><atom:link href="https://blog.ricardomendoza.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Proxyquire + Sinon]]></title><description><![CDATA[Las pruebas unitarias son vitales para el desarrollo de software. En especial cuando desarrollamos aplicaciones de gran tamaño, debemos asegurarnos de que cada una de sus unidades funciona como se espera.
Por definición, las pruebas unitarias nos ayu...]]></description><link>https://blog.ricardomendoza.dev/proxyquire-sinon-es</link><guid isPermaLink="true">https://blog.ricardomendoza.dev/proxyquire-sinon-es</guid><category><![CDATA[Node.js]]></category><category><![CDATA[unit testing]]></category><category><![CDATA[proxyquire]]></category><category><![CDATA[sinon]]></category><dc:creator><![CDATA[Ricardo Mendoza]]></dc:creator><pubDate>Fri, 07 Jul 2023 16:20:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1688742542512/1190848d-a24d-4fa2-9b5a-252256e8b46d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Las pruebas unitarias son vitales para el desarrollo de software. En especial cuando desarrollamos aplicaciones de gran tamaño, debemos asegurarnos de que cada una de sus unidades funciona como se espera.</p>
<p>Por definición, las pruebas unitarias nos ayudan a asegurarnos de que una unidad de código en específico hace lo que debe de hacer. Por lo tanto, <em>para crear pruebas unitarias sólidas debemos asegurarnos de aislar debidamente la pieza de código que queremos probar</em>. No queremos que otros módulos (las dependencias) interfieran con el resultado de la unidad que estamos probando.</p>
<p>Sin embargo, puede resultar un trabajo complicado simular cada dependencia requerida por un módulo. Aquí es donde <strong>Proxyquire</strong> entra en acción.</p>
<p><strong>Proxyquire</strong> es un módulo bastante útil, el cuál nos permite sustituir todas las dependencias requeridas por la unidad que estemos probando al importar dicha unidad. Si lo combinamos con <strong>Sinon</strong>, otro módulo de Node JS para pruebas, nos resultará mucho más fácil simular todas las dependencias y, por lo tanto, enfocarnos únicamente en el comportamiento del módulo que estamos probando.</p>
<h2 id="heading-como-funciona">Cómo funciona</h2>
<p>Veamos un ejemplo para ilustrar cómo trabajan en conjunto <strong>Proxyquire</strong> y <strong>Sinon</strong>. Imaginemos que necesitamos desarrollar un módulo que lea/escriba la configuración de los usuarios desde/hacia un archivo. Vamos a crear ese módulo y sus respectivas pruebas unitarias.</p>
<p>El código (simplificado) para este gestor de configuraciones quedaría más o menos como sigue:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs/promises'</span>);

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> load = <span class="hljs-keyword">async</span> () =&gt; {
        <span class="hljs-keyword">try</span> {
                <span class="hljs-keyword">const</span> rawSettings = <span class="hljs-keyword">await</span> fs.readFile(<span class="hljs-string">'settings.json'</span>);
                <span class="hljs-keyword">return</span> <span class="hljs-built_in">JSON</span>.parse(rawSettings);
            } <span class="hljs-keyword">catch</span> (error) {
                <span class="hljs-keyword">return</span> {};
            }
    };

    <span class="hljs-keyword">const</span> save = <span class="hljs-keyword">async</span> (settings = {}) =&gt; {
        <span class="hljs-keyword">const</span> settingsStr = <span class="hljs-built_in">JSON</span>.stringify(settings);
        fs.writeFile(<span class="hljs-string">'settings.json'</span>, settingsStr);
    };

    <span class="hljs-keyword">return</span> {
        load,
        save
    };
};
</code></pre>
<p>Como se observa, nuestro gestor de configuraciones depende del módulo <em>fs</em> de Node JS. Por lo tanto, el comportamiento de este módulo externo podría afectar los resultados de las pruebas unitarias que realicemos para este módulo que acabamos de crear. Idealmente, buscaríamos evitar esto, ya que: 1) el comportamiento del módulo <em>fs</em> (o cualquier otro módulo que nuestra unidad a probar requiera) está completamente fuera de nuestras manos (por ejemplo, conexiones a APIs externas, bases de datos o sistemas de archivos, como en este ejemplo) y 2) necesitamos enfocarnos en probar una única unidad (y no en sus dependencias).</p>
<p>Ahora veamos cómo podemos probar nuestro módulo sustituyendo sus dependencias y evitando así comportamientos no deseados.</p>
<p>(Nota: para este ejemplo, utilizaremos <strong>Mocha</strong> + <strong>Chai</strong> como marco + biblioteca para pruebas unitarias. Luego, haremos uso de <strong>Sinon</strong> y <strong>Proxyquire</strong> para sustituir las dependencias del gestor de configuraciones y probarlo de manera aislada.)</p>
<p>Pero primero lo primero: para instalar todas las dependencias de desarrollo que vamos a usar para las pruebas podemos usar el siguiente comando:</p>
<pre><code class="lang-javascript">npm install mocha chai sinon sinon-chai proxyquire
</code></pre>
<p>Después, viene el código:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> chai = <span class="hljs-built_in">require</span>(<span class="hljs-string">'chai'</span>);
chai.use(<span class="hljs-built_in">require</span>(<span class="hljs-string">'sinon-chai'</span>));
<span class="hljs-keyword">const</span> { expect } = chai;
<span class="hljs-keyword">const</span> sinon = <span class="hljs-built_in">require</span>(<span class="hljs-string">'sinon'</span>);
<span class="hljs-keyword">const</span> proxyquire = <span class="hljs-built_in">require</span>(<span class="hljs-string">'proxyquire'</span>).noCallThru();

describe(<span class="hljs-string">'Settings manager'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> settingsPath = <span class="hljs-string">'settings.json'</span>;
    <span class="hljs-keyword">let</span> settingsFake;
    <span class="hljs-keyword">let</span> fsFake;
    <span class="hljs-keyword">let</span> settingsManager;

    beforeEach(<span class="hljs-function">() =&gt;</span> {
        settingsFake = {
            <span class="hljs-attr">language</span>: <span class="hljs-string">'English'</span>
        };

        <span class="hljs-comment">// [1] Con Sinon, se crea un doble del módulo 'fs'.</span>
        fsFake = {
            <span class="hljs-comment">// [2] Se crea un doble de la función 'readFile'.</span>
            <span class="hljs-attr">readFile</span>: sinon.stub().callsFake(<span class="hljs-function"><span class="hljs-params">path</span> =&gt;</span> <span class="hljs-built_in">JSON</span>.stringify(settingsFake)),
            <span class="hljs-comment">// [3] Se crea un doble de la función 'writeFile'.</span>
            <span class="hljs-attr">writeFile</span>: sinon.stub().callsFake(<span class="hljs-function">(<span class="hljs-params">path, settings</span>) =&gt;</span> {
                settingsFake = <span class="hljs-built_in">JSON</span>.parse(settings);
            })
        };

        <span class="hljs-comment">// [4] Se carga el módulo gestor de archivos con Proxyquire.</span>
        settingsManager = proxyquire(<span class="hljs-string">'../../settingsManager'</span>, {
            <span class="hljs-string">'fs/promises'</span>: fsFake
        })();
    });

    it(<span class="hljs-string">'loads settings'</span>, <span class="hljs-keyword">async</span> () =&gt; {
        <span class="hljs-keyword">const</span> settings = <span class="hljs-keyword">await</span> settingsManager.load();

        <span class="hljs-comment">// Se revisa que la función  haya sido llamada correctamente.</span>
        expect(fsFake.readFile).to.have.been.calledOnceWith(settingsPath);
        <span class="hljs-comment">// Se revisa que las configuraciones regresadas sean correctas.</span>
        expect(settings).to.be.an(<span class="hljs-string">'object'</span>).that.deep.equals(settingsFake);
    });

    it(<span class="hljs-string">'saves settings'</span>, <span class="hljs-keyword">async</span> () =&gt; {
        <span class="hljs-keyword">const</span> defaultSettings = {
            <span class="hljs-attr">language</span>: <span class="hljs-string">'English'</span>
        };
        <span class="hljs-keyword">const</span> updatedSettings = {
            <span class="hljs-attr">language</span>: <span class="hljs-string">'Japanese'</span>
        };
        <span class="hljs-keyword">const</span> updatedSettingsStr = <span class="hljs-built_in">JSON</span>.stringify(updatedSettings);

        <span class="hljs-comment">// Primero, se revisa que las configuraciones originales coincidan con las configuraciones por defecto.</span>
        <span class="hljs-keyword">let</span> settings = <span class="hljs-keyword">await</span> settingsManager.load();
        expect(settings).to.be.an(<span class="hljs-string">'object'</span>).that.deep.equals(defaultSettings);

        <span class="hljs-comment">// Luego, se actualizan las configuraciones...</span>
        <span class="hljs-keyword">await</span> settingsManager.save(updatedSettings);
        <span class="hljs-comment">// ...y se revisa que la función haya sido llamada correctamente.</span>
        expect(fsFake.writeFile).to.have.been.calledOnceWith(settingsPath, updatedSettingsStr);

        <span class="hljs-comment">// Finalmente, se revisa que las configuraciones hayan sido actualizadas correctamente.</span>
        settings = <span class="hljs-keyword">await</span> settingsManager.load();
        expect(settings).to.be.an(<span class="hljs-string">'object'</span>).that.deep.equals(updatedSettings);
    });
});
</code></pre>
<p>Aquí una pequeña explicación de lo que sucede en el código:</p>
<p>Primero, creamos un módulo <em>fs</em> falso con <strong>Sinon</strong> (1), el cuál contiene versiones simplificadas de las funciones que utiliza nuestro gestor de configuraciones. Creamos una función <em>readFile</em> (2) con comportamiento simplificado: recibe una ruta como parámetro (el cuál es completamente ignorado) y únicamente regresa el objeto falso de configuraciones convertido a cadena. También creamos una función <em>writeFile</em> (3) con un comportamiento, igualmente, simplificado: recibe una ruta y las configuraciones a almacenar como parámetros y, simplemente, actualiza el objeto falso de configuraciones con las configuraciones recibidas.</p>
<p>Nuestro objetivo no es probar estas funciones del módulo <em>fs</em>, por lo que podemos simplificar su comportamiento para que funcionen como lo esperamos y no afecten el resultado del módulo que sí nos interesa probar.</p>
<p>Finalmente, cargamos el módulo gestor de configuraciones con <strong>Proxyquire</strong> (4) para inyectar las dependencias falsas, evitando así que se carguen las dependencias reales.</p>
<p>De esta manera podemos evitar comportamiento no deseado y enfocarnos en probar el módulo que realmente nos interesa. Con esto podemos ejecutar nuestras pruebas unitarias las veces que sean necesarias y esperar el mismo resultado con cada ejecución.</p>
<p>¡Así es como podemos simular dependencias para nuestras pruebas unitarias en Node JS con <strong>Proxyquire</strong> y <strong>Sinon</strong>!</p>
<p>¡Gracias por leer hasta aquí! Cualquier comentario o duda, háganmelo saber.</p>
<p>Imagen de portada por <a target="_blank" href="https://www.behance.net/ZafiroLuna">Zafiro Luna</a>.</p>
<p>Para profundizar en el tema:</p>
<ul>
<li><p><a target="_blank" href="https://github.com/thlorenz/proxyquire">Repositorio en Github de Proxyquire</a></p>
</li>
<li><p><a target="_blank" href="https://sinonjs.org/releases/latest/">Documentación de Sinon</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Proxyquire + Sinon]]></title><description><![CDATA[Unit tests are vital in software development. Especially when building a big application, we want to make sure that all its units work as expected.
By definition, unit tests help us ensure a single unit of code does what it has to do. Therefore, to c...]]></description><link>https://blog.ricardomendoza.dev/proxyquire-sinon-en</link><guid isPermaLink="true">https://blog.ricardomendoza.dev/proxyquire-sinon-en</guid><category><![CDATA[Node.js]]></category><category><![CDATA[unit testing]]></category><category><![CDATA[sinon]]></category><category><![CDATA[proxyquire]]></category><dc:creator><![CDATA[Ricardo Mendoza]]></dc:creator><pubDate>Fri, 07 Jul 2023 16:17:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1688746202030/43efa0e5-5fc5-46bf-8814-b669035ff7b8.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Unit tests are vital in software development. Especially when building a big application, we want to make sure that all its units work as expected.</p>
<p>By definition, unit tests help us ensure a single unit of code does what it has to do. Therefore, <em>to create solid unit tests we must assure we're isolating the piece of code we want to test as much as possible</em>. We don't want other modules (the required dependencies) to interfere with the outcome of the unit we're testing.</p>
<p>However, it could be a bit tricky to mock every single dependency a module requires. That's where <strong>Proxyquire</strong> comes into action.</p>
<p><strong>Proxyquire</strong> is a handy module that <em>lets us proxy all the dependencies required by the module we're testing when importing it</em>. If we combine it with <strong>Sinon</strong> (another helpful Node JS module for testing), we can now stub with ease any dependencies, making it easy to focus on the behavior of the unit we're testing in isolation.</p>
<h2 id="heading-how-it-works">How it works</h2>
<p>Let's use an example to illustrate how <strong>Proxyquire</strong> and <strong>Sinon</strong> work together. Imagine we need a module to retrieve/store user settings from/into a file for our application. Let's create that module along with its corresponding unit test.</p>
<p>The (simplified) code for this settings manager module would be as follows:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs/promises'</span>);

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> load = <span class="hljs-keyword">async</span> () =&gt; {
        <span class="hljs-keyword">try</span> {
                <span class="hljs-keyword">const</span> rawSettings = <span class="hljs-keyword">await</span> fs.readFile(<span class="hljs-string">'settings.json'</span>);
                <span class="hljs-keyword">return</span> <span class="hljs-built_in">JSON</span>.parse(rawSettings);
            } <span class="hljs-keyword">catch</span> (error) {
                <span class="hljs-keyword">return</span> {};
            }
    };

    <span class="hljs-keyword">const</span> save = <span class="hljs-keyword">async</span> (settings = {}) =&gt; {
        <span class="hljs-keyword">const</span> settingsStr = <span class="hljs-built_in">JSON</span>.stringify(settings);
        fs.writeFile(<span class="hljs-string">'settings.json'</span>, settingsStr);
    };

    <span class="hljs-keyword">return</span> {
        load,
        save
    };
};
</code></pre>
<p>As we can see, our new module relies on Node JS' built-in <em>file system</em> module. Therefore, the behavior of this external module could affect the unit tests for the settings manager module we just created. Ideally, we don't want this to happen, because: 1) the behavior of the <em>fs</em> module (or any other module required by the unit being tested) could be completely out of our hands (say, a connection to an external API, database, file system, etc.), and 2) we want to focus our tests on a single unit (not its dependencies).</p>
<p>So, let's see how we can test our module by mocking its dependencies, avoiding unwanted behavior.</p>
<p>(Note: for this example, we're going to use <strong>Mocha</strong> + <strong>Chai</strong> as the test framework + library. Then, we're adding <strong>Sinon</strong> and <strong>Proxyquire</strong> for mocking the dependencies of the settings manager and testing it in isolation.)</p>
<p>First things first: to install all the dev dependencies we're going to use for testing we can use the following command:</p>
<pre><code class="lang-plaintext">npm install mocha chai sinon sinon-chai proxyquire
</code></pre>
<p>Then comes the code (some test cases are omitted for simplicity):</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> chai = <span class="hljs-built_in">require</span>(<span class="hljs-string">'chai'</span>);
chai.use(<span class="hljs-built_in">require</span>(<span class="hljs-string">'sinon-chai'</span>));
<span class="hljs-keyword">const</span> { expect } = chai;
<span class="hljs-keyword">const</span> sinon = <span class="hljs-built_in">require</span>(<span class="hljs-string">'sinon'</span>);
<span class="hljs-keyword">const</span> proxyquire = <span class="hljs-built_in">require</span>(<span class="hljs-string">'proxyquire'</span>).noCallThru();

describe(<span class="hljs-string">'Settings manager'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> settingsPath = <span class="hljs-string">'settings.json'</span>;
    <span class="hljs-keyword">let</span> settingsFake;
    <span class="hljs-keyword">let</span> fsFake;
    <span class="hljs-keyword">let</span> settingsManager;

    beforeEach(<span class="hljs-function">() =&gt;</span> {
        settingsFake = {
            <span class="hljs-attr">language</span>: <span class="hljs-string">'English'</span>
        };

        <span class="hljs-comment">// [1] Create a fake 'fs' module with Sinon.</span>
        fsFake = {
            <span class="hljs-comment">// [2] Stub the 'readFile' function.</span>
            <span class="hljs-attr">readFile</span>: sinon.stub().callsFake(<span class="hljs-function"><span class="hljs-params">path</span> =&gt;</span> <span class="hljs-built_in">JSON</span>.stringify(settingsFake)),
            <span class="hljs-comment">// [3] Stub the 'writeFile' function.</span>
            <span class="hljs-attr">writeFile</span>: sinon.stub().callsFake(<span class="hljs-function">(<span class="hljs-params">path, settings</span>) =&gt;</span> {
                settingsFake = <span class="hljs-built_in">JSON</span>.parse(settings);
            })
        };

        <span class="hljs-comment">// [4] Load the settings manager module with Proxyquire.</span>
        settingsManager = proxyquire(<span class="hljs-string">'../../settingsManager'</span>, {
            <span class="hljs-string">'fs/promises'</span>: fsFake
        })();
    });

    it(<span class="hljs-string">'loads settings'</span>, <span class="hljs-keyword">async</span> () =&gt; {
        <span class="hljs-keyword">const</span> settings = <span class="hljs-keyword">await</span> settingsManager.load();

        <span class="hljs-comment">// Check that the stubbed function was called properly.</span>
        expect(fsFake.readFile).to.have.been.calledOnceWith(settingsPath);
        <span class="hljs-comment">// Check that the returned settings are correct.</span>
        expect(settings).to.be.an(<span class="hljs-string">'object'</span>).that.deep.equals(settingsFake);
    });

    it(<span class="hljs-string">'saves settings'</span>, <span class="hljs-keyword">async</span> () =&gt; {
        <span class="hljs-keyword">const</span> defaultSettings = {
            <span class="hljs-attr">language</span>: <span class="hljs-string">'English'</span>
        };
        <span class="hljs-keyword">const</span> updatedSettings = {
            <span class="hljs-attr">language</span>: <span class="hljs-string">'Japanese'</span>
        };
        <span class="hljs-keyword">const</span> updatedSettingsStr = <span class="hljs-built_in">JSON</span>.stringify(updatedSettings);

        <span class="hljs-comment">// First, check that the original settings are equal to the default ones.</span>
        <span class="hljs-keyword">let</span> settings = <span class="hljs-keyword">await</span> settingsManager.load();
        expect(settings).to.be.an(<span class="hljs-string">'object'</span>).that.deep.equals(defaultSettings);

        <span class="hljs-comment">// Then, update the settings...</span>
        <span class="hljs-keyword">await</span> settingsManager.save(updatedSettings);
        <span class="hljs-comment">// ..and check that the stubbed function was called properly.</span>
        expect(fsFake.writeFile).to.have.been.calledOnceWith(settingsPath, updatedSettingsStr);

        <span class="hljs-comment">// Finally, check that the settings where updated correctly.</span>
        settings = <span class="hljs-keyword">await</span> settingsManager.load();
        expect(settings).to.be.an(<span class="hljs-string">'object'</span>).that.deep.equals(updatedSettings);
    });
});
</code></pre>
<p>Here's a quick explanation of what happens on the above code:</p>
<p>First, we create a fake <em>fs</em> module with <strong>Sinon</strong> (1) which contains stubbed versions of the functions we use in our module. We have a stubbed <em>readFile</em> function (2) with a simplified behavior: it receives a path as a parameter (which is completely ignored) and it just returns the stringified settings fake. We also have a stubbed <em>writeFile</em> function (3) with a simplified behavior as well: it receives a path and the settings to save as parameters and it just updates the settings fake with the parsed settings received. We're not interested in testing these <em>fs</em> functions for these tests, so we can simplify their behavior as we would expect it to be for our module to work properly.</p>
<p>Finally, we load our settings manager module with <strong>Proxyquire</strong> (4) to inject the stubbed dependencies, preventing the real ones to be loaded instead.</p>
<p>This way we can avoid unexpected behavior from the modules required by the unit being tested and focus on its functionality. We can now run our unit tests as many times as we want and expect the same results every time.</p>
<p>That's how we can mock dependencies for creating unit tests in Node JS with <strong>Proxyquire</strong> and <strong>Sinon</strong>!</p>
<p>Thanks for reading! Let me know if you have any thoughts or questions!</p>
<p>For further reading:</p>
<ul>
<li><p><a target="_blank" href="https://github.com/thlorenz/proxyquire">Proxyquire's Github repository</a></p>
</li>
<li><p><a target="_blank" href="https://sinonjs.org/releases/latest/">Sinon documentation</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Understanding RESTful APIs pt 1]]></title><description><![CDATA[Are you starting with web development? Have you heard about RESTful APIs? Web developers should have a clear understanding of what RESTful APIs are, for they have become one of the foundations of modern web applications.
In this series, I will share ...]]></description><link>https://blog.ricardomendoza.dev/understanding-restful-apis-part-1</link><guid isPermaLink="true">https://blog.ricardomendoza.dev/understanding-restful-apis-part-1</guid><category><![CDATA[APIs]]></category><category><![CDATA[REST API]]></category><category><![CDATA[REST]]></category><category><![CDATA[restful]]></category><dc:creator><![CDATA[Ricardo Mendoza]]></dc:creator><pubDate>Sun, 29 May 2022 23:10:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653809271473/R8yAQ44yx.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you starting with web development? Have you heard about RESTful APIs? <strong>Web developers should have a clear understanding of what RESTful APIs are</strong>, for they have become one of the foundations of modern web applications.</p>
<p>In this series, I will share with you everything I know about RESTful APIs: from what they are and why they came to be, to how they work and why they are so convenient for building anything from small websites to entire platforms.</p>
<p>If you aim to create useful APIs or want to make the most out of the ones already out there, I invite you to read on!</p>
<p><a target="_blank" href="https://blog.ricardomendoza.dev/entendiendo-a-las-apis-restful-parte-1">Versión en español</a></p>
<h2 id="heading-part-1-how-restful-apis-came-to-be">Part 1: How RESTful APIs came to be</h2>
<h3 id="heading-the-beginning-or-rest-a-bit-of-history">The beginning (or REST: a bit of history)</h3>
<p>Before RESTful APIs, there was REST; before REST, there had to be... <em>chaos!</em></p>
<p>Back in the 90s, the number of users surfing the World Wide Web saw a rapid increase. The Internet was the new kid on the block and everyone was loving it!</p>
<p>Everyone, except programmers.</p>
<p>The development of general-purpose websites suddenly became a demanding occupation. Sooner than later, the huge growth of the web ecosystem made a big problem clear: there weren't well-defined, standardized ways of building and communicating applications throughout the Internet.</p>
<p>Luckily, several nice folks began working on this, consolidating some of the most fundamental standards of the web. One such folk, <strong>Roy Thomas Fielding</strong>, who was part of the team that specified the standards of HTTP 1.0 and 1.1, started working on a thesis about an architectural style for building and communicating systems on the Internet.</p>
<p><strong>Enter REST</strong>.</p>
<h3 id="heading-going-restful-or-rest-a-definition">Going RESTful! (or REST: a definition)</h3>
<p>Fielding presented his dissertation <em>"</em><a target="_blank" href="https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm"><em>Architectural Styles and the Design of Network-based Software Architectures</em></a><em>"</em> in 2000. There, he defined the <strong>Representational State Transfer (REST) architectural style</strong> as a set of constraints: a sort of guide for designing and building systems over the Internet.</p>
<p>We can say that REST is more about defining how to do things (an architectural style), rather than representing an implementation by itself.</p>
<p>Every piece of software that follows (all or most of) the constraints defined by the REST architectural style (aka every implementation of REST) is... <em>drum roll...</em> <strong>RESTful</strong>!</p>
<p>But, <em>what are those so-called constraints defined by REST anyway?</em> I'm glad you asked! Let's talk about the <strong>6 constraints that every RESTful implementation should follow</strong>:</p>
<ol>
<li><p><strong>Client-Server</strong>. This is our starting point: how the architecture should be. Following a client-server architecture, we must separate the user interface concerns (the client) from the data storage concerns (the server). This separation will allow every component (client or server) to evolve independently, thus, providing portability and scalability.</p>
</li>
<li><p><strong>Stateless</strong>. Having defined a client-server architecture, this second constraint states that the communication between the client and the server must be stateless: every request made by the client must contain all the information needed by the server to process it. Requests cannot rely on any context on the server: they must be independent.</p>
</li>
<li><p><strong>Cache</strong>. As a nice complement to the stateless communication between clients and servers, the cache constraint lets us tag certain resources returned by the server as cacheable or non-cacheable. A cacheable resource can be safely reused by the client for identical requests later on. This can improve speed and efficiency by reducing the number of interactions between the client and the server.</p>
</li>
<li><p><strong>Uniform Interface</strong>. This is the constraint that differentiates REST from other architectural styles. It tells us that, regardless of what resources the server is providing, there must always be a uniform interface that defines how these resources are presented and, thus, how they should be consumed by the clients. This uniform interface is, in turn, defined by four constraints:</p>
<ul>
<li><p><em>Identification of resources:</em> Every resource must be identifiable by a unique ID.</p>
</li>
<li><p><em>Manipulation of resources through representations:</em> A client should be able to manipulate resources through their representations returned by the server.</p>
</li>
<li><p><em>Self-descriptive messages:</em> Interactions between client and server should provide enough information (media-type, HTTP verb, etc.) to make clear the intention of the request.</p>
</li>
<li><p><em>Hypermedia as the engine of application state:</em> Hypertext/hyperlinks provided by the server as part of the responses should specify what can be performed next for any given resource.</p>
</li>
</ul>
</li>
<li><p><strong>Layered System</strong>. This constraint allows us to break the architecture into separate layers with a specific task each. Every layer is independent and knows nothing beyond the immediate layer they interact with. With this in mind, we can have a layer for managing authorization, for example; another one for load balancing, and so on. This also provides portability and scalability for each component on the layered system.</p>
</li>
<li><p><strong>Code-On-Demand</strong>. This last constraint is an optional one. It provides the client with the possibility to extend its functionality by downloading and executing code in the form of applets or scripts. This allows the clients to be more lightweight by reducing the features implemented directly on them.</p>
</li>
</ol>
<p>Now that we know what RESTful means, we are ready to talk about APIs, <em>RESTful APIs</em>!</p>
<h3 id="heading-defining-restful-apis-or-what-you-came-for-finally">Defining RESTful APIs (or what you came for, finally!)</h3>
<p>We're almost there!</p>
<p>With a clear idea of what REST is and what RESTful means, there's only one last bit we need to clarify: <strong>what are APIs</strong>?</p>
<p>An <strong>Application Programming Interface (API)</strong> is a set of rules that define how two pieces of software must communicate with each other. We can see it as a sort of contract that each part has to follow to transfer data between them.</p>
<p>Cool! Now we have a decent understanding of all the concepts we need to finally define a RESTful API!</p>
<p>Here's a simple definition:</p>
<p><strong>A RESTful API is a way of communicating two applications over the Internet under the constraints defined by REST</strong>. In other words, RESTful APIs are a way to define how web services present their resources and how clients should consume those resources over the Internet.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653857798942/wGjuydTCH.jpg" alt="Graphical representation of an API" /></p>
<p>So, although not exactly a standard, this implementation of REST in the form of APIs was a solution to the problem of communicating applications over the Internet. Not the only solution, though: SOAP, for instance, was already out there by the time RESTful APIs came out. But that's a story for another article...</p>
<h3 id="heading-whats-next-or-how-restful-apis-work">What's next? (or How RESTful APIs work)</h3>
<p>For the next part of the series, I'm planning on presenting a deeper explanation of how these APIs work: I'll write about how they stick to the REST constraints mentioned before, including concepts like resources, HTTP methods, etc., so that you can actually consume or even create your RESTful APIs.</p>
<p>I will finally end this series with a brief conclusion on why RESTful APIs are so useful nowadays. <em>Should you always use them? Should you not?</em></p>
<p>...</p>
<p>I hope this article helped you have a better idea of what a RESTful API is. If you have any comments or thoughts on this article or if you have a specific topic you'd like me to write about, please let me know!</p>
<p>Thank you so much for reading this far! Have a great day!</p>
<p><em>All images used in this article, including the cover, were designed specifically for this blog by</em> <a target="_blank" href="https://www.behance.net/ZafiroLuna"><em>Zafiro Luna</em></a><em>.</em></p>
]]></content:encoded></item><item><title><![CDATA[Entendiendo a las APIs RESTful parte 1]]></title><description><![CDATA[¿Estás empezando en el mundo de la programación web? ¿Has escuchado sobre las APIs RESTful? Como profesionales del desarrollo web, debemos tener un conocimiento sólido sobre las APIs RESTful, pues estas se han convertido en una herramienta fundamenta...]]></description><link>https://blog.ricardomendoza.dev/entendiendo-a-las-apis-restful-parte-1</link><guid isPermaLink="true">https://blog.ricardomendoza.dev/entendiendo-a-las-apis-restful-parte-1</guid><category><![CDATA[APIs]]></category><category><![CDATA[REST API]]></category><category><![CDATA[REST]]></category><category><![CDATA[restful]]></category><dc:creator><![CDATA[Ricardo Mendoza]]></dc:creator><pubDate>Sun, 29 May 2022 23:07:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653809216988/kXHPHWqRA.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>¿Estás empezando en el mundo de la programación web? ¿Has escuchado sobre las APIs RESTful? <strong>Como profesionales del desarrollo web, debemos tener un conocimiento sólido sobre las APIs RESTful</strong>, pues estas se han convertido en una herramienta fundamental para crear aplicaciones web en la actualidad.</p>
<p>En esta serie compartiré todo lo que sé sobre APIs RESTful: desde qué son y cómo surgieron, hasta cómo trabajan y por qué resultan convenientes para desarrollar cualquier tipo de aplicación web.</p>
<p>Si deseas crear APIs o sacar el mejor provecho de las APIs ya existentes, ¡te invito a que sigas leyendo!</p>
<p><a target="_blank" href="https://blog.ricardomendoza.dev/understanding-restful-apis-part-1">English version</a></p>
<h2 id="heading-parte-1-como-surgieron-las-apis-restful">Parte 1: Cómo surgieron las APIs RESTful</h2>
<h3 id="heading-el-inicio-o-rest-un-poco-de-historia">El inicio (o REST: un poco de historia)</h3>
<p>En la década de los 90s, el número de usuarios navegando la web aumentó drásticamente. Internet era el nuevo chico en el barrio ¡y todos lo amaban!</p>
<p>Todos, excepto los programadores.</p>
<p>El desarrollo de sitios web de propósito general se convirtió, de un momento a otro, en una ocupación demandante. Más temprano que tarde, el crecimiento acelerado del ecosistema web dejó ver un problema importante: en aquel momento no existían maneras bien definidas, estandarizadas, de construir y comunicar aplicaciones a través de Internet.</p>
<p>Afortunadamente, algunas personas comenzaron a atacar este problema, consolidando algunos de los estándares fundamentales de la web. Una de estas personas, <strong>Roy Thomas Fielding</strong>, quien fuera parte del equipo que definió los estándares de HTTP 1.0 y 1.1, comenzó a trabajar en una tesis sobre un estilo arquitectónico para construir y comunicar sistemas en Internet.</p>
<p><strong>Comienza REST</strong>.</p>
<h3 id="heading-modo-restful-o-rest-una-definicion">¡Modo RESTful! (o REST: una definición)</h3>
<p>Fielding presentó su disertación <em>"<a target="_blank" href="https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm">Architectural Styles and
the Design of Network-based Software Architectures</a>"</em> en el 2000. Ahí, definió el <strong>estilo arquitectónico de Transferencia de Estado Representacional (REST, por sus siglas en inglés)</strong> como un conjunto de reglas: una especie de guía para diseñar y construir sistemas sobre Internet.</p>
<p>Podríamos decir que REST define cómo hacer las cosas (un estilo arquitectónico) en lugar de representar una implementación por sí mismo.</p>
<p>Cualquier pieza de software que siga (todas o la mayoría de) las reglas definidas por REST (es decir, cualquier implementación de REST) es... <em>redoble de tambores...</em> ¡<strong>RESTful</strong>!</p>
<p>Pero, ¿cuáles son esas dichosas reglas definidas por REST? ¡Me alegra que lo preguntes! Hablemos, entonces, sobre las <strong>6 reglas que toda implementación de REST debe seguir</strong>:</p>
<ol>
<li><p><strong>Cliente-Servidor</strong>. Este es nuestro punto de partida: cómo debe ser la arquitectura. Siguiendo una arquitectura Cliente-Servidor, debemos separar las tareas relacionadas con la interfaz de usuario (el cliente) de las tareas del almacenamiento de datos (el servidor). Esta separación permitirá a cada componente (cliente o servidor) evolucionar de manera independiente, aportando, por lo tanto, portabilidad y escalabilidad.</p>
</li>
<li><p><strong>Carencia de Estado</strong>. Habiendo definido una arquitectura cliente-servidor, esta segunda regla indica que la comunicación entre el cliente y el servidor debe carecer de estado: cada petición hecha por el cliente debe contener toda la información que el servidor necesite para procesarla. Las peticiones no deben depender de ningún contexto en el servidor: deben de ser independientes.</p>
</li>
<li><p><strong>Caché</strong>. Como un buen complemento a la comunicación carente de estado entre clientes y servidores, esta regla nos permite etiquetar a un recurso regresado por el servidor como cacheable o no cacheable. Un recurso cacheable puede ser reutilizado sin problema por el cliente para peticiones idénticas en el futuro. Esto permite un incremento en la velocidad y la eficiencia al reducir las interacciones con el servidor.</p>
</li>
<li><p><strong>Interface Uniforme</strong>. Esta es la regla que realmente diferencia a REST de otros estilos arquitectónicos. Básicamente nos dice que, sin importar qué recurso provea el servidor, siempre debe existir una interface uniforme que defina cómo son presentados esos recursos y, por lo tanto, cómo deben ser consumidos por el cliente. Esta interface uniforme queda definida, a su vez, por 4 reglas:</p>
<ul>
<li><em>Identificación de Recursos:</em> Cada recurso debe distinguirse por un identificador único.</li>
<li><em>Manipulación de recursos a través de representaciones:</em> Un cliente debe poder manipular un recurso a través de sus representaciones, las cuáles regresa el servidor.</li>
<li><em>Mensajes auto-descriptivos:</em> Las interacciones entre el cliente y el servidor deben proveer suficiente información (tipo de medios, verbo de HTTP, etc.) para dejar clara la intensión de la petición.</li>
<li><em>Hypermedia como motor del estado de la aplicación:</em> Los hipertextos/hipervínculos proporcionados por el servidor como parte de una respuesta deben especificar qué acciones se pueden tomar en el futuro para un recurso dado.</li>
</ul>
</li>
<li><p><strong>Sistema por capas</strong>. Esta regla nos permite romper la arquitectura en capas separadas, cada una a cargo de una tarea en específico. Cada capa es independiente y no tiene conocimiento del sistema más allá de la capa aledaña con la que interactúa: son independientes. Con esto en mente, podemos tener una capa que maneje la autorización, por ejemplo; otra encargada del balanceo de carga y así sucesivamente. Esto permite aumentar la portabilidad y escalabilidad para cada componente del sistema.</p>
</li>
<li><p><strong>Código bajo demanda</strong>. Esta última regla es opcional. Le permite al cliente extender su funcionalidad descargando y ejecutando código en la forma de applets o scripts. Esto permite al cliente ser más ligero al reducir las funcionalidades implementadas directamente por él.</p>
</li>
</ol>
<p>Ahora que entendemos mejor lo que RESTful significa, estamos listos para hablar sobre APIs, <em>APIs RESTful</em>.</p>
<h3 id="heading-definiendo-las-apis-restful-o-lo-que-estabas-esperando-por-fin">Definiendo las APIs RESTful (o lo que estabas esperando, ¡por fin!)</h3>
<p>¡Casi estamos listos!</p>
<p>Ahora que tenemos una mejor idea de lo que es REST y lo que significa RESTful, sólo nos queda un concepto por revisar: <strong>¿qué es una API?</strong></p>
<p>Una <strong>Interfaz de Programación de Aplicaciones (API, por sus siglas en inglés)</strong> es un conjunto de reglas que definen cómo deben comunicarse dos piezas de software. Podemos definirla como una especie de contrato que cada parte debe seguir para poder transferir datos entre ellas.</p>
<p>¡Genial! ¡Ahora tenemos una idea clara de todos los conceptos que necesitamos para definir una API RESTful!</p>
<p>Aquí va una sencilla definición:</p>
<p><strong>Una API RESTful es una manera de comunicar dos aplicaciones en Internet bajo las reglas definidas por REST</strong>. Dicho de otro modo, las APIs RESTful definen la manera en la que los servicios web deben exponer sus recursos y cómo los clientes deben consumir dichos recursos en Internet.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653857751237/UJHJWDnCU.jpg" alt="Representación gráfica de una API" /></p>
<p>Entonces, aunque no se trata propiamente de un estándar, esta implementación de REST en la forma de APIs representó una solución al problema de comunicar dos aplicaciones en Internet. No fue la única solución, cabe aclarar: ya se hablaba de SOAP, por ejemplo, cuando las APIs RESTful apenas aparecían. Sin embargo, esa es una historia para otro artículo...</p>
<h3 id="heading-que-sigue-o-como-funcionan-las-apis-restful">¿Qué sigue? (o Cómo funcionan las APIs RESTful)</h3>
<p>Para la siguiente entrega de esta serie planeo hablar más a fondo de cómo funcionan estas APIs: escribiré a detalle sobre cómo implementan las reglas definidas por REST mencionadas anteriormente, incluyendo conceptos como recursos, métodos HTTP, etc. para que te sea más fácil construir tu propia API RESTful o consumir alguna existente.</p>
<p>Finalmente, terminaré esta serie con una breve conclusión sobre por qué las APIs RESTful son tan relevantes en la actualidad. <em>¿Deberías usarlas siempre o no?</em></p>
<p>...</p>
<p>Espero que este artículo te haya sido de utilidad para entender mejor el concepto de una API RESTful. Cualquier comentario o duda al respecto, déjamelo saber en los comentarios. De igual manera, si hay algún tema sobre el que te gustaría que escribiera, no dudes en hacérmelo saber.</p>
<p>¡Muchas gracias por leer hasta aquí! ¡Que tengas un excelente día!</p>
<p><em>Todas las imágenes utilizadas en este artículo, incluyendo la portada, fueron diseñadas específicamente para este blog por <a target="_blank" href="https://www.behance.net/ZafiroLuna">Zafiro Luna</a>.</em></p>
]]></content:encoded></item></channel></rss>