<?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[CarlosJasso.dev | Blog]]></title><description><![CDATA[I'm Carlos Jasso, a software developer, tech writer and full-time husband/dad. I'm always striving to expand both my personal and technical skills and contribute to my community.]]></description><link>https://blog.carlosjasso.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1630987351887/5YtbgiHck.png</url><title>CarlosJasso.dev | Blog</title><link>https://blog.carlosjasso.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Sun, 13 Sep 2026 21:10:33 GMT</lastBuildDate><atom:link href="https://blog.carlosjasso.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[curl - API testing made really simple]]></title><description><![CDATA[When I started learning about the HTTP protocol and had to interact with URLs and data, almost every tool that I tested either lacked proper documentation or had overly complicated instructions for something as simple as making an HTTP request. But o...]]></description><link>https://blog.carlosjasso.dev/curl-api-testing-made-really-simple</link><guid isPermaLink="true">https://blog.carlosjasso.dev/curl-api-testing-made-really-simple</guid><category><![CDATA[APIs]]></category><category><![CDATA[Testing]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Carlos Jasso]]></dc:creator><pubDate>Fri, 03 Sep 2021 15:01:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630648819727/cn5OBWbTW.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When I started learning about the HTTP protocol and had to interact with URLs and data, almost every tool that I tested either lacked proper documentation or had overly complicated instructions for something as simple as making an HTTP request. But one day, I realized that the tool that I've been using for a long time to download files from the internet could also be the greatest tool I've found so far to interact with web APIs.</p>
<blockquote>
<p><em>💡 This article assumes that you have a basic understanding of the HTTP protocol, that you know what a web API is, and that you are familiar with the CLI of your operating system.</em></p>
</blockquote>
<p>Table of contents:</p>
<ul>
<li><a class="post-section-overview" href="#the-setup">⚙The setup</a></li>
<li><a class="post-section-overview" href="#basic-curl-options">🧩 Basic curl options</a></li>
<li><a class="post-section-overview" href="#the-get-method">📩 The GET method</a></li>
<li><a class="post-section-overview" href="#the-post-method">📮 The POST method</a><ul>
<li><a class="post-section-overview" href="#sending-plain-text">🔤 Sending plain text</a></li>
<li><a class="post-section-overview" href="#query-string-parameters">🖇 Query string parameters</a></li>
<li><a class="post-section-overview" href="#sending-a-json-object">💌 Sending a JSON object</a></li>
<li><a class="post-section-overview" href="#emulating-a-form">📋 Emulating a form</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#the-other-methods">🎯 The other methods</a></li>
<li><a class="post-section-overview" href="#authentication">🔐 Authentication</a></li>
<li><a class="post-section-overview" href="#getting-creative">🤹‍♂️ Getting creative</a></li>
</ul>
<h2 id="the-setup">⚙The setup</h2>
<p>Well, just like almost every piece of software out there, curl needs to be installed on your operating system. The good news is that most likely, your system already comes with it built-in. Almost every Linux distribution comes with curl and Windows 10 also started <a target="_blank" href="https://techcommunity.microsoft.com/t5/containers/tar-and-curl-come-to-windows/ba-p/382409">shipping it from version 1803</a>, too 😉. </p>
<p>Would you like to check if your system has it? Well, let's give it the very first test drive.</p>
<p>On Windows, you may try the following command either on CMD or PowerShell:</p>
<pre><code class="lang-powershell">curl.exe --version
</code></pre>
<p>On Linux, you may try this on your terminal:</p>
<pre><code class="lang-bash">curl --version
</code></pre>
<p>The command should return some information about the curl version, libraries it counts with, release date, supported protocols and features. I'm a Linux user and in my case, I got the following output:</p>
<pre><code class="lang-text">curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3
Release-Date: 2020-01-08
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets
</code></pre>
<p>If you get an error instead, you can also download and install curl. It's free! It's available for all major operating systems out there and last time I checked, it only takes a ~5MB <a target="_blank" href="https://curl.se/download.html">download</a>.</p>
<p>If you're exploring this article but don't currently have an API handy to play with, not to worry. The <a target="_blank" href="https://httpbin.org/">httpbin</a> service is used in the examples of this post 😉.</p>
<blockquote>
<p><em>💡 Note: From this point on, bash commands will be given as examples for clarity and readability. If you are using Windows or the example snippets don't work for you, try appending <code>.exe</code> after the <code>curl</code> command or try removing the line breaks.</em></p>
</blockquote>
<h2 id="basic-curl-options">🧩 Basic curl options</h2>
<p>Using curl is pretty simple and though it can handle a plethora of different options, you might want to start by getting familiar with the following ones:</p>
<ul>
<li><code>--request</code> or <code>-X</code>: To specify the desired <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods">HTTP request method</a>. If the option is not present, curl will treat the request as GET. Example: <code>curl -X POST ...</code></li>
<li><code>--header</code> or <code>-H</code>: To include an extra header on the HTTP request. Any number of extra headers can be included. Example: <code>curl -H "X-First-Name: John" -H "X-Last-Name: Doe" ...</code></li>
<li><code>--data</code> or <code>-d</code>: To include data on the HTTP request. The data can be either included on the same command line or it can reference a text-based file to read the data from. Example: <code>curl -d "text data goes here" ...</code></li>
<li><code>--form</code> or <code>-F</code>: Lets curl emulate a filled-in form in which a user has pressed the submit button. This also enables uploading of binary files. Example: <code>curl -F name=John -F shoesize=11 ...</code></li>
<li><code>--user &lt;user:password&gt;</code> or <code>-u &lt;user:password&gt;</code>: Specify the username and password to use for server authentication.</li>
</ul>
<p>curl can present the whole HTTP request transaction with great detail in the terminal, however, I prefer it when it dumps the results into files for further review. To achieve this, you can make use of these options:</p>
<ul>
<li><code>--dump-header</code> or <code>-D</code>: Write the received protocol headers to the specified file. Example: <code>curl -D result.header ...</code></li>
<li><code>--output</code> or <code>-o</code>: Write output to the specified file instead of stdout. Example: <code>curl -o result.json ...</code></li>
</ul>
<h2 id="the-get-method">📩 The GET method</h2>
<p>Well, now that you are ready with the basics, it's time to GET the party started! 🥳</p>
<p>First, I'd recommend you to change the working directory on your CLI to one that you're familiar with such as your user directory or your desktop so that you're able to easily find the resulting files after executing the commands.</p>
<p>Let's make our very first request with:</p>
<pre><code class="lang-bash">curl -X GET <span class="hljs-string">"https://httpbin.org/get"</span> \
-H <span class="hljs-string">"accept: application/json"</span> \
-D result.headers \
-o result.json
</code></pre>
<p>On the first line, we're telling curl to perform an HTTP request with the GET method to the specified URL. On the second line, we add a header to let the server know what we'll accept as a response. On the third line, we tell curl to dump the resulting headers of our request to a file called <code>result.headers</code>. Lastly, we tell curl to write the output of the request to a file called <code>result.json</code>.</p>
<p>If everything went nice and smoothly, you should be able to see the resulting files in your working directory after executing the command. In my case, I got:</p>
<p>result.headers</p>
<pre><code class="lang-text">HTTP/2 200 
date: Thu, 02 Sep 2021 05:47:14 GMT
content-type: application/json
content-length: 169
</code></pre>
<p>In the <code>result.headers</code> file, we can see that the request went through successfully with a 200 HTTP response code, the response timestamp and all headers returned by the server. </p>
<p>result.json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"args"</span>: {}, 
  <span class="hljs-attr">"headers"</span>: {
    <span class="hljs-attr">"Accept"</span>: <span class="hljs-string">"application/json"</span>, 
    <span class="hljs-attr">"Host"</span>: <span class="hljs-string">"httpbin.org"</span>, 
    <span class="hljs-attr">"User-Agent"</span>: <span class="hljs-string">"curl/7.68.0"</span>
  },
  <span class="hljs-attr">"url"</span>: <span class="hljs-string">"https://httpbin.org/get"</span>
}
</code></pre>
<p>The <code>result.json</code> file contains the body of the response. In this case, the data that gets returned by the server following the <a target="_blank" href="https://en.wikipedia.org/wiki/JSON">JSON notation</a>.</p>
<p>Pretty neat, don't you think?</p>
<h2 id="the-post-method">📮 The POST method</h2>
<h3 id="sending-plain-text">🔤 Sending plain text</h3>
<p>This time, let's try sending a plain text message to the server by using the POST method.</p>
<pre><code class="lang-bash">curl -X POST <span class="hljs-string">"https://httpbin.org/post"</span> \
-H <span class="hljs-string">"accept: application/json"</span> \
-H <span class="hljs-string">"Content-Type: text/plain"</span> \
-H <span class="hljs-string">"Custom-Header: Testing"</span> \
-d <span class="hljs-string">"I love hashnode"</span> \
-D result.headers \
-o result.json
</code></pre>
<p>Note that we've included the header <code>"Custom-Header: Testing"</code>. It should get reflected in the body of the response.</p>
<p>result.headers</p>
<pre><code class="lang-text">HTTP/2 200 
date: Fri, 03 Sep 2021 03:16:20 GMT
content-type: application/json
content-length: 182
</code></pre>
<p>result.json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"data"</span>: <span class="hljs-string">"I love hashnode"</span>, 
  <span class="hljs-attr">"headers"</span>: {
    <span class="hljs-attr">"Accept"</span>: <span class="hljs-string">"application/json"</span>, 
    <span class="hljs-attr">"Content-Length"</span>: <span class="hljs-string">"15"</span>, 
    <span class="hljs-attr">"Content-Type"</span>: <span class="hljs-string">"text/plain"</span>, 
    <span class="hljs-attr">"Custom-Header"</span>: <span class="hljs-string">"Testing"</span>
  }
}
</code></pre>
<p>Did you notice that the server received the message along with the testing header and echoed them? That means curl was able to send the data we wanted it to.</p>
<h3 id="query-string-parameters">🖇 Query string parameters</h3>
<p>Not only sending plain text is supported by curl but also query string parameters are supported:</p>
<pre><code class="lang-bash">curl -X POST <span class="hljs-string">"https://httpbin.org/post?name=Carlos&amp;last=Jasso"</span> \
-H <span class="hljs-string">"accept: application/json"</span> \
-D result.headers \
-o result.json
</code></pre>
<p>result.headers</p>
<pre><code class="lang-text">HTTP/2 200 
date: Fri, 03 Sep 2021 03:30:47 GMT
content-type: application/json
content-length: 120
</code></pre>
<p>result.json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"args"</span>: {
    <span class="hljs-attr">"lastname"</span>: <span class="hljs-string">"Jasso"</span>, 
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Carlos"</span>
  }, 
  <span class="hljs-attr">"headers"</span>: {
    <span class="hljs-attr">"Accept"</span>: <span class="hljs-string">"application/json"</span>
  }
}
</code></pre>
<p>Whoa! The server echoed the parameters curl sent to it over the query string.</p>
<h3 id="sending-a-json-object">💌 Sending a JSON object</h3>
<p>Let's give curl another task and make it send a json file to the server and see what happens:</p>
<pre><code class="lang-bash">curl -X POST <span class="hljs-string">"https://httpbin.org/post"</span> \
-H <span class="hljs-string">"Content-Type: application/json; charset=utf-8"</span> \
-d @data.json \
-o result.json
</code></pre>
<p>This time, we're including a header to let the server know we're sending a json file. The data file path gets specified to curl with the <code>-d</code> option followed by an at sign <code>@</code> and the path to the file. </p>
<p>Here's the content of the <code>data.json</code> file for you to create it on your working directory:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Jane"</span>,
    <span class="hljs-attr">"last"</span>: <span class="hljs-string">"Doe"</span>
}
</code></pre>
<p>result.json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"data"</span>: <span class="hljs-string">"{    \"name\": \"Jane\",    \"last\": \"Doe\"}"</span>, 
  <span class="hljs-attr">"headers"</span>: {
    <span class="hljs-attr">"Accept"</span>: <span class="hljs-string">"*/*"</span>, 
    <span class="hljs-attr">"Content-Length"</span>: <span class="hljs-string">"38"</span>, 
    <span class="hljs-attr">"Content-Type"</span>: <span class="hljs-string">"application/json; charset=utf-8"</span>
  }, 
  <span class="hljs-attr">"json"</span>: {
    <span class="hljs-attr">"last"</span>: <span class="hljs-string">"Doe"</span>, 
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Jane"</span>
  }
}
</code></pre>
<p>Yet again, curl was able to send the JSON file content to the server as we can see the data echoed on the response. Kudos for curl!</p>
<h3 id="emulating-a-form">📋 Emulating a form</h3>
<p>Sometimes, you might want to emulate submitting a form and curl can make that possible:</p>
<pre><code class="lang-bash">curl -X POST <span class="hljs-string">"https://httpbin.org/post"</span> \
-H <span class="hljs-string">"Content-Type: multipart/form-data"</span> \
-F <span class="hljs-string">"FavoriteFood=Pizza"</span> \
-F <span class="hljs-string">"FavoriteBeverage=Beer"</span> \
-o result.json
</code></pre>
<p>For curl to specify to the server that what's being sent is form data, you can use a request header with the appropriate form MIME type as seen above and use the <code>-F</code> parameter for each of the form fields and values. </p>
<p>result.json</p>
<pre><code class="lang-json">{ 
  <span class="hljs-attr">"form"</span>: {
    <span class="hljs-attr">"FavoriteBeverage"</span>: <span class="hljs-string">"Beer"</span>, 
    <span class="hljs-attr">"FavoriteFood"</span>: <span class="hljs-string">"Pizza"</span>
  }, 
  <span class="hljs-attr">"headers"</span>: {
    <span class="hljs-attr">"Accept"</span>: <span class="hljs-string">"*/*"</span>, 
    <span class="hljs-attr">"Content-Length"</span>: <span class="hljs-string">"261"</span>, 
    <span class="hljs-attr">"Content-Type"</span>: <span class="hljs-string">"multipart/form-data;"</span>
  }
}
</code></pre>
<p>In the result, we can confirm that the server received a form and interpreted each of its fields correctly.</p>
<h3 id="sending-a-file">🖼 Sending a file</h3>
<p>So far, we've given curl lightweight work. How about sending a file on this round? Files are sent in a similar way forms are emulated. Would you like to copy any image to your working directory and try to send it?</p>
<pre><code class="lang-bash">curl -X POST <span class="hljs-string">"https://httpbin.org/post"</span> \
-H <span class="hljs-string">"Content-Type: multipart/form-data"</span> \
-F <span class="hljs-string">"FileComment=This is a JPG file"</span> \
-F <span class="hljs-string">"image=@image.jpg"</span> \
-o result.json
</code></pre>
<p>result.json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"files"</span>: {
    <span class="hljs-attr">"image"</span>: <span class="hljs-string">"data:image/jpeg;base64,/9j/4AAQSkZJ..."</span>
  }, 
  <span class="hljs-attr">"form"</span>: {
    <span class="hljs-attr">"FileComment"</span>: <span class="hljs-string">"This is a JPG file"</span>
  }, 
  <span class="hljs-attr">"headers"</span>: {
    <span class="hljs-attr">"Accept"</span>: <span class="hljs-string">"*/*"</span>, 
    <span class="hljs-attr">"Content-Length"</span>: <span class="hljs-string">"78592"</span>, 
    <span class="hljs-attr">"Content-Type"</span>: <span class="hljs-string">"multipart/form-data;"</span>
  }
}
</code></pre>
<p>It might take some time for the file to upload but in the end, the server will return the same file we sent to it (base64 encoded). curl has correctly handled every request we've built with it so far.</p>
<h2 id="the-other-methods">🎯 The other methods</h2>
<p>I've tested as many HTTP request methods as I've been able to think of with curl and all of them have worked splendidly. After all, what the API does with each request may vary depending on the implementation of the method. </p>
<h2 id="authentication">🔐 Authentication</h2>
<p>curl can handle server authentication when accessing a URL that requires the user to input credentials. In this case, httpbin receives the expected username and password through the URL with the format <code>/basic-auth/{user}/{passwd}</code> to match the values with the inputted credentials. This is what happens if said credentials are not entered:</p>
<pre><code class="lang-bash">curl -X GET <span class="hljs-string">"https://httpbin.org/basic-auth/carlos/secret"</span> \
-H <span class="hljs-string">"accept: application/json"</span> \
-D result.headers
</code></pre>
<p>result.headers</p>
<pre><code class="lang-text">HTTP/2 401 
date: Fri, 03 Sep 2021 04:08:44 GMT
content-length: 0
</code></pre>
<p>Dang! got a 401 (unauthorized) 🤔 </p>
<p>Oh right, we forgot to include our credentials. Let's include them in the options:</p>
<pre><code class="lang-bash">curl -X GET <span class="hljs-string">"https://httpbin.org/basic-auth/carlos/secret"</span> \
-u carlos:secret
-H <span class="hljs-string">"accept: application/json"</span> \
-D result.headers
</code></pre>
<p>result.headers</p>
<pre><code class="lang-text">HTTP/2 200 
date: Fri, 03 Sep 2021 04:14:19 GMT
content-type: application/json
content-length: 48
</code></pre>
<p>result.json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"authenticated"</span>: <span class="hljs-literal">true</span>, 
  <span class="hljs-attr">"user"</span>: <span class="hljs-string">"carlos"</span>
}
</code></pre>
<p>Yes! got logged in 😎. </p>
<p>Another common authentication method is bearer tokens but they tend to be added within a header and we have already covered that case so, I bet an example for those can be skipped.</p>
<h2 id="getting-creative">🤹‍♂️ Getting creative</h2>
<p>How have you liked curl so far? Do you think it's useful? Wait until I let you know about some extra suggestions I think you might also like.</p>
<p>I've seen that common API testing tools are free as well, but they put price tags on their collaboration features and that's fine. That's how they raise funds to keep their motors running but people like me who prefer free products and services might want to look somewhere else. What I like to do is to have API documentation on markdown files on a git repo like <a target="_blank" href="https://github.com/carlosjasso/blog-examples/tree/trunk/docs/curl_API-testing-made-really-simple">this one</a> and share them with other people. To me, that enables collaboration with curl without having to spend a single cent.</p>
<p>Also, other tools offer sophisticated GUIs but I find most of them to be too cluttered. I like simplicity and if you do, too, I'd recommend using <a target="_blank" href="https://code.visualstudio.com/">VSCode </a> if you're not using it already. I think VSCode + curl just make a perfect match ❤</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630644229526/1poN-lyIw.png" alt="curl-workflow.png" /></p>
<p>That's the workflow I normally use. You can see the rendered markdown document to the left, my <code>result.headers</code> &amp; <code>result.json</code> to the right and a terminal at the bottom to enter all my pre-designed commands. What do you think about it?</p>
<p>Do you think curl can only work fine with the REST architecture? well, I've also had the chance to use it to test SOAP with the same great results. I'm just waiting to have a new scenario to put curl to the test 🤓.</p>
<hr />
<p>I hope this post has been both fun and useful to you. Now, you know how to take advantage of curl for your API testing purposes plus you'll also look like those hackers shown on TV when you're using your terminal and text-based tools at work. If that isn't cool, I don't know what is.</p>
<p>If you'd like to become a curl guru and keep learning about it, I'd encourage you to visit its <a target="_blank" href="https://curl.se/docs/">documentation page</a>. There's really a vast number of different scenarios it can be used for.</p>
<blockquote>
<p>Fun fact: I don't know how to use Postman.</p>
</blockquote>
<p>👋</p>
<p><sub><sup>
<strong>Cover Credits: </strong>
<a href="https://www.freepik.com/vectors/computer">Computer vector created by upklyak - www.freepik.com</a> | 
https://commons.wikimedia.org/wiki/File:Curl-logo.svg, curl contributors, MIT <a target="_blank" href="http://opensource.org/licenses/mit-license.php">http://opensource.org/licenses/mit-license.php</a>, via Wikimedia Commons
</sup></sub></p>
]]></content:encoded></item><item><title><![CDATA[How to set a good project file structure]]></title><description><![CDATA[A common problem among software developers is having to decide where to put the source code, images, libraries, documentation or anything else inside of a project directory. And though it's a common issue, it's also fairly easy to tackle by having in...]]></description><link>https://blog.carlosjasso.dev/how-to-set-a-good-project-file-structure</link><guid isPermaLink="true">https://blog.carlosjasso.dev/how-to-set-a-good-project-file-structure</guid><category><![CDATA[System Architecture]]></category><category><![CDATA[best practices]]></category><dc:creator><![CDATA[Carlos Jasso]]></dc:creator><pubDate>Wed, 24 Mar 2021 15:09:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1614634740397/zNy2eVbTH.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A common problem among software developers is having to decide where to put the source code, images, libraries, documentation or anything else inside of a project directory. And though it's a common issue, it's also fairly easy to tackle by having in mind a set of "best practices" so that the project ends up happily living in its container folder and a developer can enjoy a comprehensible navigation within it.</p>
<blockquote>
<p>⚠ Disclaimer: This article does not provide a CORRECT nor a SUBLIME way of doing things. Instead, it provides tips based on the writer's experience.</p>
</blockquote>
<h2 id="the-root-of-the-file-tree">🌱 The root of the file tree</h2>
<p>In order to end up with a usable project file structure, this article will guide you on the definition of one meant to be used by a react application. We'll begin with the very root of the directory assuming that an NPM package has already been initiated. It should look like this:</p>
<pre><code class="lang-text">.                   &lt;-- represents the directory root
└── package.json    &lt;-- NPM package definition
</code></pre>
<p>It's so clean and perfect to this point but extra stuff needs to go inside of it. This root of the project's directory should be used to allocate files that might not be totally necessary for the final project's product but for the developer to know that to work with and tools to know how to act like. Here's a list of example files one can commonly find in this location:</p>
<ul>
<li>📃 <strong>README</strong> - Documentation about the project itself. It may contain the purpose of the project, description of its functionality, documentation on build steps, etc.</li>
<li>⚖ <strong>LICENSE</strong> - Specifies how the project can be used or distributed along with its constraints to do so.</li>
<li>🙅‍♂️ <strong>IGNORE</strong> - This is commonly found when there's a version control system set on the project. If Git is being used, the file <code>.gitignore</code> could be included.</li>
<li>⚙ <strong>CONFIG</strong> - Depending on the project you're building, you might find tools configurations on the root directory, too. For example, if the project is a .net application, it's common to find an <code>.sln</code> file, if the project is a nodejs application using typescript, a bundler such as webpack and the documents get automatically formatted by Prettier, you may find files such as <code>tsconfig.json</code>, <code>webpack.config.js</code> and <code>.prettierrc</code> respectively.</li>
<li>♻ <strong>ENVIRONMENT</strong> - Some projects may rely on environment variables. Most of the times, these variables are defined in the root directory. For example, the Azure Functions Core Tools rely on a <code>local.settings.json</code> file for this purpose while NodeJS relies on <code>.env</code> files instead.</li>
</ul>
<p>A root directory hosting some the aforementioned examples may look similar to this:</p>
<pre><code class="lang-text">.
├── .env.development
├── .gitignore
├── LICENSE
├── README.md
├── package.json
├── tsconfig.json
└── webpack.config.js
</code></pre>
<p>As you may notice, none of the files are really needed by a project's final product but they are important for a developer to work on the project. Any other files that have similar purposes should be stored on the root the project's directory to avoid losing track of them or get them mixed up with the project's actual source code.</p>
<h2 id="project-sub-directories">🗃 Project sub-directories</h2>
<p>It's common to find several sub-directories in a project, and each of them serves a different purpose. It totally depends on the kind of project you're building but usually one can find a structure similar to the following:</p>
<ul>
<li>⚙ <strong>.DIRECTORIES</strong> - Many tools depend on more than a single configuration file and instead of storing a dot-file on the root of the project's directory, they may create a sub-directory with its name starting with a "." (dot) to store their configurations in a single place. Good examples you may be familiar with are VSCode and Git bucease if you're making use of them, you for sure can find the <code>.vscode</code> and <code>.git</code> directories in your project. </li>
<li>🤹‍♂️ <strong>ASSETS</strong> - Contains files that may not need modifications and can be simply copied as part of the project's resulting output. Common files that are stored here are favicons, avatar pictures, type fonts, manifests, re-distributable scripts, etc. Common names used for this directory are <code>assets</code>, <code>resources</code> and <code>static</code>.</li>
<li>📚 <strong>DOCUMENTATION</strong> - You may know every bolt and nut holding your project together but when you plan to share it with other developers, it's a very good practice to let them know how the project works, looks, gets used and gets built via written documentation. Frequently, this directory is named <code>docs</code>.</li>
<li>🍔 <strong>OUTPUT</strong> - The project gets compiled and its resulting product is usually put apart from the source code in a specific directory so that it can be easily grabbed. Usual names for this directory can be <code>out</code>, <code>result</code>, <code>public</code>, <code>dist</code> and <code>bin</code>. Also, it's customary to exclude this directory from source version control systems like Git.</li>
<li>👨‍💻 <strong>SOURCE CODE</strong> - Here's where the golden nuggets, the jewels, the juicy stuff gets stored at. More to come about this special directory below 😉. An habitual name for this directory is <code>src</code>.</li>
<li>🧪 <strong>TESTS</strong> - Another good practice among developers is to create and share automated tests for our project. This helps ensure that what the project is aimed to do is actually what it does. Most tests are written code, too. But mixing the tests code with the source code can crate confusion, so, it's better to separate them and give them their own place. <code>test</code> is a very common name for this directory.</li>
</ul>
<p>Here's an example of a project directory containing some of the sections mentioned above:</p>
<pre><code class="lang-text">.
├── assets
│   ├── avatar.jpg
│   └── favicon.ico
├── docs
│   ├── README.md
│   ├── api-reference.md
│   └── build.md
├── out
├── src
│   ├── app.tsx
│   ├── footer.tsx
│   └── nav.tsx
├── test
│   ├── app.test.js
│   └── nav.test.js
├── .env.development
├── .gitignore
├── LICENSE
├── README.md
├── package.json
├── tsconfig.json
└── webpack.config.js
</code></pre>
<h2 id="source-code-file-structure">👨‍💻 Source Code file structure</h2>
<h3 id="the-layered-approach">🥪 The layered approach</h3>
<p>Not all applications will have the same structure, but they all can be divided into "concern layers." For example, when developing an API, you may want to include all <code>controllers</code> into their own directory with a separate business logic within a <code>services</code> directory and data definitions within a <code>models</code> directory. This to aim for a better understanding of the project structure, scalability and ease of maintenance.</p>
<p>Another example is a desktop application wherein a <code>UI</code> directory may hold all window designs but a <code>services</code> directory would feature all business logic, a <code>models</code> directory could hold all data definitions and a <code>data</code> directory all database transactions logic.</p>
<p>With this approach in mind, we can elaborate our <code>src</code> directory on our structure and add a <code>pages</code> directory for entities that will make use of several modules at a time, a <code>layouts</code> directory for pages "themes", a <code>modules</code> directory where entities of the app are defined such as a header, welcome, posts list, footer, etc. All these make the <code>src</code> directory look similar to this:</p>
<pre><code class="lang-text">src
├── layouts
├── models
├── modules
│   ├── footer
│   ├── header
│   └── post-list
└── pages
</code></pre>
<h3 id="solid-principles">💎 SOLID principles</h3>
<p>These principles mainly apply to Object Oriented Programming but taking them as guidance will also give you a nice result with other methodologies.</p>
<ul>
<li><strong>S</strong>ingle responsibility: A class should only have a single responsibility. That is, is should only affect a single specification of a program.</li>
<li><strong>O</strong>pen-Closed principle: Software entities such as classes, modules, functions, etc. Should be open to be extended in functionality without having to be modified at their source code level.</li>
<li><strong>L</strong>iskov substitution principle: Taking <code>S</code> as a subtype of <code>T</code>, objects of type <code>T</code> may be replaced by objects of type <code>S</code> without the program suffering a change on its desired properties.</li>
<li><strong>I</strong>nterface segregation principle: Have you ever had a bad experience using a "universal" remote control? Well, the same thing happens with programming; a remote control may be thought like an interface for controlling a device such as a TV. The interface defines the actions that a recipient of it can do. This principle states that a recipient or client should not be forced to feature an action it's not going to use, therefore, it's always better to have several small interfaces rather than a big one.</li>
<li><strong>D</strong>ependency inversion principle: The summary of this principle is "High level objects should not depend on low level implementations." This is, any high-level entity in a program should be able to work under several scenarios and its functionality should be dependent of low-level implementations. For example, a "User Administration" module should be able to take care of its business without being dependent of a "User" class where features such as name, age, registration date or other data is defined. This same module should be able to leverage the task of saving data to a database by receiving the indication to do so, but the actual task should be delegated to a low-level class that takes care of saving the information.</li>
</ul>
<p><strong><em>More about this <a target="_blank" href="https://en.wikipedia.org/wiki/SOLID.">here</a></em></strong></p>
<p>Knowing this, we can then think of adding files to the <code>src</code> directory sub-paths like this:</p>
<pre><code class="lang-text">src
├── layouts
│   ├── blog-layout.tsx
│   ├── common-layout.tsx
│   └── home-layout.tsx
├── models
│   ├── blog-post.ts
│   └── navbar-item.ts
├── modules
│   ├── footer
│   │   ├── clickable-icon.tsx
│   │   ├── external-links.tsx
│   │   ├── index.tsx
│   │   └── site-sections.tsx
│   ├── header
│   │   ├── index.tsx
│   │   ├── logo.tsx
│   │   ├── menu-button.tsx
│   │   ├── nav-button.tsx
│   │   └── navbar.tsx
│   └── post-list
│       ├── index.tsx
│       ├── list.tsx
│       └── post-card.tsx
└── pages
    ├── about.tsx
    ├── blog.tsx
    ├── error404.tsx
    └── home.tsx
</code></pre>
<hr />
<p>I hope you've enjoyed this article. Now, you have a couple of guidance points to follow when having to design a project's file structure.</p>
<p><sup><sub>
<strong>Cover credits: </strong>
Diagram made with <a href="https://www.diagrams.net/">diagrams.net</a> | <a href="https://www.freepik.com/vectors/banner">Banner vector created by pch.vector - www.freepik.com</a> | 
<a target="_blank" href="https://github.com/tonsky/FiraCode">FiraCode</a>
</sub></sup></p>
]]></content:encoded></item><item><title><![CDATA[How to setup an NPM package]]></title><description><![CDATA[Every time you'd like to start building a Node app from scratch, it's highly recommended for you to setup an NPM package so that your app can be easily managed and maintained either by you or other developers.

💡 This article assumes that both Node ...]]></description><link>https://blog.carlosjasso.dev/how-to-setup-an-npm-package</link><guid isPermaLink="true">https://blog.carlosjasso.dev/how-to-setup-an-npm-package</guid><category><![CDATA[Node.js]]></category><category><![CDATA[npm]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Carlos Jasso]]></dc:creator><pubDate>Tue, 16 Feb 2021 03:56:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1613178357116/NYhMo_HmL.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every time you'd like to start building a Node app from scratch, it's highly recommended for you to setup an NPM package so that your app can be easily managed and maintained either by you or other developers.</p>
<blockquote>
<p>💡 This article assumes that both Node and NPM are already installed on your operating system. If not, you might want to head up to this <a target="_blank" href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm">other article</a> before you continue on this one.</p>
</blockquote>
<p><strong>Table of contents:</strong></p>
<ul>
<li><a class="post-section-overview" href="#create-a-directory-for-the-app-to-live-in">📁 Create a directory for the app to live in</a></li>
<li><a class="post-section-overview" href="#initialize-the-npm-package">📦 Initialize the NPM package</a></li>
<li><a class="post-section-overview" href="#anatomy-of-the-packagejson-file">🔬 Anatomy of the <code>package.json</code> file</a></li>
<li><a class="post-section-overview" href="#taking-a-shortcut">🤓 Taking a shortcut</a></li>
<li><a class="post-section-overview" href="#dependency-version-specification">🧩 Dependency version specification</a></li>
</ul>
<h2 id="create-a-directory-for-the-app-to-live-in">📁 Create a directory for the app to live in</h2>
<p>The package will hold everything for your app. This includes: source code, configurations, assets and even documentation. Everything co-exists in a directory together, and it can be manually created. You may use your favorite directory creation method. The only recommendation for you is not to use spaces on the directory's name. Why? well, this will make it easier to navigate and prevent errors in some scenarios. Once the directory is created, go inside of it:</p>
<pre><code class="lang-txt">mkdir react-from-scratch &amp;&amp; cd react-from-scratch
</code></pre>
<h2 id="initialize-the-npm-package">📦 Initialize the NPM package</h2>
<p>An NPM package depends a lot on a very important file called <code>package.json</code>. It stores information about the package using the <a target="_blank" href="https://en.wikipedia.org/wiki/JSON#Syntax">JSON syntax</a> and though it supports several standard keys/properties, only 2 of them are required: <code>"name"</code> and <code>"version"</code>. </p>
<p>One can create and fill this file manually but fortunately, NPM comes with a built-in initializer for this file that helps a lot. To bring it up, one has to use following CLI command:</p>
<pre><code class="lang-txt">npm init
</code></pre>
<p>When this command is invoked, a questionnaire gets prompted for you to help the initializer fill the document. The questions are shown on your CLI one by one and they look like this:</p>
<pre><code class="lang-txt">package name: (react-from-scratch)
version: 0.0.1
description: Very cool react app built from scratch
entry point: src/app.tsx
test command:
git repository: &lt;url-to-git-repo&gt;
keywords: react typescript sass
author: Carlos Jasso
license: MIT
</code></pre>
<p>and the resulting file contains this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"react-from-scratch"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Very cool react app built from scratch"</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"src/app.tsx"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>
  },
  <span class="hljs-attr">"keywords"</span>: [
    <span class="hljs-string">"react"</span>,
    <span class="hljs-string">"typescript"</span>,
    <span class="hljs-string">"sass"</span>
  ],
  <span class="hljs-attr">"author"</span>: <span class="hljs-string">"Carlos Jasso"</span>,
  <span class="hljs-attr">"license"</span>: <span class="hljs-string">"MIT"</span>
}
</code></pre>
<h2 id="anatomy-of-the-packagejson-file">🔬 Anatomy of the <code>package.json</code> file</h2>
<p>Have you noticed that some values are given within parenthesis? Those are the default values that the initializer will write to the <code>package.json</code> if you just hit the <code>ENTER</code> key when the question prompts for the answer. You can change those values to anything of your preference.</p>
<p>Each of the fields represents the following:</p>
<ul>
<li><code>"name"</code>: contains your package's name. It must be written in lowercases, not include spaces but it may contain hyphens or underscores. Its default value is the directory's name.</li>
<li><code>"version"</code>: this value must be in the <code>&lt;MajorRelease&gt;.&lt;MinorRelease&gt;.&lt;PatchRelease&gt;</code> form or <code>x.x.x</code>. Its default value is <code>1.0.0</code>.</li>
<li><code>"description"</code>: self explanatory, right? its value can even be an empty string <code>""</code> (default).</li>
<li><code>"main"</code>: it references the file that the assembly starts with. Commonly, one can find this field with the values <code>"index.js"</code>, <code>"app.js"</code>, <code>"my-app-name.js"</code>. If you're not sure what to fill this with, you may as well leave it blank and will cause no harm.</li>
<li><code>"scripts"</code>: its value is a nested json object with key/value entries for each of the "actions" needed to execute the package (or app) in one or other way. It by default has a <code>"test"</code> script that simply  prints <code>Error: no test specified</code> to your CLI when executed.</li>
<li><code>"keywords"</code>: an array of words that can be used to describe the package. It's common to find the names of the technologies involved in the project and by default, it's an empty value.</li>
<li><code>"author"</code>: so that it's easy to find out whom a package was created by, it's convenient to add the author's information. It's suggested to follow the format <code>&lt;Name&gt; &lt;email@example.com&gt; &lt;http://example.com)&gt;</code> but just adding your name should be enough. An empty value is included by default.</li>
<li><code>"license"</code>: a license should be specified to let people know how they are allowed to use your package and what constraints you've set for it. The value must be a <a target="_blank" href="https://spdx.org/licenses/">SPDX license identifier</a> which default value is <code>"ISC"</code>.</li>
</ul>
<h2 id="taking-a-shortcut">🤓 Taking a shortcut</h2>
<p>At this far, you may be wondering if there's a quicker way to create the <code>package.json</code> file. Fortunately, there's a way to indicate the NPM initializer to answer all the questions of the questionnaire with their default values. This is done by passing the <code>-y</code> argument to the command like this:</p>
<pre><code class="lang-text">npm init -y
</code></pre>
<p>but this may not be as fun as entering your own data.</p>
<h2 id="dependency-version-specification">🧩 Dependency version specification</h2>
<p>Most of the times, NODE apps are not only composed by the source code written by a developer but they also feature several packages written by others. In order to keep every dependency neat and tidy, whether they get used on the final product or only during build-time, the <code>package.json</code> file features a section where those dependencies are specified:</p>
<pre><code class="lang-json">{
  ...,
  <span class="hljs-attr">"dependencies"</span>: {
    <span class="hljs-attr">"react"</span>: <span class="hljs-string">"^17.0.1"</span>,
    <span class="hljs-attr">"react-dom"</span>: <span class="hljs-string">"~17.0.0"</span>
  },
  <span class="hljs-attr">"devDependencies"</span>: {
    <span class="hljs-attr">"ts-loader"</span>: <span class="hljs-string">"8.0.0"</span>,
    <span class="hljs-attr">"typescript"</span>: <span class="hljs-string">"&gt;=4.1.0"</span>,
    <span class="hljs-attr">"webpack"</span>: <span class="hljs-string">"&lt;=5.0.0"</span>,
    <span class="hljs-attr">"webpack-cli"</span>: <span class="hljs-string">"~4.5.0"</span>
  }
}
</code></pre>
<p>Commonly, the name and version of each dependency is included in the <code>package.json</code> file and NPM will know what package to look for. Also, the path to a tarball or git URL can be specified.</p>
<p>The version value of a dependency is written in a rather specific notation that is pretty easy to understand:</p>
<ul>
<li><code>version</code>: (no special characters) must match <code>version</code> exactly.</li>
<li><code>&gt;version</code>: must be greater than <code>version</code>.</li>
<li><code>&gt;=version</code>: must be greater than or equal to <code>version</code>.</li>
<li><code>&lt;version</code>: must be lower than <code>version</code>.</li>
<li><code>&lt;=version</code>: must be lower than or equal to <code>version</code>.</li>
<li><code>~version</code>: approximately equivalent to <code>version</code>. Allow patch-level or minor-level changes.</li>
<li><code>^version</code>:  allow upgrades compatible with <code>version</code>.</li>
<li><code>1.2.x</code>: could be <code>1.2.0</code>, <code>1.2.1</code>, etc., but not <code>1.3.0</code>.</li>
<li><code>*</code>: matches any version</li>
<li><code>""</code>: (empty string) same as <code>*</code></li>
<li><code>version1 - version2</code>: same as <code>&gt;=version1 &lt;=version2</code>.</li>
<li><code>range1 || range2</code>: passes if either <code>range1</code> or <code>range2</code> are satisfied.</li>
</ul>
<p>At first, you may find that the <code>package.json</code> file doesn't contain neither a <code>"dependencies"</code> nor a <code>"devDependencies"</code> section, and that's because those sections aren't included when the file gets first initialized, however, it's important to know what these two sections are used for.</p>
<hr />
<p>I hope you've found this article to be useful. Now you know how to properly initialize an NPM package and understand the contents of a <code>package.json</code> file a bit better.</p>
<p>If you'd like to go deeper into the topic, you may want to give this <a target="_blank" href="https://docs.npmjs.com/cli/v6/configuring-npm/package-json">awesome document</a> a read.</p>
<blockquote>
<p>fun fact: this is my very first published article ever.</p>
</blockquote>
<p><sub><sup>
<strong>Cover Credits: </strong>
<a href="https://www.freepik.com/psd/mockup">Mockup psd created by freepik - www.freepik.com</a> | 
<a href="https://commons.wikimedia.org/wiki/File:Npm-logo.svg">Boboss74</a>, <a href="https://creativecommons.org/licenses/by-sa/4.0">CC BY-SA 4.0</a>, via Wikimedia Commons
</sup></sub></p>
]]></content:encoded></item></channel></rss>