<?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: IsaacThaJunior</title>
    <description>The latest articles on DEV Community by IsaacThaJunior (@isaacthajunior).</description>
    <link>https://dev.to/isaacthajunior</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%2F710088%2F731d68ff-9eec-4a96-a873-f6ee7a0be579.png</url>
      <title>DEV Community: IsaacThaJunior</title>
      <link>https://dev.to/isaacthajunior</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/isaacthajunior"/>
    <language>en</language>
    <item>
      <title>5 Shopify problems that Medusa solves</title>
      <dc:creator>IsaacThaJunior</dc:creator>
      <pubDate>Thu, 05 May 2022 14:21:03 +0000</pubDate>
      <link>https://dev.to/medusajs/5-shopify-problems-that-medusa-solves-52dn</link>
      <guid>https://dev.to/medusajs/5-shopify-problems-that-medusa-solves-52dn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.shopify.com/"&gt;Shopify&lt;/a&gt; is a popular ecommerce platform used by a lot of merchants. With Shopify, you are able to build your storefront without technical knowledge. However, Shopify merchants with time run through some problems that lead them to employ hacky workarounds in their stores.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medusajs.com/"&gt;Medusa&lt;/a&gt; is a rising open source Shopify alternative built for developers. Medusa is an open source ecommerce platform that comes with many ecommerce features such as an intuitive admin interface, promotions support, E2E order handling, RMA (return merchandise authorization) flows, and easy-to-integrate third-party services.&lt;/p&gt;

&lt;p&gt;In this article, you’ll learn more about what problems Shopify has that Medusa takes into account and provides a solution for as a platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Medusa
&lt;/h2&gt;

&lt;p&gt;The most important thing about Medusa is its abstraction-based architecture which gives customization capabilities for developers. Medusa’s headless architecture makes it easy to integrate with third-party services such as Content Management Systems (CMS), fulfillment providers, payment providers, and notification systems. &lt;/p&gt;

&lt;p&gt;Its headless architecture combined with its open source nature makes a great starting point for building much more tailored ecommerce setups.&lt;/p&gt;

&lt;p&gt;The flexibility in customization and integration provided for developers means that the merchants can be selective in terms of the services they choose to use with their ecommerce store. For example, you can integrate &lt;a href="https://strapi.io/"&gt;Strapi&lt;/a&gt; or &lt;a href="https://www.contentful.com/"&gt;Contentful&lt;/a&gt; to add rich CMS capabilities to your store. &lt;/p&gt;

&lt;p&gt;All of this can be done with Medusa and with no hacky workarounds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shopify comparison: Problems that Medusa solves
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Customization of the backend
&lt;/h3&gt;

&lt;p&gt;Shopify is a great option if you are creating an ecommerce store that does not require any custom features. But it falls short of the mark when you want to make customizations based on your business needs, which is often the case. This is the core problem with Shopify, as it leads developers and merchants to add multiple apps to their stores or add code blocks to implement hacky workarounds.&lt;/p&gt;

&lt;p&gt;Whereas Medusa is built with customization in mind. Although it provides &lt;a href="https://github.com/medusajs/medusa#features"&gt;tons of features out-of-the-box&lt;/a&gt;, you have countless ways to customize the setup based on the composable open source architecture. You can create or use existing plugins to integrate your store with third-party services.&lt;/p&gt;

&lt;p&gt;As for the frontend, you have the freedom to choose the frontend framework of your choice to power your storefront. Be it Next.js, Gatsby, Remix, or any other framework, all you need is to connect to &lt;a href="https://docs.medusajs.com/api/store"&gt;Medusa’s REST APIs&lt;/a&gt;. This gives you more flexibility in optimizing your storefront for the best user experience. &lt;/p&gt;

&lt;h3&gt;
  
  
  Poor site performance
&lt;/h3&gt;

&lt;p&gt;In Shopify, a lot of advanced features that merchants might want to add to their stores can only be added either through purchasing Shopify Apps or including custom code blocks in their store, as mentioned in the previous section. This is more the case when the features being added are custom to the merchants’ use case.&lt;/p&gt;

&lt;p&gt;Adding too many apps to your Shopify store or filling it up with custom code can have an adverse effect on page load speed. A slow ecommerce store can make customers frustrated and lead them to leave your store in favor of another faster store.&lt;/p&gt;

&lt;p&gt;On the other hand, Medusa’s headless architecture which decouples the backend from the frontend releases the frontend from the shackles of the backend and makes it faster. This means that your store loads independently from the backend and just interacts with it to fetch or post data.&lt;/p&gt;

&lt;p&gt;Moreover, this separation of the frontend from the backend means that additional features that you wish to add to your Medusa server as plugins do not affect your storefront’s speed. This leads to a better user experience and more traffic to your store.&lt;/p&gt;

&lt;h3&gt;
  
  
  Omnichannel Support
&lt;/h3&gt;

&lt;p&gt;Omnichannel refers to the ability to sell on multiple channels (across devices and platforms) while giving your customers a seamless experience across multiple channels. It also gives merchants the ability to manage orders logistically the same way regardless of where the customer places the order.&lt;/p&gt;

&lt;p&gt;To truly provide omnichannel support you need an ecommerce platform that allows you to utilize your store’s resources similarly across platforms and devices.&lt;/p&gt;

&lt;p&gt;Shopify’s 3 plans (Basic, Shopify, and Advanced) don’t provide a clear way to support omnichannel in your store. There are some unofficial apps that provide it, but merchants will often need multiple of them rather than just one. This can further slow down your store and fills it with more apps.&lt;/p&gt;

&lt;p&gt;Alternatively, Shopify provides a headless commerce solution through its Shopify Plus plan which comes at a heavy price of &lt;a href="https://www.shopify.com/plus/pricing"&gt;$2000 per month&lt;/a&gt;. The headless architecture can make it easier for you to make use of your store’s resources across platforms, but it comes at a big price.&lt;/p&gt;

&lt;p&gt;With Medusa, omnichannel support is available by default due to its headless architecture. Medusa’s REST APIs are designed to be consumed uniformly regardless of which client is sending the requests. So, you can provide a seamless experience to your users on both ecommerce websites as well as mobile apps.&lt;/p&gt;

&lt;p&gt;Omnichannel support is achievable in Medusa without additional integrations or added costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-currency support
&lt;/h3&gt;

&lt;p&gt;By supporting multiple currencies in a store, your customers will be able to view prices based on their local currency. This gives your customers a better experience and more clarity when shopping around the world.&lt;/p&gt;

&lt;p&gt;In Shopify, this feature is only available if the merchant can activate Shopify Pay, which is only available in &lt;a href="https://help.shopify.com/en/manual/payments/shopify-payments/shopify-payments-requirements#supported-countries-and-regions"&gt;17 countries&lt;/a&gt;, as well as activate Shopify Market. Even with these 2 activated, merchants still need an Advanced plan if they want to customize the price format in different currencies or the exchange rates.&lt;/p&gt;

&lt;p&gt;An alternative approach that Shopify merchants use is creating multiple stores that give them more control over the product prices in different currencies. A big disadvantage of this approach is the difficulty that comes with managing multiple products, orders, and settings, among other resources separately for each store. This makes your store more prone to human errors and miscommunications.&lt;/p&gt;

&lt;p&gt;With Medusa, there is no need to create or have multiple stores just to handle multiple currencies. Medusa lets you do it all from one admin dashboard. You can create multiple regions in the same store and select the currency of the region. Then, you’ll be able to set the price of the product differently for each currency.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://dev.to/medusajs/how-an-open-source-platform-resolves-shopifys-multi-currency-issues-47lg"&gt;Suggested Read: How Medusa Resolves Shopify's Multi-Currency Issues.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability and Maintainability
&lt;/h3&gt;

&lt;p&gt;Most ecommerce stores start small and then gradually get bigger with time. Starting small means that there is no need for heavy resources, custom features, or complex integrations to provide various features like customer service.&lt;/p&gt;

&lt;p&gt;With time, businesses using Shopify find that their stores are incapable of growing with their business needs. This is due to all the problems mentioned earlier in this article. Businesses tend to need later on, if not from the start, more customization capabilities, multi-currency and omnichannel support, and better performant ecommerce websites.&lt;/p&gt;

&lt;p&gt;This often leads businesses to continue employing hacky workaround or pay additional costs to try and keep their store performant with a good user experience. Also, if they use Shopify apps in their store it can become hard to maintain the store in case some apps don’t play well together.&lt;/p&gt;

&lt;p&gt;Medusa, on the other hand, not only resolves all the problems mentioned above, but it is capable of scaling with businesses’ growth. A business can tailor their ecommerce platform to their needs or make sure the server can handle more users or products, at lower costs.&lt;/p&gt;

&lt;p&gt;Furthermore, Medusa is lightweight to maintain even after adding custom logic due to its abstraction-based architecture. Medusa’s existing use cases show examples of global stores (+30M USD in yearly revenue) being able to run an entire ecommerce setup on Medusa with only 1 frontend developer supporting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Choose an ecommerce platform that will not only meet your current business needs but also be able to scale as your business grows.&lt;/p&gt;

&lt;p&gt;Medusa is an ecommerce platform that aims to provide a good experience for both developers and merchants. As a merchant, you are no longer restricted by the shackles of proprietary software. As a developer, you are free to customize and make changes to the code as you see fit.&lt;/p&gt;

&lt;p&gt;To get started with Medusa, check out the &lt;a href="https://docs.medusajs.com/quickstart/quick-start"&gt;Quickstart guide&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Should you have any issues or questions related to Medusa, then feel free to reach out to the Medusa team via &lt;a href="https://discord.gg/F87eGuwkTp"&gt;Discord&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The this Keyword in Javascript</title>
      <dc:creator>IsaacThaJunior</dc:creator>
      <pubDate>Mon, 17 Jan 2022 09:02:19 +0000</pubDate>
      <link>https://dev.to/isaacthajunior/the-this-keyword-in-javascript-30i2</link>
      <guid>https://dev.to/isaacthajunior/the-this-keyword-in-javascript-30i2</guid>
      <description>&lt;p&gt;The &lt;code&gt;this&lt;/code&gt; keyword has got to be one of the most misunderstood concepts in Javascript, especially to beginners. I remember being frustrated by it on more than one occasion. Some might even say that it is one of the most challenging concepts to understand in Javascript. In order to read and write good Javascript code, you must understand the &lt;code&gt;this&lt;/code&gt; keyword. In this tutorial, I will endeavor to break it down and show you how the &lt;code&gt;this&lt;/code&gt; keyword works and that there is no reason to be scared of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the this Keyword?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;this&lt;/code&gt; keyword is a special variable automatically created for every function by Javascript, and it will point to or take the value of the "owner" of the function that is calling it. The &lt;code&gt;this&lt;/code&gt; keyword is dynamic, and its value is assigned or known only when the function is called and depends on how the function is called.&lt;br&gt;
There are four (4) ways to call a function in Javascript, and the value of the &lt;code&gt;this&lt;/code&gt; keyword changes in each way.&lt;/p&gt;

&lt;h4&gt;
  
  
  1) As a Method:
&lt;/h4&gt;

&lt;p&gt;For a function to be called as a method, it must be defined as a property on an object or as a function that is attached to an object. When we call a method the &lt;code&gt;this&lt;/code&gt; keyword will point to the object on which the method is called, or it points to the object that is calling the method. Let's see an example below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const student = {
  name: 'Isaac',
  class: 'Junior',
  age: '16',
  callStudent: function () {
    return `${this.name} is ${this.age} years old`;
  },
};
console.log(student.callStudent()); // Isaac is 16 years old
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the example above, the method is the &lt;code&gt;callStudent&lt;/code&gt; method because it is a function that is attached to the &lt;code&gt;student&lt;/code&gt; object. We then called the method and console logged it. Inside the method, we used the &lt;code&gt;this&lt;/code&gt; keyword, and we found the value of the &lt;code&gt;this&lt;/code&gt; keyword to be &lt;code&gt;student&lt;/code&gt; because it is the object that is calling the &lt;code&gt;callStudent&lt;/code&gt; method. And that’s why &lt;code&gt;this.name&lt;/code&gt; is Isaac because it means &lt;code&gt;student.name&lt;/code&gt; and &lt;code&gt;this.age&lt;/code&gt; is 16 because it means &lt;code&gt;student.age&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  2) Calling functions as regular functions:
&lt;/h4&gt;

&lt;p&gt;This is probably the default way of calling function. The &lt;code&gt;this&lt;/code&gt; keyword can have different values when used in a regular function call depending on whether you are coding in strict mode or default mode (non-strict mode).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In strict mode&lt;/strong&gt;: Strict mode doesnt allow for default binding and therefore when used in strict mode, the &lt;code&gt;this&lt;/code&gt;  keyword in a regular function call is &lt;code&gt;undefined&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    'use strict';
    function myFunction() {
      console.log(this === undefined); // true
    }

    myFunction();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In default mode&lt;/strong&gt;: When used in default mode, the &lt;code&gt;this&lt;/code&gt; keyword refers to the global object, which in the case of the broswer is the &lt;code&gt;window&lt;/code&gt; object. Let us see an example below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    function printThis() {
      console.log(this)
    }

    printThis()
    // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: It should be noted that using &lt;code&gt;this&lt;/code&gt; in default mode can be very problematic and can introduce bugs into your code because you aren’t sure where your &lt;code&gt;this&lt;/code&gt; keyword is pointing. Therefore it is advised that you always write your Javascript code in strict mode. &lt;/p&gt;

&lt;h4&gt;
  
  
  3) In a Constructor
&lt;/h4&gt;

&lt;p&gt;A constructor is a function that creates an object and initializes that object with a class. A constructor is called when an object is declared with the &lt;code&gt;new&lt;/code&gt; keyword. The &lt;code&gt;this&lt;/code&gt; keyword is set to the newly created object. Let’s look at the example below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Sport(type) {
  this.type = type;
}
Sport.prototype.getType = function () {
  return this.type;
};
let sport = new Sport('Football');
console.log(sport.getType()); // Football
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the code block above, we created an object with the &lt;code&gt;new&lt;/code&gt; keyword and then the &lt;code&gt;this&lt;/code&gt; keyword was set to the newly created object (Sport). That’s why we could access &lt;code&gt;this.type&lt;/code&gt; to get Football. The capital letter is used to show that the function is a constructor. &lt;/p&gt;

&lt;h4&gt;
  
  
  4) Using the &lt;code&gt;call()&lt;/code&gt; and &lt;code&gt;apply()&lt;/code&gt; method
&lt;/h4&gt;

&lt;p&gt;All functions in Javascript are first class objects meaning that they have their own methods and properties. The &lt;code&gt;call()&lt;/code&gt; and &lt;code&gt;apply()&lt;/code&gt; method are two of those methods. These methods lets you set the &lt;code&gt;this&lt;/code&gt; keyword when calling a function irrespective of whether that function is being called in the global scope or as the object's method, as we will see in the example below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getSport(prefix) {
  console.log(prefix + this.type);
}
let footBall = {
  type: 'Football!',
};
let cricket = {
  type: 'Cricket!',
};
getSport(footBall, "It's called ") //[object Object]undefined
getSport(cricket, "It's called ") //[object Object]undefined

getSport.call(footBall, "It's called "); // It's called Football!
getSport.call(cricket, "It's called "); // It's called Cricket!

getSport.apply(footBall, ["It's called "]); // It's called Football!
getSport.apply(cricket, ["It's called "]); // It's called Cricket!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the example above, we see that when we called the &lt;code&gt;getSport&lt;/code&gt; function that it returned  &lt;code&gt;[object Object]undefined&lt;/code&gt; because there is no connection between &lt;code&gt;getSport&lt;/code&gt;, &lt;code&gt;footBall&lt;/code&gt;, or &lt;code&gt;cricket&lt;/code&gt;. Therefore, the &lt;code&gt;this&lt;/code&gt; keyword will result in &lt;code&gt;undefined&lt;/code&gt; in strict mode or to the global object in default mode. However, when we use &lt;code&gt;call()&lt;/code&gt; and &lt;code&gt;apply()&lt;/code&gt;, we invoke the &lt;code&gt;this&lt;/code&gt; keyword of &lt;code&gt;footBall&lt;/code&gt; and &lt;code&gt;cricket&lt;/code&gt; on the &lt;code&gt;getSport&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The difference between &lt;code&gt;apply()&lt;/code&gt; and &lt;code&gt;call()&lt;/code&gt; method is that  &lt;code&gt;apply()&lt;/code&gt;  takes in arguments as an array while &lt;code&gt;call()&lt;/code&gt; requires arguments to be passed in one by one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other ways in which the this Keyword can be referenced
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;this&lt;/code&gt; keyword can also be referenced in other ways apart from when functions are called, and we are going to discuss them in this section.&lt;/p&gt;

&lt;h4&gt;
  
  
  Arrow functions
&lt;/h4&gt;

&lt;p&gt;Arrow functions do not get their own &lt;code&gt;this&lt;/code&gt; keyword. Instead, if you use the &lt;code&gt;this&lt;/code&gt; keyword in an arrow function, it will simply be the &lt;code&gt;this&lt;/code&gt; keyword of the surrounding function (the parent function). Technically it is known as the lexical &lt;code&gt;this&lt;/code&gt; keyword because the arrow function inherits the &lt;code&gt;this&lt;/code&gt; keyword from the outer lexical scope (function).&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sayName = {
  name: 'Isaac Junior',
  regularFunction: function () {
    console.log(this.name);
  },
  arrowFunction: () =&amp;gt; {
    console.log(this.name);
  },
};
sayName.regularFunction(); // "Isaac Junior"
sayName.arrowFunction(); // undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the example above, we created an object with two functions set as methods. When we called the first function which was a regular function, we notice that the &lt;code&gt;this&lt;/code&gt; keyword pointed to the object that was calling the method and that was why we got Isaac Junior in the console.&lt;br&gt;
But when we called the second function which was an arrow function, we notice that we get undefined or nothing in the console and that is because arrow functions do not have their own &lt;code&gt;this&lt;/code&gt; binding. &lt;/p&gt;

&lt;h4&gt;
  
  
  Using the bind() method
&lt;/h4&gt;

&lt;p&gt;Sometimes, you might need to use a method over and over with the &lt;code&gt;this&lt;/code&gt; context of another object, and in that case you could use the &lt;code&gt;bind&lt;/code&gt; method to create a brand new function with an explicitly bound &lt;code&gt;this&lt;/code&gt;. Let’s look at an example below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let gender = {
  type: 'male',
  getType: function () {
    return this.type;
  },
};
let seaAnimal = {
  type: 'Octupus',
};
let type = gender.getType.bind(seaAnimal);
console.log(type()); // Octupus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the example above, we bound the &lt;code&gt;this&lt;/code&gt; keyword to the &lt;code&gt;seaAnimal&lt;/code&gt; object. And thats why the value of the type property is that of the &lt;code&gt;seaAnimal&lt;/code&gt; object in the console&lt;/p&gt;

&lt;h4&gt;
  
  
  Event Handlers
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;this&lt;/code&gt; keyword will always point to the DOM element that the handler function is attached to in event handlers. Let’s see an example below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const words = document.getElementsByClassName('tags');
function turnBlue() {
  this.style.backgroundColor = '#A5D9F3';
}
for (let i = 0; i &amp;lt; words.length; i++) {
  words[i].addEventListener('click', turnBlue);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the example above, we have an event listener that turns any class with &lt;code&gt;tags&lt;/code&gt; in our code blue when we click on it. We used the &lt;code&gt;this&lt;/code&gt; keyword, and as we can see, it points to the DOM element on which the event listener or handler is attached which in this case is &lt;code&gt;words&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we have looked at and broken down what the &lt;code&gt;this&lt;/code&gt; keyword is, and what it points to in every instance in which it is created. I hope that you will be more confident about making use of the &lt;code&gt;this&lt;/code&gt; keyword from now onwards whenever you are writing Javascript code&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Let’s talk Sass and why you should use it for your Stylesheets </title>
      <dc:creator>IsaacThaJunior</dc:creator>
      <pubDate>Sat, 04 Dec 2021 01:49:32 +0000</pubDate>
      <link>https://dev.to/isaacthajunior/lets-talk-sass-and-why-you-should-use-it-for-your-stylesheets-19hl</link>
      <guid>https://dev.to/isaacthajunior/lets-talk-sass-and-why-you-should-use-it-for-your-stylesheets-19hl</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Styling with CSS is a pain and that’s the truth of the matter. Most developers find it hard to use the box model and center divs and even after trying and learning how to center divs, you then get the shocker that not every browser is compatible with your styling and you have to add extra lines of code to provide compatibility for other browsers.&lt;br&gt;
Well, worry no more. Sass takes care of compatibility issues of browsers by being compatible across different browsers and also new versions of Sass are backward-compatible meaning that older Sass syntax or lines of Sass code can still work without modifications. And if you want to have fun while writing CSS code then I can think of no better way than to learn SASS&lt;/p&gt;

&lt;p&gt;Without further ado, let's get into it.&lt;/p&gt;

&lt;p&gt;SASS supports two different syntaxes which can load up each other and they are Indented Syntax which is the original SASS syntax and SCSS.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is Indented Syntax or SASS?
&lt;/h3&gt;

&lt;p&gt;SASS is short for Syntactically Awesome Style Sheet. I know, I know, syntactically sounds like a lot no? Well, what it means is that the lines( syntax ) of SASS code are so awesome that it is known as CSS with superpowers.&lt;br&gt;
SASS is known as a CSS preprocessor meaning that it lets you create and write code that is then compiled into CSS. SASS uses the file extension .sass&lt;br&gt;
SASS code has a loose syntax with no semicolons, it is preferred for those that want to be concise as possible when writing CSS code. An example of SASS code is given below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
body
  display: inline-flex
  position: relative
  border: 2px solid #FF0000
  border-radius: 3px
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What is SCSS?
&lt;/h3&gt;

&lt;p&gt;SCSS is short for Sassy Cascading Style Sheets. SCSS uses the file extension .scss and it's a superset of CSS which means that all valid codes of CSS are also valid codes of SCSS. Based on its closeness and similarities with CSS, it is the easiest syntax to get used to and also to write which makes it the most popular between the two syntaxes. SCSS is preferred by those that prefer similarities when writing CSS code. An example of SCSS code is given below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;body{
  display: inline-flex
  position: relative
  border: 2px solid #FF0000
  border-radius: 3px
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Compiler for SASS and SCSS
&lt;/h3&gt;

&lt;p&gt;One of the disadvantages of SCSS and SASS is the fact that browsers cannot read SCSS and SASS code. Therefore for your SCSS code to work, you have to install a compiler in whichever code editor you are using. The code editor will then take that written SCSS code and then interpret it into CSS which can then be understood by browsers. I use Visual Studio Code editor which is a free code editor by Microsoft and which supports extensions. I use Live Sass Compiler which is shown in the image below:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eitELJIV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropbox.com/s_A5FC3FEB1398CEEEFACCD0F7551397B4F833999434F00B00C02B2DBAF7DFBB3A_1638571908590_Screenshot%2Bfrom%2B2021-12-03%2B23-34-57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eitELJIV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropbox.com/s_A5FC3FEB1398CEEEFACCD0F7551397B4F833999434F00B00C02B2DBAF7DFBB3A_1638571908590_Screenshot%2Bfrom%2B2021-12-03%2B23-34-57.png" alt="" width="713" height="671"&gt;&lt;/a&gt;&lt;br&gt;
 Now after you have installed the extension, you will see the Watch Sass icon below meaning that it is watching and compiling every SASS code to CSS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9Nv8YkxI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropbox.com/s_A5FC3FEB1398CEEEFACCD0F7551397B4F833999434F00B00C02B2DBAF7DFBB3A_1638572273993_Screenshot%2Bfrom%2B2021-12-03%2B23-34-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9Nv8YkxI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropbox.com/s_A5FC3FEB1398CEEEFACCD0F7551397B4F833999434F00B00C02B2DBAF7DFBB3A_1638572273993_Screenshot%2Bfrom%2B2021-12-03%2B23-34-01.png" alt="" width="561" height="18"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Benefits of using SCSS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code Splitting&lt;/strong&gt;: One of the benefits of using SCSS is that it allows for code splitting meaning that instead of having a huge and bulky SCSS file, you can have small, separate files for styling different parts of your web app and this also helps in the long run as it makes code debugging easier. All you need to do is put a _ in front of the file you want to split and then when you are done you then use the @import rule to import that file into your main SCSS file which won’t have the __ in front of it.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vwggE2gt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropbox.com/s_A5FC3FEB1398CEEEFACCD0F7551397B4F833999434F00B00C02B2DBAF7DFBB3A_1638572958703_Screenshot%2Bfrom%2B2021-12-04%2B00-08-53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vwggE2gt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropbox.com/s_A5FC3FEB1398CEEEFACCD0F7551397B4F833999434F00B00C02B2DBAF7DFBB3A_1638572958703_Screenshot%2Bfrom%2B2021-12-04%2B00-08-53.png" alt="" width="148" height="171"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Using Variables&lt;/strong&gt;: SCSS offers the ability for you to create variables. Variables allow you to store a certain value and then re-use that variable throughout your code thereby keeping it DRY ( Don’t Repeat yourelf ). Below you can see how variables can be created:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$primary-color: hsl(210, 36%, 96%);
$secondary-color: #2ffff5;
$ubuntu-font: 'Ubuntu', 'Arial', 'Helvetica', sans-serif;
$nunito-font: 'Nunito', 'Arial', 'Helvetica', sans-serif;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We can then use those variables anywhere in our code like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;h1{
  color: $primary-color;
  font: $nunito-font;
}

p{
  color: $secondary-color;
  font: $ubuntu-font;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nested Syntax&lt;/strong&gt;: Imagine you have a section with a class of projects and inside that section, you have a div and a button with a class of projects_&lt;em&gt;items and projects&lt;/em&gt;_btn respectively. Now SCSS allows you to nest those classes together instead of using the traditional CSS way of targeting each class separately. Now nesting allows for easy to read and maintainable code, it also prevents us from rewriting selectors multiple times. Example of nesting is shown below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
.projects {
  color: $primary-color;
  font: $ubuntu-font;
  padding-bottom: 2rem;

  &amp;amp;__items {
    width: 60vw;
    margin: 2rem auto 0 auto;
    display: grid;
    grid-template-columns: 1fr;
    grid-gap: 2rem;
  }

    &amp;amp;__btn {
    font: $nunito-font;
    color: $secondary-color;
    font-size: 1.4rem;
    opacity: 0;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mixins&lt;/strong&gt;: Using variables in your code is amazing right, but mixins are more cool and amazing. Mixins let you define styles that can be re-used throughout your code. We then use &lt;code&gt;@include&lt;/code&gt; to ‘include’ our mixin wherever we want to use it
An example of mixin is given below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@mixin transition-ease {
  color: $secondary-color;
  font: $ubuntu-font;
  transition: all 0.5s ease-in-out;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To include our mixin in any part of our code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a{
  @include transition-ease;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we introduced and talked about SASS, its benefits, and why you should start using it instead of the conventional CSS. You can visit &lt;a href="https://sass-lang.com/guide"&gt;here&lt;/a&gt; to learn more about SASS.&lt;/p&gt;

</description>
      <category>openreplay</category>
      <category>scss</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>A dive into ABAC systems in Node.js applications with Fauna</title>
      <dc:creator>IsaacThaJunior</dc:creator>
      <pubDate>Mon, 29 Nov 2021 00:40:48 +0000</pubDate>
      <link>https://dev.to/isaacthajunior/a-dive-into-abac-systems-in-nodejs-applications-with-fauna-2gi2</link>
      <guid>https://dev.to/isaacthajunior/a-dive-into-abac-systems-in-nodejs-applications-with-fauna-2gi2</guid>
      <description>&lt;p&gt;Authorization is a significant component when building web applications, as developers are required both to know and recognize the identity of their users, grant them access and then restrict access to unregistered or unauthorized users. Put simply, It is a process of user recognition. In this tutorial, we are going to talk about ABAC, ABAC systems and ABAC in Node.js applications with Fauna.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ABAC authentication?
&lt;/h2&gt;

&lt;p&gt;Attribute-Based Access Control or ABAC is a system that defines or controls access to what users can create or delete. It is an authorization model that grants access to users through attributes rather than roles.&lt;br&gt;
According to the &lt;a href="https://docs.fauna.com/fauna/current/security/abac"&gt;documentation&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Attribute-based access control (ABAC) is a flexible, fine-grained strategy for managing identity-based operations within Fauna&lt;/em&gt;.&lt;/p&gt;

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

&lt;p&gt;ABAC controls detailed level user access, which is established based on attributes different from its counterpart. The role-based access control (RBAC) controls broad access, which is established based on roles.&lt;/p&gt;

&lt;p&gt;One of the benefits of ABAC is its user-intuitive nature that hides technical permission sets behind easy-to-understand user profiles that anyone with authority can update. It knows that the user will have the access they need as long as their attributes are up to date.&lt;/p&gt;

&lt;p&gt;Another benefit is that ABAC enables dynamic and context-specific access to resources adapted to different access control policies. &lt;/p&gt;
&lt;h4&gt;
  
  
  Usefulness of ABAC in modern software development
&lt;/h4&gt;

&lt;p&gt;ABAC provides fine-grained, elegant and contextual access control that is focused on delivering functional, transactional and data access controls. It's easier to maintain architecture allows  for the swift and streamlined onboarding of new APIs. &lt;/p&gt;

&lt;p&gt;One use case for ABAC is in the use of Completely Automated public Turing Test To Tell computers and Humans Apart or Captcha as is commonly known. Captchas are used to control access depending on whether the party seeking access is a machine or human.&lt;/p&gt;

&lt;p&gt;Another use case is a newly re-assigned finance executive is only able to access information that is directly to their new project and not their previous one&lt;/p&gt;
&lt;h4&gt;
  
  
  ABAC in NodeJS systems
&lt;/h4&gt;

&lt;p&gt;ABAC is an extension of RBAC that tries to solve problems in a specific situation. It uses attributes as building blocks in NodeJS systems to define access control rules and access requests. In systems where attributes separate access, ABAC provides a framework to solve role explosion issues by defining rights based on various properties of various users.&lt;/p&gt;
&lt;h4&gt;
  
  
  How ABAC systems work in NodeJS applications.
&lt;/h4&gt;

&lt;p&gt;ABAC works by examining attributes to make decisions concerning access and this attributes can be broken up into four categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Subject attributes: This can be a human user or any device that issues access requests to perform operations on objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Object attributes: This is the resource or anything upon which the subject can operate. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Action: The execution of a function at the request of the subject on the object or what exactly will the subject do with the resource. It describes the action being attempted. This includes read, write, edit, delete, copy, execute, and modify.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Environmental attributes: The operational or situational context in which the access request occurs. The environmental attribute is independent of subject and object attributes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Using Fauna for ABAC systems with NodeJS
&lt;/h4&gt;

&lt;p&gt;Fauna provides some features such as privileges, membership, predicate functions, overlapping roles in a document and even through delegation. In this section we will look at these features and how they can be used to provide access to our Fauna documents. We will use Node.js to build an example application that leverages Fauna’s ABAC feature.&lt;/p&gt;
&lt;h5&gt;
  
  
  Privileges
&lt;/h5&gt;

&lt;p&gt;A privilege is used to specify a resource in a Fauna database (e.g. a document, key, index, etc.) Privileges are specific actions that can be executed on particular resources and can be assessed through a set of predefined actions and a predicate function. With privileges, developers can add specific access to a group of predefined actions to grant access. Actions in Fauna can vary depending on the use case, this can be core schemas for a collection, index, function or even a key. We can add access to this in the create  and delete schemas. The documents use case and access in this can be added in the read, history_read and history_write. &lt;/p&gt;
&lt;h5&gt;
  
  
  Membership
&lt;/h5&gt;

&lt;p&gt;Membership defines a set of collections whose documents should have the role's privileges. A predicate function can be provided when determining the membership.&lt;/p&gt;
&lt;h5&gt;
  
  
  Predicate Functions
&lt;/h5&gt;

&lt;p&gt;A predicate function is an FQL, read-only function that returns a boolean value to show or indicate whether access or action is allowed or not. The purpose of a predicate function is to read attributes of resources and create access policies on them when some conditions have been met. If the condition returns false, then the condition is not met.&lt;/p&gt;
&lt;h5&gt;
  
  
  Overlapping roles
&lt;/h5&gt;

&lt;p&gt;This is a situation where a document has two or more roles for performing a specific action and Fauna tries to optimize for common access patterns so as to avoid evaluating roles unnecessarily.&lt;/p&gt;
&lt;h4&gt;
  
  
  Getting started with NodeJS project
&lt;/h4&gt;

&lt;p&gt;This section will discuss how to use Fauna on a Nodejs project, but first, we will install Fauna on our local machine. To do this, we will install the Fauna shell using the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g fauna-shell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command above will install the Fauna shell on your local machine. After we have installed the fauna shell, we then log in with our fauna credentials. If you don’t have an account with Fauna, you can create one here. &lt;/p&gt;

&lt;p&gt;To create a database using the Fauna shell, we will use the command below, you can change the database name however you see fit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
fauna create-database abac-database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will create a database named &lt;code&gt;abac-database&lt;/code&gt;, to start the database on your terminal, run the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
fauna shell abac-database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we need to get our secret key from Fauna which we will use for our application by running the command below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
CreateKey({ role: "server" })

//  Returns something like this
//  {
//   ref: Ref(Keys(), "278091949991264787"),
//   ts: 1601468000353000,
//    role: 'server',
//    secret: 'fnAD2_sntiACE_xHweiTXMNvy7Z4vJ2OkA7yZAd1',  copy this
//    hashed_secret: '$2a$05$AjuS2MrHwgBCUKepWp/KLOniI4hinzLbUqIHf1PZsOlu3qbSncgr.'
//  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you’ve started the database, you’d need to create a collection for contacts, address and phone numbers below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
CreateCollection({ name: "contacts" }),
CreateCollection({ name: "address" }),
CreateCollection({ name: phone_number })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create indexes for our collection by copying the code block below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
CreateIndex({ 
  name: "user_by_name",
  source: Collection("contacts"),
  terms: [{ field: ["data", "name"] }],
})

CreateIndex({ 
  name: "user_by_number",
  source: Collection("phone_number"),
  terms: [{ field: ["data", "phone_number"] }],
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then add data to our collections below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Map([
  ["Isaac Okoro", 34900],
  ["Kay", 49061],
  ["Bright", 29083]
], Lambda("data", Let(
    {
      user: Create(Collection("contacts"), {
        data: { name: Select(0, Var("data")) },
        credentials: { address: "east west road" }
      }),
        salary: Select(1, Var("data"))
      },
      Create(Collection("phone_number"), { data: {
        user: Select("ref", Var("contacts")),
        phone_number: Var("phone_number")
      }})
 )))     
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we created contacts and phone_number collections, and inside it we created a user that references a key, the contacts collection also stores the user’s credentials and address. In our next section, we will look at using our prepared database in a Node.js application.&lt;/p&gt;

&lt;h4&gt;
  
  
  Using ABAC system in Contacts App
&lt;/h4&gt;

&lt;p&gt;First, we will build a Node.js contacts application. To do that, we will run the command below in our Terminal to scaffold a Node.js application :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will then asked some question, answer them and then a &lt;code&gt;package.json&lt;/code&gt; file will be created for you.&lt;/p&gt;

&lt;p&gt;Then we will install our Fauna dependency which we will use in our project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
npm i faunadb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we installed fauna’s NPM package, we will then go into our Fauna account and then get our secret key after which we will navigate to our application and connect our Fauna access key to our project’s env file.&lt;br&gt;
Next, install the following dependencies which we will use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
npm install commander inquirer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- `Commander` is a simple library for commands.
- `inquirer` is for complex input commands
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we have installed our dependencies, we then navigate to our index.js file and import those dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const faunadb = require('faunadb');
const program = require('commander');
const { prompt } = require('inquirer');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we create a new js file called prompts.js ( you can name yours differently) and then we create our prompts command and then export it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const newContactPrompts = [
  {name: 'firstName', message: 'First Name'},
  {name: 'lastName', message: 'Last Name'},
  {name: 'phoneNumber', message: 'Phone Number'}
]
module.exports = {newContactPrompts}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we create a file where we put the logic for the app&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const fs = require('fs')
const path = require('path')
// this path needs to be relative to work with fs
const contactsLocation = path.join(__dirname, 'contacts.json')
/**
 * should read the contacts at the
 * @contactsLocation path and convert
 * it to a js object
 */
const getContacts = () =&amp;gt; {
  const contacts = fs.readFileSync(contactsLocation)
    .toString()
  return JSON.parse(contacts)
}
/**
 * takes a contacts object, converts it to JSON
 * and saves it at the @contactsLocation path
 * @param {Object} contacts contacts object
 */
const saveContacts = (contacts) =&amp;gt; {
  fs.writeFileSync(contactsLocation, JSON.stringify(contacts, null, 2))
}
module.exports = { 
  contactsLocation,
  getContacts,
  saveContacts
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After we have done that, we then import our newly created files to be used in our index.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const faunadb = require('faunadb');
const program = require('commander')
const { prompt } = require('inquirer')
const {newContactPrompts} = require('./prompts')
const {getContacts, saveContacts} = require('./utils')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code block below, we defined the contacts CLI commands&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
program
  .version('0.0.1')
  .description('Address book CLI program')
program
  .command('new')
  .alias('n')
  .description('add a new contact')
  .action(() =&amp;gt; {
    prompt(newContactPrompts)
      .then(({firstName, lastName, phoneNumber}) =&amp;gt; {
        const key = firstName + ' ' + lastName
        const contacts = getContacts()
        contacts[key] = {firstName, lastName, phoneNumber}
        saveContacts(contacts)
      })
  })
program
  .command('list')
  .alias('l')
  .description('list all contacts')
  .action(() =&amp;gt; {
    const contacts = getContacts()
    prompt([
      {
        type: 'list',
        name: 'selected',
        message: 'Select a contact',
        choices: Object.keys(contacts)
      }
    ])
      .then(({selected}) =&amp;gt; {
        const contact = contacts[selected]
        console.log(JSON.stringify(contact, null, 2))
      })
  })
program.parse(process.argv)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you’ve done this, run the command below in your terminal to add a new contact to your Fauna database&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
node index.js new 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The image below should be the same as yours if done correctly:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jH1Ik2Rz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/464wpzbgor5aoqvuiebh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jH1Ik2Rz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/464wpzbgor5aoqvuiebh.png" alt="Image" width="662" height="110"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In this tutorial, we learned how to create a comprehensive authorization model and use it with Fauna's API and built-in ABAC features. We also built a contacts application and enabled ABAC by giving different permissions to users and admin  to it.&lt;/p&gt;

&lt;p&gt;Currently, access can be given to any Fauna database, but the Fauna Query Language implements it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Resources
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://docs.fauna.com/fauna/current/tutorials/authentication/abac"&gt;The Fauna Docs&lt;/a&gt;&lt;br&gt;
  &lt;a href="https://docs.fauna.com/fauna/current/tutorials/authentication/abac"&gt;GitHub Repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>fauna</category>
      <category>node</category>
    </item>
    <item>
      <title>Using Doppler in Serverless Applications</title>
      <dc:creator>IsaacThaJunior</dc:creator>
      <pubDate>Tue, 28 Sep 2021 04:27:33 +0000</pubDate>
      <link>https://dev.to/isaacthajunior/using-doppler-in-serverless-applications-13bn</link>
      <guid>https://dev.to/isaacthajunior/using-doppler-in-serverless-applications-13bn</guid>
      <description>&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Secrets management is a core part of any application development as it helps keep secrets safe and ensures that you can control how and when your secrets are stored. Secret management might be tough for any developer as it requires broader security controls and a coordinated process for managing all types of secrets. Doppler was created to manage your secrets. In this tutorial, we will learn how to manage secrets in serverless applications using Doppler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goals
&lt;/h2&gt;

&lt;p&gt;In this tutorial, you will learn how to build a simple serverless application. We’ll then set up our project with Doppler to store these secret keys instead of using the native .env file. At the end of this tutorial you will learn how Doppler can be used to store all your secrets credentials.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Serverless applications?
&lt;/h2&gt;

&lt;p&gt;Serverless applications are cloud native applications that run without having us manage servers. they also have service integrations that are built in so that we can put our focus into building our applications instead of configuring it and thinking about servers. Serverless applications scale automatically as needed and respond to change faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are secrets?
&lt;/h2&gt;

&lt;p&gt;Simply put, secrets are sets of sensitive information that unlocks protected resources and are used to authenticate privileged users. They are also known as digital authentication credentials. Passwords are a well-known example, but there are APIs, SSH keys, private certificates, etc. These secrets are fundamental to an application's productivity. Still, they can cause huge risks if not handled properly, and that is why you need a secret manager to help remove these risks. This is where &lt;a href="https://www.doppler.com/"&gt;Doppler&lt;/a&gt; comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  ENV files and why you should stop using it
&lt;/h2&gt;

&lt;p&gt;A .env file is a simple configuration file used for customizing and controlling app environment variables. Simply put, it is used to keep secrets out of source code and has been used and is still used by developers today. Inasmuch as it has served us in the past and is still serving us, you should not use them again for storing confidential information.&lt;/p&gt;

&lt;p&gt;One of the reasons is that .env files breaks down during updates and branch merging. Another is that it is hard to track access because the domain where they are stored is completely available.&lt;/p&gt;

&lt;p&gt;One other reason is that managing .env files is time consuming and error prone if done manually which might give rise to misconfiguration.&lt;/p&gt;

&lt;p&gt;These reasons are why you need a fully automated secret manager like &lt;a href="https://www.doppler.com/"&gt;Doppler&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Doppler?
&lt;/h2&gt;

&lt;p&gt;According to its &lt;a href="https://docs.doppler.com/docs/enclave-guide"&gt;documentation&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;Doppler's secure and scalable Universal Secrets Manager seeks to make developers lives easier by removing the need for env files, hardcoded secrets, and copy-pasted credentials.&lt;br&gt;
The Doppler CLI provides easy access to secrets in every environment from local development to production and a single dashboard makes it easy for teams to centrally manage app configuration for any application, platform, and cloud provider.&lt;br&gt;
Doppler works for every language with a steadily growing list of integrations and to get started, choose your type of adventure. Whether you want to create your first project or install the Doppler CLI, you have come to the right place.&lt;br&gt;
Doppler provides a safe and secure place for developers to store secrets, thereby doing away with hardcoded secrets and .env files, which have a very high risk of your secrets getting exposed or accessed by unauthorized parties. Doppler also removes the human element and automates the secret management process.&lt;/p&gt;

&lt;p&gt;Doppler also has its CLI that makes it easier to install, authenticate and run your applications in a few clicks. Doppler groups secrets together by application in its dashboard so that access is served when the application starts.&lt;/p&gt;

&lt;p&gt;Doppler also makes it easier for users to integrate directly from most major cloud platforms like Heroku, Netlify, and other secret managers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a Serverless application
&lt;/h2&gt;

&lt;p&gt;In this section, readers will learn how to manage app secrets in a serverless application using Doppler.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QQVkaU4R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x17lcqrrh1ih2gjhsbmq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QQVkaU4R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x17lcqrrh1ih2gjhsbmq.png" alt="Serverless application"&gt;&lt;/a&gt;&lt;br&gt;
In the image above, we have our serverless application. We need to get our secret keys from FaunaDB to store them in our secret manager.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XmG_QSUX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ckabd7j1eehpygernejy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XmG_QSUX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ckabd7j1eehpygernejy.png" alt="our project"&gt;&lt;/a&gt;&lt;br&gt;
Then we navigated to the security tab, and there we got the secret key which we will use for our application, as we will see from the image below:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9XEZjHbH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u5kk4ye972rbsy9h4lcl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9XEZjHbH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u5kk4ye972rbsy9h4lcl.png" alt="security dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Doppler
&lt;/h2&gt;

&lt;p&gt;Before we start saving our secrets on Doppler, we first have to create an account. Then we create a workplace that we can save with any name we want. Our workplace should look like the image below:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vDiCSV2B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5qiwqup1a7gnpw5ql46j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vDiCSV2B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5qiwqup1a7gnpw5ql46j.png" alt="workplace"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating our serverless project
&lt;/h2&gt;

&lt;p&gt;We will create our project on Doppler by navigating to the create project card when setting up our workspace. Then we will add the details of our projects, and the results should look like the image below if done correctly:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QWD5N4yc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jmsq613nyfqqw47m06y7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QWD5N4yc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jmsq613nyfqqw47m06y7.png" alt="project site"&gt;&lt;/a&gt;&lt;br&gt;
After we have created our application, we will then navigate to the dev environment. Then we will store our secret from Fauna in the secrets card, which should look like the image below if done correctly.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TOKKhVWd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzyaoi81oogyio8t93fd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TOKKhVWd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzyaoi81oogyio8t93fd.png" alt="Keys stored"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have successfully set up Doppler for a serverless application to secure our apps secrets. We have drastically reduced risks by doing away with .env files. &lt;br&gt;
With this article, serverless teams can now learn how to use Doppler for building serverless apps. First, using our serverless application, we connected it to FaunaDB for our secret keys. Next, we then stored the said keys using Doppler instead of the traditional  .env file. Readers can find the code used in this tutorial &lt;a href="https://github.com/IkehAkinyemi/serverless-ui-project"&gt;here&lt;/a&gt;, you can also learn more about Doppler &lt;a href="https://docs.doppler.com/docs"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
