<?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: KyleJB</title>
    <description>The latest articles on DEV Community by KyleJB (@kylejb).</description>
    <link>https://dev.to/kylejb</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%2F450476%2F8a1c0faf-fab1-4e0e-af10-9f3fe12323ec.jpeg</url>
      <title>DEV Community: KyleJB</title>
      <link>https://dev.to/kylejb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kylejb"/>
    <language>en</language>
    <item>
      <title>A key difference between .then() and async-await in JavaScript</title>
      <dc:creator>KyleJB</dc:creator>
      <pubDate>Thu, 10 Sep 2020 17:52:31 +0000</pubDate>
      <link>https://dev.to/kylejb/a-key-difference-between-then-and-async-await-in-javascript-53e9</link>
      <guid>https://dev.to/kylejb/a-key-difference-between-then-and-async-await-in-javascript-53e9</guid>
      <description>&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%2Fmedia.sparkpost.com%2Fuploads%2F2016%2F11%2FHow-To-Handle-Async-Email-600x300.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%2Fmedia.sparkpost.com%2Fuploads%2F2016%2F11%2FHow-To-Handle-Async-Email-600x300.png" alt="Picture of Asynchronous processes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Asynchronous code can be frustrating when its behaviors are not fully understood.  In JavaScript, &lt;code&gt;.then()&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; are the most commonly used functions for handling asynchronous nature of a &lt;code&gt;Promise&lt;/code&gt;.  I'd like to take a stab at demystifying some of the quirks that make JavaScript feel "weird" in order to help us take full advantage of asynchrony. &lt;/p&gt;




&lt;p&gt;When learning all about &lt;code&gt;fetch()&lt;/code&gt; and the &lt;code&gt;Promise&lt;/code&gt; &lt;code&gt;fetch()&lt;/code&gt; returns, I was introduced to JavaScript's &lt;code&gt;.then()&lt;/code&gt;function as a means of handling the asynchronous nature of a &lt;code&gt;Promise&lt;/code&gt;.  So, what's the deal with &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt;? Is it just syntactic sugar to avoid &lt;code&gt;.then()&lt;/code&gt;'s callback hell? Searching "async vs .then" in google produces front page results such as this &lt;a href="https://stackoverflow.com/a/54497100" rel="noopener noreferrer"&gt;stackoverflow post&lt;/a&gt;. But, as we all come to know on our coding journey, the devil is in the details... &lt;/p&gt;

&lt;p&gt;In order to examine the behaviors of &lt;code&gt;async-await&lt;/code&gt; and &lt;code&gt;then&lt;/code&gt;, I built a small program. First, we need to create a database (I used &lt;code&gt;json-server&lt;/code&gt;) to make our fetch requests.&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%2Fi%2F0ek13iysx7ewvmwq8hos.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%2Fi%2F0ek13iysx7ewvmwq8hos.png" alt="Sample Database to Fetch from on localhost:3000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, we need to write two functions that are practically identical save for one detail - one has to use &lt;code&gt;then&lt;/code&gt; and the other has to use &lt;code&gt;async-await&lt;/code&gt;. Take note of the carefully placed &lt;code&gt;console.log&lt;/code&gt;s , as we will be tracking their appearances shortly.&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%2Fi%2Fkcvwu91rrynij5jkgnr7.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%2Fi%2Fkcvwu91rrynij5jkgnr7.png" alt="Fetch with .then()"&gt;&lt;/a&gt;&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%2Fi%2Fcppdbtrd73xktv0qt1na.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%2Fi%2Fcppdbtrd73xktv0qt1na.png" alt="Fetch with async-await"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Towards the bottom of the file, I added two additional &lt;code&gt;console.log&lt;/code&gt;s wrapped around my invocation of the aforementioned function, I run both separately like so:&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%2Fi%2Ftf4kofma9xrt1gsy414s.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%2Fi%2Ftf4kofma9xrt1gsy414s.png" alt="Code snippet of how I call each function separately"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Before you read further, what order will the &lt;code&gt;console.log&lt;/code&gt;s come out in? Do take into account the &lt;code&gt;console.log&lt;/code&gt;s within the function definition themselves too...&lt;/p&gt;

&lt;p&gt;The results!&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%2Fi%2Fdqss5vnhqmi6ikiadaen.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%2Fi%2Fdqss5vnhqmi6ikiadaen.png" alt="Output of console.logs after running function with .then()"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice how &lt;code&gt;then&lt;/code&gt; runs through the entire function and then continues the execution after the function invocation before returning back to the function to perform the series of &lt;code&gt;then&lt;/code&gt; operations after the &lt;code&gt;Promise&lt;/code&gt; was resolved?&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%2Fi%2F278b7kswgxjlk9lpxfn9.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%2Fi%2F278b7kswgxjlk9lpxfn9.png" alt="Output of console.logs after running function with async-await"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contrasting this with Async/Await, the function halts execution within the function scope continues to execute other tasks that follow its invocation before stepping back into the promise upon its resolution; this behavior will continue until all Promises are resolved.&lt;/p&gt;

&lt;p&gt;Pan Wangperawong, quoted below, summarizes the differences succinctly in &lt;a href="https://dev.to/pan/when-to-use-async-await-vs-then-with-promises-1gb7"&gt;his blog post&lt;/a&gt;, which I encourage you to check out if you'd like more context.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;async-await&lt;/code&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Useful to use if your code works with Promises and needs to execute sequentially. Due to blocking, you might lose some ability to process code in parallel. I've primarily used async-await when making API requests.  —Pan Wangperawong&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;then&lt;/code&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;If you develop your frontend with React.js, a typical use case might be to display a loading screen until a fetch request returns and then using a setState to update the UI. —Pan Wangperawong&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>An Introduction to Computer Networking for Web Developers</title>
      <dc:creator>KyleJB</dc:creator>
      <pubDate>Tue, 18 Aug 2020 15:34:51 +0000</pubDate>
      <link>https://dev.to/kylejb/an-introduction-to-computer-networking-for-web-developers-41lg</link>
      <guid>https://dev.to/kylejb/an-introduction-to-computer-networking-for-web-developers-41lg</guid>
      <description>&lt;p&gt;Have you ever stopped to think about how information is transmitted from computer to computer? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MMEFjCld--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media1.tenor.com/images/ae0a1d53525901b101b0af2e88a0abc4/tenor.gif%3Fitemid%3D7713390" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MMEFjCld--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media1.tenor.com/images/ae0a1d53525901b101b0af2e88a0abc4/tenor.gif%3Fitemid%3D7713390" alt="Rabbit Hole"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's mind-blowing and we do it all the time – from making &lt;code&gt;fetch&lt;/code&gt; calls in our applications to the daily usage of our computers. &lt;/p&gt;

&lt;p&gt;Let's contextualize this exploration through the lens of RESTful protocols. Our data, like an email that we'd like to send to a friend, is broken up into "packets" that are transmitted from one computer and rebuilt on the receiving computer. Let's follow an email from your computer with an IP address of 1.2.3.4 as it traverses the internet to your friend's computer at IP address of 5.6.7.8.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5I6QTVsn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ipcisco.com/wp-content/uploads/email-transfer-over-tcpip-model-1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5I6QTVsn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ipcisco.com/wp-content/uploads/email-transfer-over-tcpip-model-1.jpg" alt="IPCisco Image of TCP-IP Model"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We start from the top left corner of the diagram and work our way to the upper right hand corner:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;application layer&lt;/strong&gt; is where we navigate to &lt;a href="https://gmail.com"&gt;https://gmail.com&lt;/a&gt; to compose and send an email. If your message is too long, it will be broken up into packets as we enter the TCP layer of the networking protocol stack.&lt;/li&gt;
&lt;li&gt;At the &lt;strong&gt;TCP layer&lt;/strong&gt;, packets are assigned to port numbers based on the data type. The IANA governs and documents these conventions. For purposes of this introductory post, our takeaway should be that our packets are assigned to the appropriate port number for the receiving computer.&lt;/li&gt;
&lt;li&gt;At the &lt;strong&gt;IP layer&lt;/strong&gt;, our packets receive the destination address (e.g*., IP address of 5.6.7.8*).&lt;/li&gt;
&lt;li&gt;Finally, we arrive at the &lt;strong&gt;hardware layer&lt;/strong&gt; (&lt;em&gt;e.g., ethernet cables&lt;/em&gt;) where our encapsulated alphanumeric data (&lt;em&gt;i.e., strings&lt;/em&gt;) is transformed into electronic signals and gets sent across phone/cable lines – or light, if you have fiber.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Similarly to how UPS or USPS would route your online order from a warehouse overseas to your doorstep, your email packet traverses the internet in milliseconds to your figurative doorstep. Once arrived at 5.6.7.8, we reverse the steps outlined above. And with the help of checksums (a computation to confirm that no packets are missing or tampered with), the packets we sent are collected and reassembled on our friend's computer.&lt;/p&gt;

&lt;p&gt;From a technical perspective, the data contained within (&lt;em&gt;i.e., the email or picture&lt;/em&gt;) is very much the same. For those that are philosophically inclined, is the reassembled email &lt;em&gt;really&lt;/em&gt; the same as what you sent?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;In a future post, I would like to explore the OSI/TCP-IP model in more detail to explore topics such as security and performance to help us become better coders.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How should you secure your API token?</title>
      <dc:creator>KyleJB</dc:creator>
      <pubDate>Tue, 18 Aug 2020 01:34:17 +0000</pubDate>
      <link>https://dev.to/kylejb/how-should-you-secure-your-api-token-2odl</link>
      <guid>https://dev.to/kylejb/how-should-you-secure-your-api-token-2odl</guid>
      <description>&lt;p&gt;&lt;em&gt;Welcome to my first blog post! I’d like to kick things off with a discussion on an important topic and propose an easy-to-implement solution to enable us to get started on what matters — our projects — while protecting ourselves on the internet.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post will contextualize API key management on the presumption that you write in Ruby. However, the concepts herein should be applicable to any language.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why should I care?&lt;/li&gt;
&lt;li&gt;‘dotenv’ to the rescue&lt;/li&gt;
&lt;li&gt;Implementation/TL;DR&lt;/li&gt;
&lt;li&gt;Citations&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  1. Why should I care? &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;We’re ready to move from “Hello World!” to our first project, but how do we start? Learning how to program is a daunting task. Take it from me; I started this journey three weeks ago and I thought I had — at least — the basic best practices committed to memory when I jumped into building my first project: &lt;a href="https://github.com/kylejb/nyc-mta-station-arrival-feed"&gt;The Commuter&lt;/a&gt; (&lt;em&gt;interfaces with NYC’S MTA API via CLI&lt;/em&gt;). Unexpectedly, the biggest obstacles that I have faced to date pertain to everything but programming.&lt;/p&gt;

&lt;p&gt;If your first foray into this world was anything like mine, coding best practices were easily forgotten in the face of obstacles. In my situation, I was wrestling with tokens and how to pass their value to the server in order to gain access to their data. I resigned to hardcoding the tokens in my code in order to distill the problem.&lt;/p&gt;

&lt;p&gt;Did you happen to instinctually bristle when I admitted to hardcoding my token in my application file? Why? Maybe it was because we were taught dynamic code is better than static code? Or, maybe what I did goes against common sense when dealing with private information — you wouldn’t write your username and password to your email address on a homework assignment after all, right? Regardless of your reason, haven’t we all found ourselves in this situation — hardcoding some variable to help solve a complex problem?&lt;/p&gt;

&lt;p&gt;Although there may be a better way (do let me know), I would think this is a reasonable approach to take provided that we refactor our code after testing is complete. However, are you making commits on git (e.g., &lt;code&gt;git add .&lt;/code&gt;, &lt;code&gt;git commit -m “yay, api works"&lt;/code&gt;)? Perhaps, you are also pushing that repository onto GitHub for your portfolio or to collaborate with others? Are you completely sure that you did not include those secret tokens within one the many commits or pushes to GitHub?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;…hundreds of thousands of API and cryptographic keys leaked at a rate of thousands per day.¹&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Researchers at North Carolina State University (NCSU) — Michael Meli, Matthew R. McNiece, Bradley Reaves — discovered that “even if commit histories are rewritten, secrets can still be recovered.” And, over the course of their study, many repositories publicly expose their key — like I almost did. And thanks to search indexing by companies like Google, it would have taken — on average — 20 seconds for my key to be discoverable through a search query that these researchers utilized.¹&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;While we cannot say from this analysis alone why cryptographic keys are leaked, it is clear that the poor practice of embedding secrets in code is a major root cause.¹&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because deleting those branches, files, or editing that line of code now would be too late, we need to set up our project folder correctly. And, on a brief tangent, I also recommend you take a look at &lt;a href="https://medium.com/u/9b4073211b0"&gt;Daniel Hahm&lt;/a&gt;’s &lt;em&gt;&lt;a href="https://medium.com/@dhahm01/a-beginners-look-into-git-commands-cbc57d9f34f4"&gt;Beginner’s Look at Git&lt;/a&gt;&lt;/em&gt; if you want to git better.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. &lt;code&gt;dotenv&lt;/code&gt; to the rescue &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;There are dozens of ways to handle the process. If you’re new to programming and are learning Ruby, I recommend the &lt;a href="https://www.rubydoc.info/gems/dotenv"&gt;gem ‘dotenv’&lt;/a&gt;; this is easiest to implement and gets the job done.&lt;/p&gt;

&lt;p&gt;Other programming languages have similar libraries that go by different names, but these all expect our file structure to incorporate a file (not folder) called &lt;code&gt;.env&lt;/code&gt; that stores our secret environment variables, which we can then invoke in our code base as a variable. But, before proceeding further, add &lt;code&gt;.env&lt;/code&gt; to your list in &lt;code&gt;.gitignore&lt;/code&gt;. This will ensure that git will never add, commit, and/or push your &lt;code&gt;.env&lt;/code&gt; file, thereby preventing public API exposure as long as you &lt;strong&gt;only&lt;/strong&gt; keep the secret values hardcoded to the &lt;code&gt;.env&lt;/code&gt;file.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Walkthrough — from setup to implementation &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Step 1 — install the ‘dotenv’ gem:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add &lt;code&gt;gem "dotenv"&lt;/code&gt;into your Gemfile and don’t forget to run &lt;code&gt;bundle install&lt;/code&gt;after doing so.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step 2 — create your &lt;code&gt;.env&lt;/code&gt;file:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While your terminal is in your project directory, &lt;code&gt;touch .env&lt;/code&gt;to create the file. If you’re using VSCode like me, the file will appear in root of your project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TbNr0X_x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ay-qBk-qcviW6MI5Gk7MWcg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TbNr0X_x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ay-qBk-qcviW6MI5Gk7MWcg.png" alt="https://cdn-images-1.medium.com/max/800/1*y-qBk-qcviW6MI5Gk7MWcg.png" width="250" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.env&lt;/code&gt; is known as a “global file” to the &lt;code&gt;dotenv&lt;/code&gt; gem and expects to find in the main folder of your project.&lt;/p&gt;

&lt;p&gt;This is the only file where you should be writing your API key values and setting them equal to a CONSTANT (in Ruby, capitalized variables are constants — not global). Here’s an example of what this should look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lTM8xp-Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ade_toSN5uua1QnxpihkIUg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lTM8xp-Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ade_toSN5uua1QnxpihkIUg.png" alt="https://cdn-images-1.medium.com/max/800/1*de_toSN5uua1QnxpihkIUg.png" width="503" height="92"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don’t worry… this isn’t my real API token. :)&lt;/p&gt;

&lt;p&gt;You can define as many environment variables and values as you wish here. You can access the value of your key like so: &lt;code&gt;ENV["YOUR_VAR_NAME"]&lt;/code&gt;. For example, if I wanted to use my API key, as depicted in the example above, I would write &lt;code&gt;ENV["MTA_KEY"]&lt;/code&gt;in another file. &lt;strong&gt;But, none of this will work until we complete step 3&lt;/strong&gt;: requiring the gem and making sure the gem loads so that it can access the locally defined environment variable we created here elsewhere in our project folder.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step 3— file configurations:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;:: **MOST IMPORTANT&lt;/strong&gt; → create or update your &lt;code&gt;.gitignore&lt;/code&gt;file and add &lt;code&gt;.env&lt;/code&gt;to the list like so:**&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DE5RpK0Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AFJsq2RwTaS_QhvQvQTuP1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DE5RpK0Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AFJsq2RwTaS_QhvQvQTuP1A.png" alt="https://cdn-images-1.medium.com/max/800/1*FJsq2RwTaS_QhvQvQTuP1A.png" width="528" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note &lt;code&gt;.env&lt;/code&gt; on line 15; this ensures that &lt;code&gt;git&lt;/code&gt; commands will never add, commit, or push this file with your secret keys to the public domain.&lt;/p&gt;

&lt;p&gt;:: &lt;em&gt;SECONDARY CONFIGURATIONS&lt;/em&gt; → making &lt;code&gt;dotenv&lt;/code&gt; accessible within our project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require 'dotenv'
Dotenv.load
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dtSjKylC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2A9nIGnSF18F78AED-vFfItg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dtSjKylC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2A9nIGnSF18F78AED-vFfItg.png" alt="https://cdn-images-1.medium.com/max/600/1*9nIGnSF18F78AED-vFfItg.png" width="462" height="162"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my app, class MtaRunner is the only model that requires access to my MTA API key, so this would suffice.&lt;/p&gt;

&lt;p&gt;If you’ve built a custom class (&lt;a href="https://medium.com/@mjhorowitz714/object-oriented-programming-in-ruby-9d02e8654659?sk=8300f1ff5da9c14b04adb18d16bfac3f"&gt;learn more about classes here&lt;/a&gt; by &lt;a href="https://medium.com/u/1e6589752708"&gt;Michael Horowitz&lt;/a&gt;) for your API calls, you may add the aforementioned lines above your class definition as depicted on the left. Alternatively, you may also add the aforementioned lines of code into your &lt;code&gt;environment.rb&lt;/code&gt; file provided that your project file is linked up to all your necessary folders/files properly; the benefit of adding the two lines to your &lt;code&gt;environment.rb&lt;/code&gt; file is you can access your key in all your models without needing to write &lt;code&gt;require 'dotenv'&lt;/code&gt;on each file.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want the ability to use dotenv when running &lt;code&gt;rake console&lt;/code&gt;to debug or test your API, I wrote this bit of code in my &lt;code&gt;Rakefile&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MEvqFzja--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AH3rv-FU6N_tFgpXIBAo7ww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MEvqFzja--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AH3rv-FU6N_tFgpXIBAo7ww.png" alt="https://cdn-images-1.medium.com/max/800/1*H3rv-FU6N_tFgpXIBAo7ww.png" width="513" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The change was done on line 3 and line 7. For any task(s) that may require &lt;code&gt;dotenv&lt;/code&gt;, you can follow a similar pattern to ensure it runs concurrently with that desired task.²&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Citations &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;[1]: Michael Meli, Matthew R. McNiece, and Bradley Reaves. (February 2019). &lt;em&gt;&lt;a href="https://www.ndss-symposium.org/wp-content/uploads/2019/02/ndss2019_04B-3_Meli_paper.pdf"&gt;How Bad Can It Git? Characterizing Secret Leakage in Public GitHub Repositories&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;[2]: Rubydoc. &lt;em&gt;&lt;a href="https://www.rubydoc.info/gems/dotenv/2.0.0#sinatra-or-plain-ol-ruby"&gt;dotenv Documentation.&lt;/a&gt;&lt;/em&gt; &lt;a href="https://www.rubydoc.info/gems/dotenv/2.0.0#sinatra-or-plain-ol-ruby"&gt;https://www.rubydoc.info/gems/dotenv/2.0.0#sinatra-or-plain-ol-ruby&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>ruby</category>
      <category>security</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
