<?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: Tonie</title>
    <description>The latest articles on DEV Community by Tonie (@tonieng).</description>
    <link>https://dev.to/tonieng</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%2F1026953%2F5c22e387-2024-4ded-8510-1aa28aaaeabc.jpeg</url>
      <title>DEV Community: Tonie</title>
      <link>https://dev.to/tonieng</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tonieng"/>
    <language>en</language>
    <item>
      <title>Implementing a Custom Payment Gateway Integration in MedusaJS</title>
      <dc:creator>Tonie</dc:creator>
      <pubDate>Wed, 02 Aug 2023 08:00:12 +0000</pubDate>
      <link>https://dev.to/tonieng/implementing-a-custom-payment-gateway-integration-in-medusajs-4ke7</link>
      <guid>https://dev.to/tonieng/implementing-a-custom-payment-gateway-integration-in-medusajs-4ke7</guid>
      <description>&lt;p&gt;When it comes to processing online payments, offering a diverse range of payment options is crucial for e-commerce applications. While MedusaJS provides native support for popular payment gateways, you may have specific requirements that necessitate integrating a custom payment gateway like Paystack. In this article, we will guide you through the process of implementing Paystack as a custom payment gateway in MedusaJS, empowering you to offer seamless payment experiences to your customers.&lt;/p&gt;

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

&lt;p&gt;Medusa is an open-source, composable commerce platform specifically designed for developers. With its flexible architecture, MedusaJS empowers users to build highly customized commerce solutions catering to their needs. By providing modular commerce infrastructure, Medusa simplifies the custom development process, allowing developers to focus on creating unique and tailored e-commerce experiences.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yI5VIT5z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1689234642268/9da902a7-67c1-4f7f-81ec-d6bf3b5a6e40.avif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yI5VIT5z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1689234642268/9da902a7-67c1-4f7f-81ec-d6bf3b5a6e40.avif" alt="medusa e-commerce architecture" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;You can learn more about the Medusa architecture in their&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://docs.medusajs.com/development/fundamentals/architecture-overview"&gt;&lt;strong&gt;&lt;em&gt;official documentation&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One of the key strengths of MedusaJS is its ability to leverage cutting-edge infrastructure technologies. It embraces serverless architecture and employs edge workers to ensure exceptional scalability, reliability, and performance. This enables online stores built on Medusa to handle increasing traffic and deliver seamless user experiences, even during peak periods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Paystack?
&lt;/h2&gt;

&lt;p&gt;Paystack is a popular payment gateway used across several countries in Africa. It offers a developer-friendly API, and robust security features, and supports various payment methods.&lt;/p&gt;

&lt;p&gt;Integrating Paystack into a Medusa store offers several benefits, including a developer-friendly API, robust security measures, and support for multiple payment methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;p&gt;To fully understand the content of this article, you will need the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A recent version of node v16+&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Yarn (or npm) installed on your computer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A code editor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Paystack account (If you do not have one you can sign up using this &lt;a href="https://dashboard.paystack.com/#/signup"&gt;link&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Git&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Setting up Medusa Backend and Admin Dashboard
&lt;/h2&gt;

&lt;p&gt;In this section, we'll go through how to set and configure the Medusa backend and admin dashboard.&lt;/p&gt;

&lt;p&gt;The Medusa Backend acts as the core element accountable for managing the logic and data of the store. It provides REST APIs that are utilized by the Medusa Admin and Storefront for tasks such as data retrieval, creation, and modification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing the Medusa backend and Admin Dashboard
&lt;/h3&gt;

&lt;p&gt;Follow these steps to install the Medusa backend and admin dashboard.&lt;/p&gt;

&lt;p&gt;Open your terminal and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn create medusa-app

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You'll be prompted to enter the name of your project which will be used to create your project directory. You can use the default name &lt;code&gt;my-medusa-store&lt;/code&gt; or any name of your choice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, you will be asked to provide the necessary PostgreSQL database credentials, including the username and password. If the credentials are valid, you can proceed to the next step.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You'll then be asked to enter an email for your admin user. This email will be used to signup on your admin dashboard.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After these, the setup process will begin and on completion, the Medusa backend will start and the admin dashboard will be opened in your default browser. This is where you sign up using the email you provided during the setup process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow the tutorial steps on the dashboard to create your first product.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Installing packages and configuring the backend.
&lt;/h3&gt;

&lt;p&gt;Open your terminal and type in the following command to install the &lt;code&gt;medusa-payment-paystack&lt;/code&gt; plugin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add medusa-payment-paystack

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This adds Paystack as a payment provider to Medusa e-commerce stores.&lt;/p&gt;

&lt;p&gt;Open your project with your code editor and go to the .env file. Here you'll have to add your paystack secret key using the following format You can get your secret key from the setting page on your paystack admin dashboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PAYSTACK_SECRET_KEY=yourpaystacksecretkey

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to the &lt;code&gt;medusa-config.js&lt;/code&gt; file and add the following lines of code within the &lt;code&gt;plugins&lt;/code&gt; array&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  {
    resolve: `medusa-payment-paystack`,
    options: {
      secret_key: PAYSTACK_SECRET_KEY, //declare this as a variable just above your plugin
    },
  },

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your medusa-config.js file should look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dotenv = require("dotenv");

let ENV_FILE_NAME = "";
switch (process.env.NODE_ENV) {
  case "production":
    ENV_FILE_NAME = ".env.production";
    break;
  case "staging":
    ENV_FILE_NAME = ".env.staging";
    break;
  case "test":
    ENV_FILE_NAME = ".env.test";
    break;
  case "development":
  default:
    ENV_FILE_NAME = ".env";
    break;
}

try {
  dotenv.config({ path: process.cwd() + "/" + ENV_FILE_NAME });
} catch (e) {}

// CORS when consuming Medusa from admin
const ADMIN_CORS =
  process.env.ADMIN_CORS || "http://localhost:7000,http://localhost:7001";

// CORS to avoid issues when consuming Medusa from a client
const STORE_CORS = process.env.STORE_CORS || "http://localhost:8000";

const DATABASE_URL =
  process.env.DATABASE_URL || "postgres://localhost/medusa-store";

const REDIS_URL = process.env.REDIS_URL || "redis://localhost:6379";
const PAYSTACK_SECRET_KEY = process.env.PAYSTACK_SECRET_KEY;
const STRIPE_API_KEY = process.env.STRIPE_API_KEY;

const plugins = [
  `medusa-fulfillment-manual`,
  `medusa-payment-manual`,
  {
    resolve: `@medusajs/file-local`,
    options: {
      upload_dir: "uploads",
    },
  },
  {
    resolve: `medusa-payment-stripe`,
    options: {
      api_key: STRIPE_API_KEY,
    },
  },
  {
    resolve: `medusa-payment-paystack`,
    options: {
      secret_key: PAYSTACK_SECRET_KEY,
    },
  },
  {
    resolve: "@medusajs/admin",
    /** @type {import('@medusajs/admin').PluginOptions} */
    options: {
      autoRebuild: true,
      develop: {
        open: process.env.OPEN_BROWSER !== "false",
      },
    },
  },
];

const modules = {
  /*eventBus: {
    resolve: "@medusajs/event-bus-redis",
    options: {
      redisUrl: REDIS_URL
    }
  },
  cacheService: {
    resolve: "@medusajs/cache-redis",
    options: {
      redisUrl: REDIS_URL
    }
  },*/
};

/** @type {import('@medusajs/medusa').ConfigModule["projectConfig"]} */
const projectConfig = {
  jwtSecret: process.env.JWT_SECRET,
  cookieSecret: process.env.COOKIE_SECRET,
  store_cors: STORE_CORS,
  database_url: DATABASE_URL,
  admin_cors: ADMIN_CORS,
  // Uncomment the following lines to enable REDIS
  // redis_url: REDIS_URL
};

/** @type {import('@medusajs/medusa').ConfigModule} */
module.exports = {
  projectConfig,
  plugins,
  modules,
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's all for the backend. Go to your terminal and run &lt;code&gt;yarn start&lt;/code&gt; to start up your backend server and admin dashboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Paystack as a Payment Option on the Admin Dashboard.
&lt;/h3&gt;

&lt;p&gt;With your backend now configured and running on the terminal. Open up your browser and go to &lt;code&gt;http://localhost:9000/app&lt;/code&gt; to access your admin dashboard. Log in using your credentials and use the following steps to Add Paystack as a payment option.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;On the navigation panel, click on the settings button to go to the settings page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, click on the &lt;strong&gt;+&lt;/strong&gt; icon to set up a new region or choose an existing region. click on the three dots and select Edit region to edit the details about a particular region.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter the necessary details (Country, currency, etc). Scroll to the bottom of the page where you have &lt;strong&gt;Payment Providers.&lt;/strong&gt; If you set up the Medusa backend correctly, you should see &lt;code&gt;paystack&lt;/code&gt; as a payment option. Select it and save.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;note:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;on the settings page you can add a new currency specific to your region by opening the&lt;/em&gt; &lt;strong&gt;&lt;em&gt;currency&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;tab.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's all you have to do on your Admin dashboard. Next, we will setup and configure our Storefront.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up and Configuring the Storefront
&lt;/h2&gt;

&lt;p&gt;For the storefront, we'll be using the Medusa Nextjs starter template. Use the following steps to install.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing the Storefront
&lt;/h3&gt;

&lt;p&gt;Open your terminal and type run the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app -e https://github.com/medusajs/nextjs-starter-medusa my-medusa-storefront

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the installation process, change to the newly created directory &lt;code&gt;my-medusa-storefront&lt;/code&gt; and rename the template environment variable file to use environment variables in development:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd my-medusa-storefront
mv .env.template .env

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;note:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;running the storefront in a Windows environment throws some errors, you should instead run it on a Linux-like environment.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Installing Packages
&lt;/h3&gt;

&lt;p&gt;Open up your terminal and run the following command to install the &lt;code&gt;react-paystack&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add react-paystack
//you might need to delete the package-lock.json

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a React library for implementing a Paystack payment gateway in React applications. It provides us with some vital components and functions to initiate and authorize payments.&lt;/p&gt;

&lt;p&gt;Open up your project within your code editor and navigate to the &lt;code&gt;.env&lt;/code&gt; file to add your &lt;strong&gt;paystack public test key&lt;/strong&gt; using the format below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Paystack Public Key
NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY=yourpublicapikey

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuring the Paystack Button Component
&lt;/h3&gt;

&lt;p&gt;Next, we will need to add Paystack as a payment provider in the payment button component. Navigate to the &lt;code&gt;/src/modules/checkout/components/payment-button/index.tsx&lt;/code&gt; file and update it using the following steps:&lt;/p&gt;

&lt;p&gt;First, we import the PaystackButton component from the react-paystack component we installed earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { PaystackButton } from "react-paystack"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will add &lt;strong&gt;paystack&lt;/strong&gt; as a &lt;code&gt;case&lt;/code&gt; in the &lt;code&gt;switch&lt;/code&gt; statement within the &lt;code&gt;PaymentButton&lt;/code&gt; function. In this case, we'll return a &lt;code&gt;PayStackPaymentButton&lt;/code&gt; component which we'll create in the next step. Update the switch statement to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch (paymentSession?.provider_id) {
    case "stripe":
      return (
        &amp;lt;StripePaymentButton session={paymentSession} notReady={notReady} /&amp;gt;
      )
    case "paystack":
      return (
        &amp;lt;PayStackPaymentButton session={paymentSession} notReady={notReady} /&amp;gt;
      )
    case "manual":
      return &amp;lt;ManualTestPaymentButton notReady={notReady} /&amp;gt;
    case "paypal":
      return (
        &amp;lt;PayPalPaymentButton notReady={notReady} session={paymentSession} /&amp;gt;
      )
    default:
      return &amp;lt;Button disabled&amp;gt;Select a payment method&amp;lt;/Button&amp;gt;
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, it's time to create the PayStackPaymentButton we used earlier. To do that, create a new component just under the &lt;code&gt;PaymentButton&lt;/code&gt; like the one below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* 
Assigns the value of the environment variable 
NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY to PAYSTACK_PUBLIC_KEY 
or an empty string if the environment variable is not set
*/
const PAYSTACK_PUBLIC_KEY = process.env.NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY || ""
const PayStackPaymentButton = ({
  session,
  notReady,
}: {
  session: PaymentSession
  notReady: boolean
}) =&amp;gt; {
  const { cart } = useCart()
  const { onPaymentCompleted } = useCheckout()

  const txRef = String(session.data?.paystackTxRef)
  const total = cart?.total || 0
  const email = cart?.email || ""
  const currency =
    cart?.region.currency_code.toUpperCase() === "NGN" ? "NGN" : "USD" || "NGN"

  return (
    &amp;lt;PaystackButton
      email={email}
      amount={total}
      reference={txRef}
      publicKey={PAYSTACK_PUBLIC_KEY}
      currency={currency}
      text="Pay with Paystack"
      onSuccess={onPaymentCompleted}
    /&amp;gt;
  )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above defines a component called &lt;code&gt;PayStackPaymentButton&lt;/code&gt; which takes two props: &lt;code&gt;session&lt;/code&gt; of type &lt;code&gt;PaymentSession&lt;/code&gt; and &lt;code&gt;notReady&lt;/code&gt; of type &lt;code&gt;boolean&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Within the component, it uses hooks to access the cart and checkout functionalities. It extracts the &lt;code&gt;paystackTxRef&lt;/code&gt; from the session data, the &lt;code&gt;total&lt;/code&gt; from the cart, and the &lt;code&gt;email&lt;/code&gt; from the cart.&lt;/p&gt;

&lt;p&gt;Based on the region currency code in the cart, it determines the currency to be either "NGN" or "USD" (defaulting to "NGN" if neither).&lt;/p&gt;

&lt;p&gt;Finally, it renders the &lt;code&gt;PaystackButton&lt;/code&gt; component imported from the &lt;code&gt;react-paystack&lt;/code&gt; library called with various props including the extracted &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;total&lt;/code&gt;, &lt;code&gt;txRef&lt;/code&gt;, PAYSTACK_PUBLIC_KEY, &lt;code&gt;currency&lt;/code&gt;, and a success callback function called &lt;code&gt;onPaymentCompleted&lt;/code&gt;. which was destructured from the &lt;code&gt;useCheckout&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;After adding all these changes, your payment button component should look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useCheckout } from "@lib/context/checkout-context"
import { PaymentSession } from "@medusajs/medusa"
import Button from "@modules/common/components/button"
import Spinner from "@modules/common/icons/spinner"
import { OnApproveActions, OnApproveData } from "@paypal/paypal-js"
import { PayPalButtons, PayPalScriptProvider } from "@paypal/react-paypal-js"
import { useElements, useStripe } from "@stripe/react-stripe-js"
import { useCart } from "medusa-react"
import React, { useEffect, useState } from "react"
import { PaystackButton } from "react-paystack"

type PaymentButtonProps = {
  paymentSession?: PaymentSession | null
}

const PaymentButton: React.FC&amp;lt;PaymentButtonProps&amp;gt; = ({ paymentSession }) =&amp;gt; {
  const [notReady, setNotReady] = useState(true)
  const { cart } = useCart()

  useEffect(() =&amp;gt; {
    setNotReady(true)

    if (!cart) {
      return
    }

    if (!cart.shipping_address) {
      return
    }

    if (!cart.billing_address) {
      return
    }

    if (!cart.email) {
      return
    }

    if (cart.shipping_methods.length &amp;lt; 1) {
      return
    }

    setNotReady(false)
  }, [cart])

  switch (paymentSession?.provider_id) {
    case "stripe":
      return (
        &amp;lt;StripePaymentButton session={paymentSession} notReady={notReady} /&amp;gt;
      )
    case "paystack":
      return (
        &amp;lt;PayStackPaymentButton session={paymentSession} notReady={notReady} /&amp;gt;
      )
    case "manual":
      return &amp;lt;ManualTestPaymentButton notReady={notReady} /&amp;gt;
    case "paypal":
      return (
        &amp;lt;PayPalPaymentButton notReady={notReady} session={paymentSession} /&amp;gt;
      )
    default:
      return &amp;lt;Button disabled&amp;gt;Select a payment method&amp;lt;/Button&amp;gt;
  }
}

const PAYSTACK_PUBLIC_KEY = process.env.NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY || ""
const PayStackPaymentButton = ({
  session,
  notReady,
}: {
  session: PaymentSession
  notReady: boolean
}) =&amp;gt; {
  const { cart } = useCart()
  const { onPaymentCompleted } = useCheckout()

  const txRef = String(session.data?.paystackTxRef)
  const total = cart?.total || 0
  const email = cart?.email || ""
  const currency =
    cart?.region.currency_code.toUpperCase() === "NGN" ? "NGN" : "NGN" || "NGN"

  return (
    &amp;lt;PaystackButton
      email={email}
      amount={total}
      reference={txRef}
      publicKey={PAYSTACK_PUBLIC_KEY}
      currency={currency}
      text="Pay with Paystack"
      onSuccess={onPaymentCompleted}
    /&amp;gt;
  )
}

const StripePaymentButton = ({
  session,
  notReady,
}: {
  session: PaymentSession
  notReady: boolean
}) =&amp;gt; {
  const [disabled, setDisabled] = useState(false)
  const [submitting, setSubmitting] = useState(false)
  const [errorMessage, setErrorMessage] = useState&amp;lt;string | undefined&amp;gt;(
    undefined
  )

  const { cart } = useCart()
  const { onPaymentCompleted } = useCheckout()

  const stripe = useStripe()
  const elements = useElements()
  const card = elements?.getElement("cardNumber")

  useEffect(() =&amp;gt; {
    if (!stripe || !elements) {
      setDisabled(true)
    } else {
      setDisabled(false)
    }
  }, [stripe, elements])

  const handlePayment = async () =&amp;gt; {
    setSubmitting(true)

    if (!stripe || !elements || !card || !cart) {
      setSubmitting(false)
      return
    }

    await stripe
      .confirmCardPayment(session.data.client_secret as string, {
        payment_method: {
          card: card,
          billing_details: {
            name:
              cart.billing_address.first_name +
              " " +
              cart.billing_address.last_name,
            address: {
              city: cart.billing_address.city ?? undefined,
              country: cart.billing_address.country_code ?? undefined,
              line1: cart.billing_address.address_1 ?? undefined,
              line2: cart.billing_address.address_2 ?? undefined,
              postal_code: cart.billing_address.postal_code ?? undefined,
              state: cart.billing_address.province ?? undefined,
            },
            email: cart.email,
            phone: cart.billing_address.phone ?? undefined,
          },
        },
      })
      .then(({ error, paymentIntent }) =&amp;gt; {
        if (error) {
          const pi = error.payment_intent

          if (
            (pi &amp;amp;&amp;amp; pi.status === "requires_capture") ||
            (pi &amp;amp;&amp;amp; pi.status === "succeeded")
          ) {
            onPaymentCompleted()
          }

          setErrorMessage(error.message)
          return
        }

        if (
          (paymentIntent &amp;amp;&amp;amp; paymentIntent.status === "requires_capture") ||
          paymentIntent.status === "succeeded"
        ) {
          return onPaymentCompleted()
        }

        return
      })
      .finally(() =&amp;gt; {
        setSubmitting(false)
      })
  }

  return (
    &amp;lt;&amp;gt;
      &amp;lt;Button
        disabled={submitting || disabled || notReady}
        onClick={handlePayment}
      &amp;gt;
        {submitting ? &amp;lt;Spinner /&amp;gt; : "Checkout"}
      &amp;lt;/Button&amp;gt;
      {errorMessage &amp;amp;&amp;amp; (
        &amp;lt;div className="text-red-500 text-small-regular mt-2"&amp;gt;
          {errorMessage}
        &amp;lt;/div&amp;gt;
      )}
    &amp;lt;/&amp;gt;
  )
}

const PAYPAL_CLIENT_ID = process.env.NEXT_PUBLIC_PAYPAL_CLIENT_ID || ""

const PayPalPaymentButton = ({
  session,
  notReady,
}: {
  session: PaymentSession
  notReady: boolean
}) =&amp;gt; {
  const [submitting, setSubmitting] = useState(false)
  const [errorMessage, setErrorMessage] = useState&amp;lt;string | undefined&amp;gt;(
    undefined
  )

  const { cart } = useCart()
  const { onPaymentCompleted } = useCheckout()

  const handlePayment = async (
    _data: OnApproveData,
    actions: OnApproveActions
  ) =&amp;gt; {
    actions?.order
      ?.authorize()
      .then((authorization) =&amp;gt; {
        if (authorization.status !== "COMPLETED") {
          setErrorMessage(`An error occurred, status: ${authorization.status}`)
          return
        }
        onPaymentCompleted()
      })
      .catch(() =&amp;gt; {
        setErrorMessage(`An unknown error occurred, please try again.`)
      })
      .finally(() =&amp;gt; {
        setSubmitting(false)
      })
  }
  return (
    &amp;lt;PayPalScriptProvider
      options={{
        "client-id": PAYPAL_CLIENT_ID,
        currency: cart?.region.currency_code.toUpperCase(),
        intent: "authorize",
      }}
    &amp;gt;
      {errorMessage &amp;amp;&amp;amp; (
        &amp;lt;span className="text-rose-500 mt-4"&amp;gt;{errorMessage}&amp;lt;/span&amp;gt;
      )}
      &amp;lt;PayPalButtons
        style={{ layout: "horizontal" }}
        createOrder={async () =&amp;gt; session.data.id as string}
        onApprove={handlePayment}
        disabled={notReady || submitting}
      /&amp;gt;
    &amp;lt;/PayPalScriptProvider&amp;gt;
  )
}

const ManualTestPaymentButton = ({ notReady }: { notReady: boolean }) =&amp;gt; {
  const [submitting, setSubmitting] = useState(false)

  const { onPaymentCompleted } = useCheckout()

  const handlePayment = () =&amp;gt; {
    setSubmitting(true)

    onPaymentCompleted()

    setSubmitting(false)
  }

  return (
    &amp;lt;Button disabled={submitting || notReady} onClick={handlePayment}&amp;gt;
      {submitting ? &amp;lt;Spinner /&amp;gt; : "Checkout"}
    &amp;lt;/Button&amp;gt;
  )
}

export default PaymentButton

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we need to add Paystack as an option in our payment element. Navigate to &lt;code&gt;/src/modules/checkout/components/payment-element/index.tsx&lt;/code&gt; and update the PaymentInfoMap object to look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const PaymentInfoMap: Record&amp;lt;string, { title: string; description: string }&amp;gt; = {
  stripe: {
    title: "Credit card",
    description: "Secure payment with credit card",
  },
  "stripe-ideal": {
    title: "iDEAL",
    description: "Secure payment with iDEAL",
  },
  paypal: {
    title: "PayPal",
    description: "Secure payment with PayPal",
  },
  paystack: {
    title: "Paystack",
    description: "Secure payment with Paystack",
  },
  manual: {
    title: "Test payment",
    description: "Test payment using medusa-payment-manual",
  },
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code defines a constant variable named "PaymentInfoMap" as an object with key-value pairs. The keys are strings representing various payment methods, and the values are objects with two properties: "title" and "description".&lt;/p&gt;

&lt;p&gt;And voila, you've successfully integrated the Paystack payment processor into the Medusa e-commerce application. Here's a quick demo of the checkout process&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/_AN60Cg7wOI"&gt;https://youtu.be/_AN60Cg7wOI&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;In this article, we've covered how to implement a custom payment processor like Paystack into a Medusa e-commerce application.&lt;/p&gt;

&lt;p&gt;The process involves setting up the Medusa backend and admin dashboard, installing the necessary packages, configuring the backend to include the Paystack plugin, and adding Paystack as a payment option in the admin dashboard. Additionally, the storefront needs to be set up and configured to integrate Paystack as a payment provider. This includes installing the Medusa Next.js starter template, configuring the Paystack button component in the payment button module, and adding paystack as an option in the payment element.&lt;/p&gt;

&lt;p&gt;By following these steps, you can successfully integrate Paystack into MedusaJS and offer seamless payment experiences to customers. The integration of Paystack expands the payment options available to customers, enhances security, and ensures a smooth checkout process, ultimately improving the overall user experience and driving customer satisfaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.medusajs.com/"&gt;Medusa Documentation:&lt;/a&gt; The official documentation of Medusa provides in-depth information about the platform's features, architecture, and usage. It serves as a comprehensive guide to help you understand and utilize Medusa effectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/medusajs/medusa"&gt;Medusa GitHub Repository:&lt;/a&gt; The GitHub repository of Medusa houses the source code, issue tracker, and community contributions. You can explore the repository to access the latest updates, contribute to the project, or report any issues you encounter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://paystack.com/docs/"&gt;Paystack Documentation:&lt;/a&gt; If you want to delve deeper into Paystack's capabilities and explore its features, the Paystack documentation provides comprehensive resources, including API references, integration guides, and troubleshooting tips.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/Tonie-NG/medusa-payment-integration"&gt;Article Code Repository:&lt;/a&gt; Access the GitHub repository containing the code for this article to explore the complete implementation of the Paystack custom payment gateway in Medusa. The repository includes the backend and frontend code, as well as instructions for setup and configuration.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Introduction to Authentication and Authorization using JSON Web Tokens in Nodejs</title>
      <dc:creator>Tonie</dc:creator>
      <pubDate>Thu, 11 May 2023 05:54:46 +0000</pubDate>
      <link>https://dev.to/tonieng/introduction-to-authentication-and-authorization-using-json-web-tokens-in-nodejs-p4a</link>
      <guid>https://dev.to/tonieng/introduction-to-authentication-and-authorization-using-json-web-tokens-in-nodejs-p4a</guid>
      <description>&lt;p&gt;As someone who’s been deeply involved with web applications, I can’t emphasize enough how critical they’ve become in our daily lives. Consequently, they demand reliable authentication and authorization mechanisms to safeguard sensitive information from prying eyes. In my opinion, JSON Web Tokens (JWT) offer a refreshingly simple yet secure way to implement these mechanisms in Node.js applications. In this article, I’ll provide you with a detailed guide to JWT-based authentication and authorization in Node.js, complete with a step-by-step walkthrough, helpful code snippets, and best practices you can follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are JSON Web Tokens (JWTs)?
&lt;/h2&gt;

&lt;p&gt;JSON Web Tokens (JWTs) are compact, URL-safe means of representing claims to be transferred between two parties. JWTs consist of three parts: a header, a payload, and a signature. The header contains metadata about the token, such as the algorithm used to sign it. The payload contains claims, which are statements about an entity (typically, the user) and additional data. The signature is used to verify that the sender of the JWT is who it says it is and to ensure that the message wasn’t changed along the way.&lt;/p&gt;

&lt;p&gt;JWTs provide several advantages over traditional session-based authentication. Firstly, they don’t require storing user information on the server, which makes them highly scalable and easy to use. Secondly, they are stateless, which means that there is no need to manage server-side sessions. Thirdly, they can be easily exchanged between different systems and applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of JWT structure
&lt;/h2&gt;

&lt;p&gt;JSON Web Tokens (JWTs) are a type of token that consists of three parts: a header, a payload, and a signature. JWTs are encoded in Base64 URL format, which makes them easy to transmit over HTTP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5n2l3kuff09bbznfbw2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5n2l3kuff09bbznfbw2n.png" alt="Structure of JSON Web Token (jwt)" width="378" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The header of a JWT contains information about the token, such as the algorithm used for the signature. The header is typically a JSON object that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;alg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HS256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;typ&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JWT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;alg&lt;/code&gt; property specifies the algorithm used for the signature, which can be HMAC, RSA, or ECDSA. The &lt;code&gt;typ&lt;/code&gt; property specifies the type of token, which is always “JWT” for JWTs.&lt;/p&gt;

&lt;p&gt;The payload of a JWT contains the claims, or pieces of information, about the user or client. The payload is also a JSON object that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sub&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1234567890&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;iat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1516239022&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;sub&lt;/code&gt; property specifies the subject of the token, which is typically the user ID. The &lt;code&gt;name&lt;/code&gt; property specifies the name of the user. The &lt;code&gt;iat&lt;/code&gt; property specifies the time at which the token was issued, in Unix timestamp format.&lt;/p&gt;

&lt;p&gt;Finally, the signature of a JWT is used to verify the integrity of the token. The signature is calculated by combining the header and payload of the token with a secret key, and then encoding the result using the algorithm specified in the header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;HMACSHA256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;base64UrlEncode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
  &lt;span class="nf"&gt;base64UrlEncode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;bit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="nx"&gt;base64&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  JWT claims and their significance
&lt;/h2&gt;

&lt;p&gt;JWT claims are pieces of information about the user or client that are included in the token’s payload. Claims can be used to provide context about the user or client, such as their ID or role, and can be used for both authentication and authorization purposes.&lt;/p&gt;

&lt;p&gt;There are three types of claims in a JWT:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Registered claims – These are a set of predefined claims that are commonly used in JWTs. Some examples of registered claims include iss (issuer), exp (expiration time), and nbf (not before). Registered claims are optional, but using them can make your JWTs more interoperable with other systems.&lt;/li&gt;
&lt;li&gt;Public claims – These are claims that are defined by the user and are intended to be shared with others. Public claims should follow the naming conventions specified in the JWT specification.&lt;/li&gt;
&lt;li&gt;Private claims – These are claims that are specific to your application and are not intended to be shared with others. Private claims should use a namespace that is specific to your application, to avoid conflicts with other claims.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Uses of JWT Claims
&lt;/h3&gt;

&lt;p&gt;JWT claims can be used for various purposes in your application, including:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Authentication – JWTs can be used to authenticate users by including a sub claim in the payload that identifies the user. When a user logs in, you can create a JWT with the user’s ID as the sub claim, and then use the JWT to authenticate the user on subsequent requests.&lt;/li&gt;
&lt;li&gt;Authorization – JWTs can be used to authorize users by including a roles claim in the payload that specifies the user’s roles or permissions. When a user makes a request, you can verify their JWT and check whether the roles claim includes the required role for the requested action.&lt;/li&gt;
&lt;li&gt;Statelessness – Because JWTs contain all the necessary information about the user or client, they can be used to create stateless APIs. This means that you don’t need to store session data on the server, which can improve scalability and reduce complexity.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Benefits of JWT
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Stateless: JWTs are stateless, meaning that the server does not need to keep track of sessions or tokens. This makes JWTs easier to scale and more efficient to use in distributed systems.&lt;/li&gt;
&lt;li&gt;Cross-domain: JWTs can be used across different domains and servers, making them a flexible solution for authentication and authorization in modern web applications.&lt;/li&gt;
&lt;li&gt;Security: JWTs are digitally signed using a secret key, making it difficult for an attacker to forge or tamper with the token. Additionally, JWTs can be encrypted to provide an extra layer of security.&lt;/li&gt;
&lt;li&gt;Decentralized: JWTs can be generated and verified by different services, allowing for decentralized authentication and authorization in microservices architectures.&lt;/li&gt;
&lt;li&gt;Payload: JWTs can contain a payload of user data, such as user ID or user permissions, making them useful for authorization as well as authentication.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Authentication with JWT in Node.js
&lt;/h2&gt;

&lt;p&gt;Authentication is the process of verifying the identity of a user or a client trying to access a resource or service. In Node.js, authentication is typically implemented by requiring users to provide a valid set of credentials, such as a username and password, to gain access to the application. The server then checks the provided credentials against a database or a third-party authentication service, and if the credentials are valid, the user is granted access.&lt;/p&gt;

&lt;p&gt;When a user or client logs in to a Node.js web application, the server generates a JWT and sends it back to the client. This JWT contains a set of claims, which are pieces of information about the user or client, such as their ID or role. The JWT is then stored on the client side, typically in a cookie or in local storage.&lt;/p&gt;

&lt;p&gt;The authentication process using JWT involves three steps: (1) the client sends a login request with their credentials, (2) the server verifies the credentials and generates a JWT, and (3) the server sends the JWT to the client, which can then use it to access protected resources.&lt;/p&gt;

&lt;p&gt;To implement JWT-based authentication in Node.js, you can use the “jsonwebtoken” library. Here’s a step-by-step guide:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the “jsonwebtoken” library using npm.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="s2"&gt;`npm install jsonwebtoken`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
js&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a login route in your Node.js application that accepts user credentials (e.g., username and password).&lt;/li&gt;
&lt;li&gt;Validate the credentials and generate a JWT using the “jsonwebtoken” library.&lt;/li&gt;
&lt;li&gt;Send the JWT back to the client as a response.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Check if the user exists and the password is correct&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid username or password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Generate a JWT with a secret key&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secretKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mySecretKey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1h&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secretKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Return the token to the client&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the example above, we create a &lt;code&gt;login&lt;/code&gt; route that accepts a username and password from the client. We then check if the user exists and the password is correct. If the credentials are valid, we generate a JWT using the “jsonwebtoken” library and send it back to the client as a response.&lt;/p&gt;
&lt;h2&gt;
  
  
  Authorization with JWT in Node.js
&lt;/h2&gt;

&lt;p&gt;Authorization, on the other hand, is the process of determining whether a user or a client has the necessary permissions to access a specific resource or perform a specific action in the application. In Node.js, authorization is typically implemented by assigning roles or permissions to users based on their identity or other attributes. For example, a user with an “admin” role may be authorized to access and modify certain parts of the application, while a regular user may only be authorized to view certain resources.&lt;/p&gt;

&lt;p&gt;Authorization in the context of JWTs is often implemented by including user or client permissions as claims in the JWT. For example, a user with an “admin” role may have an “admin” claim in their JWT, which grants them access to certain parts of the application that regular users cannot access. The server can then check the presence of the “admin” claim in the JWT to determine whether the user is authorized to perform a specific action or access a specific resource.&lt;/p&gt;

&lt;p&gt;Once a client has a valid JWT, they can use it to access protected resources on the server. To implement JWT-based authorization in Node.js, you can use middleware functions that verify the JWT and check the user’s permissions before allowing access to the protected resource.&lt;/p&gt;

&lt;p&gt;Here’s a step-by-step guide for implementing JWT-based authorization in Node:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a middleware function that verifies the JWT and check the user’s permissions before allowing access to the protected resource.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authMiddleware&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No token provided&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secretKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/protected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;authMiddleware&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You are authorized to access this resource&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the example above, we create a middleware function that verifies the JWT and sets the decoded payload as the &lt;code&gt;req.user&lt;/code&gt; object. We then use this middleware function to protect the &lt;code&gt;/protected&lt;/code&gt; route.&lt;/p&gt;

&lt;p&gt;When a client tries to access the &lt;code&gt;/protected&lt;/code&gt; route, the middleware function will verify the JWT in the “Authorization” header. If the JWT is valid, the middleware function will set the &lt;code&gt;req.user&lt;/code&gt; object and allow the client to access the protected resource. If the JWT is invalid or missing, the middleware function will return an error response.&lt;/p&gt;
&lt;h2&gt;
  
  
  Token Refresh and Expiry
&lt;/h2&gt;

&lt;p&gt;One of the key features of JWTs is their ability to set an expiration time for the token. This provides an added layer of security by ensuring that a token cannot be used indefinitely. When a token expires, the user must obtain a new token to continue accessing protected resources.&lt;/p&gt;

&lt;p&gt;In addition to setting an expiration time, JWTs can also include a refresh token. A refresh token is a separate token that is used to obtain a new JWT when the original token has expired. This can provide a better user experience by allowing users to continue accessing protected resources without having to constantly log in.&lt;/p&gt;

&lt;p&gt;To implement token refresh and expiry in your Node.js application, you can use a combination of middleware and token management libraries. Here’s an example of how to implement token refresh and expiry using the jsonwebtoken library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsonwebtoken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;refreshTokenSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your_refresh_token_secret&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accessTokenSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your_access_token_secret&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;refreshTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="c1"&gt;// Middleware to check if user is authenticated&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authenticateJWT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authHeader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;authHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accessTokenSecret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Endpoint to generate new access and refresh tokens&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;refreshTokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refreshTokenSecret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;accessTokenSecret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;15m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Endpoint to log in and generate access and refresh tokens&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// authenticate user&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accessTokenSecret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;15m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refreshTokenSecret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;refreshTokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Endpoint to log out and revoke refresh token&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/logout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;refreshTokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;refreshTokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;204&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we’re using two JWT secrets: one for access tokens and one for refresh tokens. We’re also storing refresh tokens in an array on the server, so that we can check whether a given refresh token is valid.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;authenticateJWT&lt;/code&gt; middleware checks whether a user is authenticated by verifying the access token. If the token is valid, it sets the &lt;code&gt;req.user&lt;/code&gt; property to the user object.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/token&lt;/code&gt; endpoint is used to generate new access tokens using a valid refresh token. If the refresh token is valid, we verify it and generate a new access token with a 15 minute expiration time.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/login&lt;/code&gt; endpoint is used to log in and generate a new access token and refresh token pair. We generate both tokens and store the refresh token in the refreshTokens array&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for JWT-based Authentication and Authorization
&lt;/h2&gt;

&lt;p&gt;Here are some best practices to follow when implementing JWT-based authentication and authorization in Node.js:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Always use a secure random secret key for signing and verifying JWTs.&lt;/li&gt;
&lt;li&gt;Use short-lived JWTs (e.g., one hour) to minimize the risk of token hijacking.&lt;/li&gt;
&lt;li&gt;Implement rate limiting and other security measures to prevent brute force attacks on the login endpoint.&lt;/li&gt;
&lt;li&gt;Use HTTPS to encrypt all communication between the client and the server.&lt;/li&gt;
&lt;li&gt;Store sensitive user data (e.g., passwords) securely using hashing and salting.&lt;/li&gt;
&lt;li&gt;Use a consistent naming convention for JWT-related headers and payload fields.&lt;/li&gt;
&lt;li&gt;Use middleware functions to validate JWTs and protect resources.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;JSON Web Tokens (JWTs) provide a secure and efficient way to implement authentication and authorization in Node.js applications. By following the best practices outlined in this article, you can ensure that your JWT-based authentication and authorization system is robust and secure.&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>jwt</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What is Algorithmic Efficiency?: An Introduction to Asymptotic Analysis.</title>
      <dc:creator>Tonie</dc:creator>
      <pubDate>Mon, 13 Mar 2023 08:00:39 +0000</pubDate>
      <link>https://dev.to/tonieng/what-is-algorithmic-efficiency-an-introduction-to-asymptotic-analysis-fo2</link>
      <guid>https://dev.to/tonieng/what-is-algorithmic-efficiency-an-introduction-to-asymptotic-analysis-fo2</guid>
      <description>&lt;p&gt;Algorithms are at the heart of computer science and programming. They are a set of instructions that a computer follows to perform a specific task.&lt;/p&gt;

&lt;p&gt;It's like a recipe that helps you bake a cake or cook a meal, but for computers. Just like there are different recipes to cook a meal, there are also different ways to solve a problem in programming and it is in the interest of the programmer to pick the most efficient approach.&lt;/p&gt;

&lt;p&gt;Algorithmic efficiency is the measurement of the performance of an algorithm in terms of time and space/memory complexity. Simply put, an efficient/ideal algorithm takes up the least possible memory and executes it in the least possible time.&lt;/p&gt;

&lt;p&gt;When analyzing algorithms, it's not enough to simply measure how long an algorithm takes to run on a specific input. Instead, we need to have an understanding of how an algorithm's performance scales as the input size grows.&lt;/p&gt;

&lt;p&gt;This is where Asymptotic analysis comes in. It allows us to analyze the performance of an algorithm as the input size grows larger and larger. By using asymptotic analysis, we can compare different algorithms and make informed decisions about which algorithm to use in a given situation. We can also identify bottlenecks in an algorithm's performance and find ways to optimize it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Asymptotic Analysis?
&lt;/h2&gt;

&lt;p&gt;Asymptotic analysis is a technique that is used to analyze the behavior and performance of an algorithm as the input size grows larger and larger.&lt;/p&gt;

&lt;p&gt;To understand this, let's consider a simple example:&lt;/p&gt;

&lt;p&gt;Imagine you were given an array of numbers and told to find a number within that list and deduce its position.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linear Search Algorithm
&lt;/h3&gt;

&lt;p&gt;One way you can solve this task is to go into the array and check the position of every value in the list until we get to the value we are looking for. And if we don't find the value only then can we confirm that the element does not exist in the array.&lt;/p&gt;

&lt;p&gt;This is called the linear search algorithm and here is an example of its implementation in python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def linear_search(array, target):
    for i in range(len(array)):
        if array[i] == target:
            return i
    return None

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, the function &lt;code&gt;linear_search&lt;/code&gt; function takes an &lt;code&gt;array&lt;/code&gt; and a &lt;code&gt;target element&lt;/code&gt; as inputs. It then iterates through each element in the array until it finds the target element, and returns the index position of the target element. If the target element is not found in the array, the function returns &lt;code&gt;None&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Given an array of 5 elements, this might look like a very good algorithm as it won't take much time to find the target element. But if we keep increasing the size of the array, we would find out that there would be a proportionate increase in the amount of time it will take for our algorithm to execute the task.&lt;/p&gt;

&lt;p&gt;A graphical interpretation of this algorithm will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2MJRFbH_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1678692147857/7aec8d03-8e27-4c89-a97c-70875d96d065.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2MJRFbH_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1678692147857/7aec8d03-8e27-4c89-a97c-70875d96d065.png" alt="" width="815" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, this is not an efficient algorithm because as the input size increases, it takes more and more time to execute.&lt;/p&gt;

&lt;p&gt;Here's a better way to search -&lt;/p&gt;

&lt;h3&gt;
  
  
  Binary Search Algorithm
&lt;/h3&gt;

&lt;p&gt;This algorithm begins by comparing the target value to the middle element of the array. If the middle element is the target value, the search is complete. Otherwise, the algorithm determines whether the target value is greater or less than the middle element, and discards half of the list based on this comparison. The process is repeated with the remaining half of the list until the target value is found or the list is empty&lt;/p&gt;

&lt;p&gt;For example, let's say we have a &lt;strong&gt;sorted&lt;/strong&gt; list of numbers [0, 1, 3, 4, 5, 7, 9, 11, 13] and we want to search for the value 7.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The algorithm starts by comparing 7 to the middle element, which is 5.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since 7 is greater than 5, the algorithm discards the first half of the list and repeats the process with the remaining half [7, 9, 11, 13].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The algorithm now compares 7 to the middle element of this new list, which is 9.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since 7 is less than 9, the algorithm discards the second half of the list and repeats the process with the remaining half [7].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The algorithm has now found the target value and the search is complete.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;In a binary search, the elements must be arranged in&lt;/em&gt; &lt;strong&gt;&lt;em&gt;sorted&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;order.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here's an implementation of the binary search algorithm in python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def binary_search(list, item):
    low = 0
    high = len(list) - 1

    while low &amp;lt;= high:
        mid = int((low + high)/2)
        guess = list[mid]

        if guess == item:
            return mid
        if guess &amp;gt; item:
            high = mid - 1
        else:
            low = mid + 1
    return None

sorted_list = [0, 1, 3,4, 5, 7, 9, 11, 13] 

print(binary_search(sorted_list, 7))

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's see the graphical representation of how this algorithm compares to the linear search algorithm&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gXynOWy_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1678692128198/4fa0ca0e-efe9-4ec4-a8b4-0e81cbcdbdf3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gXynOWy_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1678692128198/4fa0ca0e-efe9-4ec4-a8b4-0e81cbcdbdf3.png" alt="" width="880" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, the binary search outperforms the linear search algorithm as the input size keeps increasing. This makes it a more efficient algorithm for this case.&lt;/p&gt;

&lt;p&gt;I want you to observe something peculiar in the graph above. We can see that for small input sizes, the linear search algorithm and the binary search look to perform at the same rate. If we were to take our decision from this point, it would be a wrong and ill-informed decision. This is why we use asymptotic analysis!&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Asymptotic Analysis
&lt;/h2&gt;

&lt;p&gt;As we have seen earlier, asymptotic analysis is a very important tool for analyzing the efficiency of algorithms. I've listed some of its benefits below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Simplification: Asymptotic analysis allows us to simplify the performance analysis of algorithms by focusing on their growth rate as the input size increases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Efficiency Comparison: Asymptotic analysis allows us to compare the efficiency of algorithms for large input sizes, regardless of the specific hardware or software environment in which they are executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Design Improvement: Asymptotic analysis can help us identify inefficiencies in algorithms and guide us in making improvements to their design, leading to faster and more scalable solutions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prediction: Asymptotic analysis can help us predict the behavior of algorithms for large input sizes, allowing us to plan for the resources needed to execute them effectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Language and platform independence: Asymptotic analysis provides a language and platform-independent way of analyzing algorithms, making it easier to communicate about their performance characteristics and compare them across different programming languages and platforms.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that's a wrap 😃&lt;/p&gt;

&lt;p&gt;As we have seen, Algorithmic efficiency refers to how well an algorithm performs in terms of the resources it requires, such as time and memory. Asymptotic analysis is a technique used to analyze the efficiency of an algorithm as the input size grows.&lt;/p&gt;

&lt;p&gt;An efficient algorithm should be able to handle large inputs in a reasonable amount of time and with minimal memory usage.&lt;/p&gt;

&lt;p&gt;If you found this article insightful, kindly like, comment, and share it. I'd like this article to reach as many people as possible.&lt;/p&gt;

&lt;p&gt;Thank you and happy coding&lt;/p&gt;

</description>
      <category>asymptotic</category>
      <category>algorithms</category>
      <category>dsa</category>
    </item>
    <item>
      <title>Dockerizing Your React App: A Step-by-Step Guide</title>
      <dc:creator>Tonie</dc:creator>
      <pubDate>Tue, 07 Mar 2023 08:20:18 +0000</pubDate>
      <link>https://dev.to/tonieng/dockerizing-your-react-app-a-step-by-step-guide-55ga</link>
      <guid>https://dev.to/tonieng/dockerizing-your-react-app-a-step-by-step-guide-55ga</guid>
      <description>&lt;p&gt;Docker is a popular tool for software developers and engineers looking to streamline the process of building, testing, and deploying applications. With its ability to create lightweight, portable containers that can run on any platform, Docker has significantly impacted the way we build and deploy software applications.&lt;/p&gt;

&lt;p&gt;One of the many benefits of Docker is that it allows you to easily containerize your applications, which can help to simplify the process of deploying your code to different environments. In this article, we will focus specifically on how to Dockerize a React application.&lt;/p&gt;

&lt;p&gt;React is a popular JavaScript library for building user interfaces, while Vite is a modern build tool that enables fast and efficient development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;p&gt;To follow along in this tutorial, you will need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Node and npm installed on your machine&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A recent version of &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt; on your local machine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A text editor (preferably, VSCode)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Create a React Application
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new folder and open it within your text editor. Navigate to your terminal and type in the following command:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go into the &lt;code&gt;package.json&lt;/code&gt; file within your application and update the &lt;code&gt;dev&lt;/code&gt; command within the script tag with this&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type in the following command to start your development server&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to Dockerize a React Application
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create two files in the root directory named Dockerfile Dockerfile.dev respectively. The difference between these files is that the former is used for a production build while the latter is used for a development build.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the following code into the two Dockerfiles&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new file within the root directory and name it &lt;code&gt;docker-compose.yml&lt;/code&gt; Copy the code below and paste it into the file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now that we have set up our application. Go to your terminal and type in the following code to build the application&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If everything ran successfuly, you should see a message like the one below in your terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up
[+] Running 1/1
 - Container docker-react-client-1 Recreated 1.6s 
Attaching to docker-react-client-1
docker-react-client-1 | 
docker-react-client-1 | &amp;gt; docker-react@0.0.0 dev 
docker-react-client-1 | &amp;gt; vite --port 3000 --host
docker-react-client-1 | 
docker-react-client-1 | 
docker-react-client-1 | VITE v4.1.4 ready in 4809 ms
docker-react-client-1 | 
docker-react-client-1 | Local: http://localhost:3000/
docker-react-client-1 | Network: http://172.19.0.2:3000/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voila!! You have dockerized your first react application. Now you can go ahead and develop your application and all the changes you make will be automatically picked up by docker whenever you run the &lt;code&gt;docker-compose up&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;To see your application, go to your browser and type &lt;strong&gt;&lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you found this helpful, please like, comment and share it. I'd like this article to reach as many people as possible.&lt;/p&gt;

&lt;p&gt;The source code can be found &lt;a href="https://github.com/Tonie-NG/docker-react"&gt;here on github&lt;/a&gt;. Don't forget to star&lt;/p&gt;

</description>
      <category>docker</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Building a Location-Map App in React using Vite and Mapbox</title>
      <dc:creator>Tonie</dc:creator>
      <pubDate>Mon, 20 Feb 2023 10:35:44 +0000</pubDate>
      <link>https://dev.to/tonieng/building-a-location-map-app-in-react-using-vite-and-mapbox-25eo</link>
      <guid>https://dev.to/tonieng/building-a-location-map-app-in-react-using-vite-and-mapbox-25eo</guid>
      <description>&lt;p&gt;Location-map apps like Google maps have become increasingly part of our day-to-day activities as we rely on them to navigate our surroundings and also get information about other places.&lt;/p&gt;

&lt;p&gt;In this article, we will explore how to build a location-map app in React using Vite and Mapbox.&lt;/p&gt;

&lt;p&gt;React is a popular JavaScript library for building user interfaces, while Vite is a modern build tool that enables fast and efficient development.&lt;/p&gt;

&lt;p&gt;Mapbox, on the other hand, is a powerful platform for building custom maps and integrating them into web and mobile applications.&lt;/p&gt;

&lt;p&gt;Throughout this article, we will cover the basic steps of setting up a React application, integrating Vite for fast development, and using Mapbox to add custom maps and location data to our app.&lt;/p&gt;

&lt;p&gt;And by the end of this article, you will have the knowledge and tools to create your location-map app using these technologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along in this tutorial, you will need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Basic knowledge of React and JavaScript&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node and npm installed on your machine&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Mapbox account (this is because you will need a personalized API key). If you don't have a Mapbox account, you can sign up using &lt;a href="https://account.mapbox.com/auth/signup/"&gt;this link&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can view the live version of this project &lt;a href="https://location-map.netlify.app/"&gt;here&lt;/a&gt;. This will give you an idea and expectation of the application we will be building today&lt;/p&gt;

&lt;h2&gt;
  
  
  Building out our Location-Map App
&lt;/h2&gt;

&lt;p&gt;Now that we have the prerequisites out of the way, it's time to get our hands dirty. Let's go!&lt;/p&gt;

&lt;h3&gt;
  
  
  Project setup
&lt;/h3&gt;

&lt;p&gt;Create a new folder on your local machine and open it within your preferred code editor. In this tutorial, we named our folder "location-map" and we used VS Code as our code editor.&lt;/p&gt;

&lt;p&gt;Open your terminal and type in the following command. This is to create our react project using Vite. The period sign "." tells Vite that we want our project to be initialized in our current directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create vite@latest . //if you use npm 
//or
yarn create vite . //if you use yarn

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompts using your arrow keys and pressing enter. Once you are done, you should have a project structure like the one below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gePZ3bRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1676838323544/5844934e-f4fb-478d-ad0e-610d26234d19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gePZ3bRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1676838323544/5844934e-f4fb-478d-ad0e-610d26234d19.png" alt="" width="880" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we need to install one dependency which is the Mapbox package. Open your terminal and type&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 mapbox-gl //if you use npm
//or
yarn add mapbox-gl //if you use yarn

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuring our App
&lt;/h3&gt;

&lt;p&gt;Go into the index.css file within the src folder. Replace the css there with the one below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

body {
  margin: 0;
  font-size: 1rem;
  overflow-x: hidden;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, go into the App.css file and replace the code there with the one 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-container {
  height: 100vh;
  width: 100vw;
}

.sidebar {
  background-color: rgba(35, 55, 75, 0.9);
  color: #fff;
  padding: 6px 12px;
  font-family: monospace;
  z-index: 1;
  position: absolute;
  bottom: 1rem;
  left: 0;
  margin: 12px;
  border-radius: 4px;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are just some default styles for our component and divs which we will create later.&lt;/p&gt;

&lt;p&gt;Also within the head tag in the index.html file, we need to add the following link tag. To enable us to use the default styles provided by Mapbox.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link
      rel="stylesheet"
      href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v4.1.1/mapbox-gl-directions.css"
      type="text/css"
    /&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now go into the &lt;code&gt;App.jsx&lt;/code&gt; file and delete every code logic within the &lt;code&gt;div&lt;/code&gt; with the class name &lt;code&gt;App&lt;/code&gt;. Your file should look like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iPLld532--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1676839088579/a2bffaa8-7f92-45a5-89ea-12e229edf0d8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iPLld532--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1676839088579/a2bffaa8-7f92-45a5-89ea-12e229edf0d8.png" alt="" width="880" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next go into your src folder and create a new file named ".env". This is where we will store our API key.&lt;/p&gt;

&lt;p&gt;Go to your Mapbox dashboard and at the bottom of the page, you will find your API key. Copy and paste it into the .env file so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VITE_MAPBOX_KEY = YOUR_API_KEY

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating our Map using Mapbox
&lt;/h3&gt;

&lt;p&gt;Go into the App.jsx file within the src folder and update the code to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mapboxgl from "mapbox-gl";
import { useEffect, useRef, useState } from "react";
import "./App.css";

mapboxgl.accessToken = import.meta.env.VITE_MAPBOX_KEY;
function App() {
  const mapContainer = useRef(null);
  const map = useRef(null);
  const [lng, setLng] = useState(-70.9);
  const [lat, setLat] = useState(42.35);
  const [zoom, setZoom] = useState(9);

  useEffect(() =&amp;gt; {
    if (map.current) return; // initialize map only once
    map.current = new mapboxgl.Map({
      container: mapContainer.current,
      style: "mapbox://styles/mapbox/streets-v12",
      center: [lng, lat],
      zoom: zoom,
    });

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;div ref={mapContainer} className="map-container" /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above, we imported the Mapbox package we installed earlier and we initialized our access token with the value we stored in our .env file.&lt;/p&gt;

&lt;p&gt;Next, we declared our app's default state using the useState and useRef hooks. Then we initialized our map using a useEffect hook. This will ensure that our map will be created as soon as our App component is mounted in the DOM.&lt;/p&gt;

&lt;p&gt;Also, we rendered this map in a div within the return statement.&lt;/p&gt;

&lt;p&gt;Open your terminal and start your application using the code below to see the application on your device's browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev 
//or
yarn run dev

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding a Div to show Longitude, Latitude and Zoom level
&lt;/h3&gt;

&lt;p&gt;Next, we need to add some interactivity to our application. First, we will add a div that shows the latitude and longitude of any location the user clicks on the map.&lt;/p&gt;

&lt;p&gt;For this, add another useEffect hook to our App.jsx component just below the previous one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; useEffect(() =&amp;gt; {
    if (!map.current) return; // wait for map to initialize
    map.current.on("move", () =&amp;gt; {
      setLng(map.current.getCenter().lng.toFixed(4));
      setLat(map.current.getCenter().lat.toFixed(4));
      setZoom(map.current.getZoom().toFixed(2));
    });
  });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This utilizes the useState hook we created earlier and updates the longitude, latitude and zoom level according to the user's interaction with the application.&lt;/p&gt;

&lt;p&gt;Update the return block in our to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;div className="sidebar"&amp;gt;
        Longitude: {lng} | Latitude: {lat} | Zoom: {zoom}
      &amp;lt;/div&amp;gt;
      &amp;lt;div ref={mapContainer} className="map-container" /&amp;gt;
    &amp;lt;/div&amp;gt;
  );

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save your code and refresh your browser to see how it looks. Nice, yeah? Now let's add more functionality&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding More Functionalities
&lt;/h3&gt;

&lt;p&gt;For this, we need to add some code to our first useEffect code block. Update the useEffect code block to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
    if (map.current) return; // initialize map only once
    map.current = new mapboxgl.Map({
      container: mapContainer.current,
      style: "mapbox://styles/mapbox/streets-v12",
      center: [lng, lat],
      zoom: zoom,
    });
    map.current.addControl(new mapboxgl.NavigationControl());
    map.current.addControl(new mapboxgl.FullscreenControl());
    map.current.addControl(
      new mapboxgl.GeolocateControl({
        positionOptions: {
          enableHighAccuracy: true,
        },
        trackUserLocation: true,
      })
    );
  });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;mapboxgl.NavigationControl() adds a button to enable the user zoom in, zoom out and rotate the map.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;mapboxgl.FullscreenControl() adds a button that allows the user to full-screen mode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;mapboxgl.GeolocateControl() adds a button that lets the user view their current location&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Adding the direction component
&lt;/h3&gt;

&lt;p&gt;One final component we will need in our application is a direction component that lets the user know the distance and time it will take to get from one point on our map to another. This will specify different formats like driving, cycling, walking etc.&lt;/p&gt;

&lt;p&gt;To achieve this, we'll be adding a cdn script tag to our index.html file. Add the following script tag within the head tag in the index.html file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v4.1.1/mapbox-gl-directions.js"&amp;gt;&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After adding this tag, your index.html file should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8" /&amp;gt;
    &amp;lt;link rel="icon" type="image/svg+xml" href="/vite.svg" /&amp;gt;
    &amp;lt;script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v4.1.1/mapbox-gl-directions.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;link
      rel="stylesheet"
      href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v4.1.1/mapbox-gl-directions.css"
      type="text/css"
    /&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
    &amp;lt;title&amp;gt;Location App using Map Box&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id="root"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;script type="module" src="/src/main.jsx"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we need to add some code to display the directions component in our application. To do that, add the following code snippet to the first useEffect code block in our App.jsx file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  map.current.addControl(
      new MapboxDirections({
        accessToken: mapboxgl.accessToken,
      }),
      "top-left"
    );

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will add the direction control at the top-left of our screen. At this point your App.jsx file should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mapboxgl from "mapbox-gl";
import { useEffect, useRef, useState } from "react";
import "./App.css";

mapboxgl.accessToken = import.meta.env.VITE_MAPBOX_KEY;

function App() {
  const mapContainer = useRef(null);
  const map = useRef(null);
  const [lng, setLng] = useState(-70.9);
  const [lat, setLat] = useState(42.35);
  const [zoom, setZoom] = useState(9);

  useEffect(() =&amp;gt; {
    if (map.current) return; // initialize map only once
    map.current = new mapboxgl.Map({
      container: mapContainer.current,
      style: "mapbox://styles/mapbox/streets-v12",
      center: [lng, lat],
      zoom: zoom,
    });
    map.current.addControl(new mapboxgl.NavigationControl());
    map.current.addControl(new mapboxgl.FullscreenControl());
    map.current.addControl(
      new mapboxgl.GeolocateControl({
        positionOptions: {
          enableHighAccuracy: true,
        },
        trackUserLocation: true,
      })
    );

    map.current.addControl(
      new MapboxDirections({
        accessToken: mapboxgl.accessToken,
      }),
      "top-left"
    );
  });

  useEffect(() =&amp;gt; {
    if (!map.current) return; // wait for map to initialize
    map.current.on("move", () =&amp;gt; {
      setLng(map.current.getCenter().lng.toFixed(4));
      setLat(map.current.getCenter().lat.toFixed(4));
      setZoom(map.current.getZoom().toFixed(2));
    });
  });

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;div className="sidebar"&amp;gt;
        Longitude: {lng} | Latitude: {lat} | Zoom: {zoom}
      &amp;lt;/div&amp;gt;
      &amp;lt;div ref={mapContainer} className="map-container" /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;In this article, we explored how to build a location-map app in React using Vite and Mapbox.&lt;/p&gt;

&lt;p&gt;We saw how to use React to build a flexible and responsive user interface that can easily integrate with Mapbox's mapping platform, which offers numerous customization options to create maps that fit the specific needs of our app.&lt;/p&gt;

&lt;p&gt;Whether it's visualizing data, creating interactive experiences, or simply providing a more immersive way to view a location, a location-map app built with React, Vite, and Mapbox has the potential to be a valuable tool for a wide range of use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Here are some useful resources to aid your development of this project&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://location-map.netlify.app/"&gt;Project live version&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/Tonie-NG/maps-app"&gt;Project Source code&lt;/a&gt;. Don't forget to star the repository &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.mapbox.com/help/tutorials/use-mapbox-gl-js-with-react/"&gt;Mapbox React Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://vitejs.dev/guide/"&gt;Vite Docs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have any questions or suggestions, I'm buzzing to hear from you in the comment section.&lt;/p&gt;

&lt;p&gt;Happy coding&lt;/p&gt;

</description>
      <category>react</category>
      <category>mapbox</category>
      <category>vite</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What is Database Migration?: Benefits of Database Migration</title>
      <dc:creator>Tonie</dc:creator>
      <pubDate>Thu, 16 Feb 2023 07:48:30 +0000</pubDate>
      <link>https://dev.to/tonieng/what-is-database-migration-benefits-of-database-migration-oc</link>
      <guid>https://dev.to/tonieng/what-is-database-migration-benefits-of-database-migration-oc</guid>
      <description>&lt;p&gt;A database is an organized collection of structured and logically related data and information.&lt;/p&gt;

&lt;p&gt;Databases play a crucial role in the development of modern-day technology, as they store and manage large amounts of data in an organized manner.&lt;/p&gt;

&lt;p&gt;To keep up with the ever-increasing demand for better data management solutions, the rapid pace of technological advancements, and the growth of an application, businesses usually have to change the properties and confines of the database, to enhance performance, security, and scalability.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore the concept of database migration and its benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Database Migration?
&lt;/h2&gt;

&lt;p&gt;In an application's lifecycle, there might be a need to make changes to the functionality of the application. To track these changes, we employ the services of version control.&lt;/p&gt;

&lt;p&gt;Version control is a set of practices and tools to track and manage our application's source files such that any version of the application at different points in the project's history can be retrieved.&lt;/p&gt;

&lt;p&gt;But what if our application utilizes an external and explicit dependency like a database? How do we version control this dependency? The answer to this is database migration.&lt;/p&gt;

&lt;p&gt;Database migration is a controlled way to manage and track incremental changes within a database.&lt;/p&gt;

&lt;p&gt;It helps transform a database from its current state to a new or desired state while preventing the loss of data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we do Database Migration?
&lt;/h2&gt;

&lt;p&gt;Let's consider a simple example:&lt;/p&gt;

&lt;p&gt;Imagine you have an application that stores users' information. To store this data, you would probably need a database that looks like this 👇🏼&lt;/p&gt;

&lt;p&gt;| id | name | role |&lt;br&gt;
| 1 | tonie | software developer |&lt;br&gt;
| 2 | victor | technical writer |&lt;/p&gt;

&lt;p&gt;Now, due to certain reasons, you need to update the functionality of your application. Maybe the government says that all applications that process and store users' data must process and store their email too.&lt;/p&gt;

&lt;p&gt;You quickly go over to your application and make changes to your codebase to accommodate this new rule by adding an extra field to the form and some logic to process it and then you realize that your database cannot store this new field as it was not predefined when creating the database.&lt;/p&gt;

&lt;p&gt;Well, you could decide to create an entirely new database and then configure your application to utilize it. But there's a tradeoff here: you will lose all the data that was present in your old database!&lt;/p&gt;

&lt;p&gt;So what's the solution to this dilemma? How do you update the boundaries and properties of your database to include this new field without losing your data?&lt;/p&gt;

&lt;p&gt;The solution to this is database migration!&lt;/p&gt;

&lt;p&gt;Database migration helps you make and track these changes within your database and also updates the properties of your database to reflect them while preserving your existing data.&lt;/p&gt;

&lt;p&gt;Back to our example. If a migration tool was used to initialize our database it means that the migration tool is aware of the current state of our database which can be called version one.&lt;/p&gt;

&lt;p&gt;Now to update the properties of our database, we would go into our migration script and redefine its properties to include or exclude the fields we want to have (in this case we want to add a new "email" column).&lt;/p&gt;

&lt;p&gt;Our migration tool will now go back to our database and apply the changes structurally and logically while keeping our current data. This updated version of our database is now tracked and saved as "version 2". This means we can roll back these changes at any point during our application's life cycle.&lt;/p&gt;

&lt;p&gt;Our updated database should look like this after the migration has taken place and we've added a new user&lt;/p&gt;

&lt;p&gt;| id | name | role | email |&lt;br&gt;
| 1 | tonie | software developer | null |&lt;br&gt;
| 2 | victor | technical writer | null |&lt;br&gt;
| 3 | chisom | new user | &lt;a href="mailto:chisom@newuser.com"&gt;chisom@newuser.com&lt;/a&gt; |&lt;/p&gt;

&lt;p&gt;As we can see we have added a new user to the database with all the current fields and our old users that have not yet provided this information (the email) have been assigned a value of null.&lt;/p&gt;

&lt;p&gt;Now they can be prompted to provide this information which will be used to populate their respective fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Database Migration
&lt;/h2&gt;

&lt;p&gt;As we have seen earlier, database migration is a very beneficial tool for software developers working with databases.&lt;/p&gt;

&lt;p&gt;Here are some benefits of database migration&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Preservation of data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating a dependable data backup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Increased efficiency within an application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduced downtime.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integration with modern technologies.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In conclusion, database migration is a critical process that enables businesses to enhance their data management capabilities by keeping track of the changes in their database.&lt;/p&gt;

&lt;p&gt;It can help organizations achieve better performance, security, scalability, and flexibility while minimizing costs and downtime. However, the migration process can be complex, and several factors need to be considered to ensure a successful outcome.&lt;/p&gt;

&lt;p&gt;It's essential to choose the right approach, plan the migration carefully, and perform thorough testing to minimize risks and avoid data loss.&lt;/p&gt;

&lt;p&gt;By understanding database migration and its benefits, businesses can make smart decisions that help them achieve their data management goals and maintain a competitive advantage.&lt;/p&gt;

</description>
      <category>database</category>
      <category>databasemigration</category>
    </item>
    <item>
      <title>What is CORS? : How to enable CORS in Nodejs App.</title>
      <dc:creator>Tonie</dc:creator>
      <pubDate>Mon, 13 Feb 2023 08:00:39 +0000</pubDate>
      <link>https://dev.to/tonieng/what-is-cors-how-to-enable-cors-in-nodejs-app-3mjj</link>
      <guid>https://dev.to/tonieng/what-is-cors-how-to-enable-cors-in-nodejs-app-3mjj</guid>
      <description>&lt;p&gt;Cross-Origin Resource Sharing (CORS) is a web browser mechanism that allows for resources that are restricted outside a domain (origin) to be requested from another domain.&lt;/p&gt;

&lt;p&gt;In this article, we'll get to understand why we use CORS and how to enable it in a Nodejs App.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we use CORS?
&lt;/h2&gt;

&lt;p&gt;To understand why we use CORS, we need to understand the underlying security risk it protects us from.&lt;/p&gt;

&lt;p&gt;Web scripting is the process of creating and embedding scripts that automates various functions and sequential tasks in a web page. These scripts can be used for various purposes including animations, tracking of information within our application, integration, ads etc.&lt;/p&gt;

&lt;p&gt;This variation poses a very potential security risk because third-party scripts can access our application and steal sensitive data which can then be used to perform some harmful operations within our application. Due to this risk, same-origin policy was introduced.&lt;/p&gt;

&lt;p&gt;Same-origin policy is a web mechanism that allows a web page to retrieve or access resources from applications that are within its origin. Two resources can be said to have the same origin if their URL has the same host, port, and protocol.&lt;/p&gt;

&lt;p&gt;For instance:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://www.hashnode.com&lt;/code&gt; and &lt;code&gt;https://www.hashnode.com/@TonieNG&lt;/code&gt; are of the same origin while &lt;code&gt;https://www.hashnode.com/@TonieNG&lt;/code&gt; and &lt;code&gt;https://tonie.hashnode.dev/&lt;/code&gt; are of different origins.&lt;/p&gt;

&lt;p&gt;CORS serves as a mechanism that when enabled can allow for resource sharing between applications that are of different origins and it is implemented on top of HTTP so that the server side can instruct the browser to allow interactions from certain URLs.&lt;/p&gt;

&lt;p&gt;It consists of a preflight request, sent by the browser before each request. A set of headers should then be added on every server response (preflight or not) to allow or disallow the request if the origin is forbidden.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to enable CORS in Nodejs App?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new folder on your local device and open it with your preferred IDE. In this tutorial, I used VS Code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open your terminal and type in the following code to initialize a nodejs project:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we need to install the dependencies for this project. Open your terminal and enter this command&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a file named &lt;code&gt;index.js&lt;/code&gt; and in the &lt;code&gt;package.json&lt;/code&gt; file add a start property within the script object. Your &lt;code&gt;package.json&lt;/code&gt; and folder structure should look like this&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, go into the &lt;code&gt;index.js&lt;/code&gt; file and type in the following to set up our application using express:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now to enable &lt;strong&gt;CORS&lt;/strong&gt; , we will need to make a few changes to our &lt;code&gt;index.js&lt;/code&gt; file. Update the contents of your file to look like this&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As we can see, it's quite easy to set up CORS in our Nodejs Application. For further clarifications or research, check the &lt;a href="https://www.npmjs.com/package/cors"&gt;cors documentation&lt;/a&gt;. I've also provided the &lt;a href="https://github.com/Tonie-NG/CORS"&gt;GitHub repository&lt;/a&gt; that contains the code written in this tutorial here (give it a star).&lt;/p&gt;

&lt;p&gt;If you have any question or suggestions, feel free to ask in the comment section. You can also shoot me a DM on &lt;a href="https://twitter.com/Tonie_NG"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy Coding&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Sending Emails from a Nodejs Application using Nodemailer</title>
      <dc:creator>Tonie</dc:creator>
      <pubDate>Fri, 27 Jan 2023 08:33:51 +0000</pubDate>
      <link>https://dev.to/tonieng/sending-emails-from-a-nodejs-application-using-nodemailer-1ejn</link>
      <guid>https://dev.to/tonieng/sending-emails-from-a-nodejs-application-using-nodemailer-1ejn</guid>
      <description>&lt;p&gt;As a Software Developer, you've probably worked on a project where you need to communicate some information in real-time from your Nodejs application.&lt;/p&gt;

&lt;p&gt;This information can be anything from password reset to notifications on subscription services, to changes in terms and services. There's a whole lot of information that can be communicated and there are several ways through which we can send this information.&lt;/p&gt;

&lt;p&gt;In this article, we will learn how to send emails from a Nodejs application using nodemailer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Nodemailer?
&lt;/h2&gt;

&lt;p&gt;There are different reasons why we should use Nodemailer to send emails, I've listed some of them below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We can send different types of data like plain text, HTML content, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It has OAuth2 authentication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It has Unicode support for any character, which means we can send emojis within our emails&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It uses different transport methods like the SES transport method in addition to the built-in SMTP support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;To follow along, you would need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A code editor of your choice (preferably VS Code) and a stable internet connection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An updated version of the Nodejs software is installed on your local device. You can visit the &lt;a href="https://nodejs.org/en/download/"&gt;Nodejs download&lt;/a&gt; site and follow the prompts to install it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimal experience working with nodejs applications using express.js&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Experience using API testing tools (preferably postman)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let's get to coding.....&lt;/p&gt;

&lt;h2&gt;
  
  
  Initializing our Nodejs project
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new folder, with any name of your choice and open it with your code editor. In this case, we used VS Code and we have named our folder "nodemailer-tutorial".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open up your terminal and type in the following command&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we need to install the dependencies that will be needed for this project. On your terminal, type in the following command and press enter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we're done with the installation, go into the package.json file and within the script object, add this line of code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the next step, we need to create files and folders for our application.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Configuring our App and Creating Routes
&lt;/h2&gt;

&lt;p&gt;Navigate to your index.js file and write the lines of code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require("express");
const cors = require("cors");
const dotenv = require("dotenv");
const app = express();
const email = require("./routes/email");

app.use(express.json());
app.use(
  cors({
    origin: "*",
  })
);
dotenv.config();

app.get("/", (req, res) =&amp;gt; {
  res.status(200).send("Welcome");
});

app.use("/email", email);

app.listen(process.env.PORT || 3000, () =&amp;gt; {
  console.log(`Server is up and running`);
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are importing the modules and packages we imported earlier and then configuring them. Also, we set up our app to listen on port 3000. To start up our application, open your terminal, type in npm start and hit enter. You should see a message that reads "Server is up and running". Go to postman and send a get request to this URL &lt;code&gt;http://127.0.0.1:3000/&lt;/code&gt;. You should be met with a "Welcome" message like the one below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8t0zwOTg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1674800896321/76d3614c-5cf8-459c-8ba4-ff68ec083b2b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8t0zwOTg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1674800896321/76d3614c-5cf8-459c-8ba4-ff68ec083b2b.png" alt="" width="880" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now go into the email.js file and then type in the following lines of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const router = require("express").Router();
const sendMail = require("../utilities/sendemail");

router.post("/", async (req, res) =&amp;gt; {
  try {
    // Here is where we write our logic and functionalities to send the email
  } catch (error) {
    res.status(500).send(error.message);
  }
});

module.exports = router;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we just set up the route that will be used for sending our emails. We also imported a module in the second line which is a function that defines how our emails are sent and structured.&lt;/p&gt;

&lt;p&gt;Before we write out this function, we need to enable some security features on our host account (the email address from which we would send out emails). Go to your account settings and set up an "Application specific" credential for your nodejs application and you'll be provided with a password. Open up the .env file and type the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HOST = smtp.gmail.com
SERVICE = gmail
EMAIL_PORT = 587
SECURE= true
USER = tutorial@gmail.com //Replace with your email address
PASS = password // Replace with your application-specific password

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt; *: We are using Gmail in this tutorial. The settings might be different if you use another email service.*&lt;/p&gt;

&lt;p&gt;Now go over to the sendemail.js file and type in the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nodemailer = require("nodemailer");

module.exports = async (email, subject, text) =&amp;gt; {
  try {
    // initialize and define the mode of transport
    const transporter = nodemailer.createTransport({
      host: process.env.HOST,
      service: process.env.SERVICE,
      port: Number(process.env.EMAIL_PORT),
      secure: Boolean(process.env.SECURE),
      auth: {
        user: process.env.USER,
        pass: process.env.PASS,
      },
    });

    // Defining the mail and sending it using the transport
    const sentEmail = await transporter.sendMail({
      from: process.env.USER,
      to: email,
      subject: subject,
      text: text,
    });
    const response = "Email sent successfully";
    console.log(response);
  } catch (error) {
    console.log(error.message);
    return response;
  }
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we created a function and within it, we used the nodemailer package to create a transport. Transport defines the method and medium that will be used to send the email. We also called the sendMail method that sends the email using the preselected transport object.&lt;/p&gt;

&lt;p&gt;You can access the &lt;a href="http://nodemailer.com/usage/"&gt;nodemailer&lt;/a&gt; documentation to learn more about these methods and parameters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Back to the email.js Route
&lt;/h3&gt;

&lt;p&gt;We can now use the sendemail function. To do that, update the code to look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const router = require("express").Router();
const sendMail = require("../utilities/sendemail");

router.post("/", async (req, res) =&amp;gt; {
  try {
    const email = await req.body.email;
    const message = await req.body.message;
    const subject = await req.body.subject;

    const sentEmail = await sendMail(email, subject, message);

    return res.status(200).send("You email is on the way");
  } catch (error) {
    res.status(500).send(error.message);
  }
});

module.exports = router;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's test this out on postman. Copy the JSON object below and provide the details you want to send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "email": "myaddress@gmail.com", //Input the address you want to mail
    "subject": "Testing my email server", //Change to any subject you want
    "message": "Confirm you can see this" //Use a personalized message of your choice
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Back to postman, go to "Body", click on "raw" and then select JSON. Paste the JSON object into the text area and send a post request to &lt;code&gt;http://127.0.0.1:3000/email&lt;/code&gt;. Your request should look like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5TGxmynG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1674806129822/34cb2ea7-1330-401f-bcef-6481eb8a8cfc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5TGxmynG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1674806129822/34cb2ea7-1330-401f-bcef-6481eb8a8cfc.png" alt="" width="880" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now check your recipient email inbox and you will see your message sitting right there waiting to be clicked.&lt;/p&gt;

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

&lt;p&gt;And that's a wrap. We've successfully built a Nodejs application that enables us to send emails using Nodemailer: a module that allows you to send emails from your server with ease.&lt;/p&gt;

&lt;p&gt;I've provided a link to the project &lt;a href="https://github.com/Tonie-NG/nodemailer-tutorial"&gt;on GitHub&lt;/a&gt;. Here you can find all the code snippets used for this project.&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions, I'll be buzzing to hear from you in the comment section.&lt;/p&gt;

&lt;p&gt;Happy coding 💫&lt;/p&gt;

</description>
      <category>email</category>
      <category>node</category>
      <category>nodemailer</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What is a REST API?</title>
      <dc:creator>Tonie</dc:creator>
      <pubDate>Tue, 18 Oct 2022 08:29:02 +0000</pubDate>
      <link>https://dev.to/tonieng/what-is-a-rest-api-4255</link>
      <guid>https://dev.to/tonieng/what-is-a-rest-api-4255</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;REST APIs provide a flexible and lightweight way to integrate applications and are emerging as the most popular way to connect components in microservices architectures.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An API (Application programming interface) is a a set of rules and protocols that defines how software products and applications communicate with each other.&lt;/p&gt;

&lt;p&gt;Let's visualize an API as a waiter in a restaurant. You the customer can be referred to as the client while the chefs in the kitchen can be called the Server.&lt;/p&gt;

&lt;p&gt;Now the Waiter is a way or protocol through which you place your order (communicate) to the chef (server) and also get a response if any (your food perhaps).&lt;/p&gt;

&lt;p&gt;If there are any errors, let's say the food isn't available. The chef will communicate to you through the waiter and so on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MxteFb04--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1666049097896/9Pi6-b3Ba.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MxteFb04--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1666049097896/9Pi6-b3Ba.jpeg" alt="images (9)_1.jpeg" width="740" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This simple analogy can be applied to how software applications communicate.&lt;/p&gt;

&lt;p&gt;Now that we have had an overview of how APIs work, &lt;strong&gt;What is a REST API and why do we use it?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a REST API?
&lt;/h2&gt;

&lt;p&gt;A REST API also known as RESTful API is an API that follows the design principles of REST (Representational State Transfer) architectural system.&lt;/p&gt;

&lt;p&gt;REST APIs are the most widely appreciated APIs and are preferred to other APIs like SOAP or XML-RPC because of the flexibility it offers to software developers.&lt;/p&gt;

&lt;p&gt;It is also language agnostic, meaning that they can be implemented in virtually any programming language and they support several data formats.&lt;/p&gt;

&lt;p&gt;The only condition in developing REST APIs is that they conform to the following REST design principles listed below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Uniform Interface&lt;/strong&gt; : This means that each request made from the client to the server should look alike no matter where that request is made from. The REST API should guarantee that the same chunk of data from the client belongs to only one URI (Unique Resource Identifier).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cacheability&lt;/strong&gt; : Resources being communicated via a REST API should be cacheable on both the client and server side of the application. Responses should also include information that tells the client if caching is available for that resource. This helps improve performance on the client side and scalability on the server side.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Client-Server decoupling&lt;/strong&gt; : The client and server side of the application must be independent of each other. The only information about the server that should be known by the client is the URI of a requested resource. The client should not be able to interact with the server in any way. Likewise, the server shouldn't be able to alter the client, it should only be able to process the requested data via HTTP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Layered system architecture&lt;/strong&gt; : The calls and responses in REST go through different categories also known as layers. This means that the client and server may not connect directly with each other. There may be several channels in the communication loop.&lt;br&gt;&lt;br&gt;
To this end, REST APIs need to be designed so that the client and server are not aware of the communication channel used(whether it's an end to end communication or through an intermediary between them).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Statelessness&lt;/strong&gt; : REST APIs are stateless. Rather than relying on the server remembering previous requests, REST applications require each request to contain all of the information necessary for the server to process it. Server applications arent allowed to store any data related to a client request.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How does a REST API Work?
&lt;/h2&gt;

&lt;p&gt;REST APIs communicate through HTTP(hyper text transfer protocol) to carry out database functions or operations like creating, reading, updating, and deleting information (also known as CRUD) within a resource.&lt;/p&gt;

&lt;p&gt;In HTTP, there are five common methods that are used for communication, they are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GET: The &lt;code&gt;get&lt;/code&gt; method is used to read or retrieve the representation of a resource in a database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST: The &lt;code&gt;post&lt;/code&gt; method is used to create new resources in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PATCH: The &lt;code&gt;patch&lt;/code&gt; method is used to modify the data or information within a resource identified by a URI. This request only needs to contain the changes to the resource not the complete resource.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PUT: The &lt;code&gt;put&lt;/code&gt; method is used to update and modify the data within a resource identified by a URI. This request needs to contain the complete resource ie. if you want to change the username of a user, you'll need to provide every other information relating to that user resource.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DELETE: As the name implies, the &lt;code&gt;delete&lt;/code&gt; method is used to delete a resource identified by a URI.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zvgWy_mi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1666049177384/gZh1VxtQ8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zvgWy_mi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1666049177384/gZh1VxtQ8.png" alt="images (4).png" width="704" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;The state of a resource at any particular instant is known as the resource representation and this information can be delivered to a client in several formats including JavaScript Object Notation (JSON), HTML, XLT, Python, PHP, or plain text.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;JSON is by far the most used between software developers because it is readable by both humans and machines and it is programming language-agnostic.&lt;/p&gt;

&lt;p&gt;Request headers and response headers, along with conventional HTTP status codes, are commonly used within REST APIs.&lt;/p&gt;

&lt;p&gt;Request headers and parameters contain important identifier information like metadata, authorizations, uniform resource identifiers (URIs), caching, cookies etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits Of REST APIs
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility and Scalability&lt;/strong&gt; : One of the most important benefit of REST APIs is the scalability and flexibility it offers software engineers. REST APIs can be scaled quickly due to the separation between the client and the server. Additionally, due to its flexible nature engineers can also easily integrate REST APIs without much added work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Independence&lt;/strong&gt; : In the architectural design of REST APIs, the client and server are independent of each other. This means that engineers can go on to work on different parts of the application separately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lightweight&lt;/strong&gt; : One of the main benefits of REST APIs is that they follow HTTP standard, which means that they're format-agonistic and you can use XML, JSON, HTML, etc. Making REST APIs fast and lightweight. This feature is particularly necessary for mobile app projects, internet of things devices, and more.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Disadvantage of REST APIs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Flexibility&lt;/strong&gt; : Yeah, you heard right FLEXIBILITY! Although it is a big advantage of REST API design, it also makes it easy to develop an API thats broken or/and performs poorly.&lt;/p&gt;

&lt;p&gt;REST APIs are the most popular and widely used APIs in the world of software development . They are efficient, high-performing, consume less bandwidth, and are cost-effective.&lt;/p&gt;

&lt;p&gt;That's a wrap, you can go ahead and start building your own APIs. While designing your APIs, you should make sure to take cognizance of your consumer's objectives and then build accordingly.&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions, I'll be buzzing to hear from you in the comment section.&lt;/p&gt;

&lt;p&gt;Happy coding 💫&lt;/p&gt;

</description>
      <category>api</category>
      <category>restapi</category>
      <category>backend</category>
    </item>
    <item>
      <title>State Management in React with Redux Toolkit (RTK)</title>
      <dc:creator>Tonie</dc:creator>
      <pubDate>Wed, 05 Oct 2022 09:32:18 +0000</pubDate>
      <link>https://dev.to/tonieng/state-management-in-react-with-redux-toolkit-rtk-1kmp</link>
      <guid>https://dev.to/tonieng/state-management-in-react-with-redux-toolkit-rtk-1kmp</guid>
      <description>&lt;p&gt;Have you ever tried to re-render a component or some form of data whenever there's a change in the UI of your application?&lt;/p&gt;

&lt;p&gt;You've probably tried to use Hooks to effect (pun intended :-) ) this change and where needed you've applied some prop values. Well you've just managed the state of your application.&lt;/p&gt;

&lt;p&gt;But while this might be effective for your small and simple project, it's actually a reductant approach and might prove ineffective when you start working on bigger and more complex applications.&lt;/p&gt;

&lt;p&gt;In this article, we'll be looking at the basics of state in React and how to manage it using Redux Toolkit (RTK).&lt;/p&gt;

&lt;p&gt;State and state management is one of the most complex concepts for developers and quite rightly so.&lt;/p&gt;

&lt;p&gt;The state is a built-in JavaScript object that contains the data and information about a component.&lt;/p&gt;

&lt;p&gt;This data is dynamic and can be modified overtime. When they do, the component re-renders to reflect the necessary changes.&lt;/p&gt;

&lt;p&gt;The change in state of a component can occur as a response to a user's action or a system generated event, either way these changes needs to be managed.&lt;/p&gt;

&lt;p&gt;The state of an application helps us to track the changing data in a component and managing the state of application simply means managing the reaction of an application's component to these state changes.&lt;/p&gt;

&lt;p&gt;There are 4 different kinds of states in React with different ways to mange them. However in this article, we'll be focusing on managing the Global state which is the state across multiple components.&lt;/p&gt;

&lt;p&gt;Although this article is beginner friendly, I suggest you know a little bit of JavaScript and React in order to fully grasp the ideas, code and logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Management using RTK
&lt;/h2&gt;

&lt;p&gt;Let's imagine for a second we have a dashboard application in react where we display the user's information across multiple components like the Navbar, main page and possibly the footer.&lt;/p&gt;

&lt;p&gt;This is a dynamic information that can change overtime ie it depends on the user's action.&lt;/p&gt;

&lt;p&gt;Let's say the user wants to update the username and email, we have to somehow track this change and dynamically render it across the multiple components.&lt;/p&gt;

&lt;p&gt;To do this, we could create the variables at the top level of our react application, and pass it as a prop down to its child components and then to its grandchild till we get to the components where it is needed. This is known as prop-drilling.&lt;/p&gt;

&lt;p&gt;While this might work, it is redundant and makes it hard to maintain our application in the future.&lt;/p&gt;

&lt;p&gt;Also we are often left with unnecessary prop values in components where they are not needed across multiple points in our application. To tackle this, we use state management tools like the Redux Toolkit.&lt;/p&gt;

&lt;p&gt;The Redux Toolkit provides a very simple and straightforward solution: create a store independent from any component and then make it accessible to every component at all levels of our application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--73UKNbCC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1664912281426/Rl-_92PCE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--73UKNbCC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1664912281426/Rl-_92PCE.png" alt="images.png" width="671" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are the steps in using the Redux Toolkit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install and Configure the Redux Toolkit and Redux&lt;/li&gt;
&lt;li&gt;Create a Redux Folder (preferably)&lt;/li&gt;
&lt;li&gt;Create a Slice &lt;/li&gt;
&lt;li&gt;Create a store&lt;/li&gt;
&lt;li&gt;Provide Store to React at the top most component&lt;/li&gt;
&lt;li&gt;Proceed to use the store values anywhere across the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll be explaining each of these steps below, let's go! But first, go ahead and create your react application as I won't be going over that.&lt;/p&gt;

&lt;p&gt;We'll be using the user information example we discussed earlier and also try to update the information across multiple components in our application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install and Configure Redux and Redux Toolkit.
&lt;/h3&gt;

&lt;p&gt;In your terminal, type the following lines of code&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 @reduxjs/toolkit react-redux

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install and configure the Redux Toolkit&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a Redux folder
&lt;/h3&gt;

&lt;p&gt;Create a Folder for the Redux Logic preferably inside the src folder of your application. Let's call this folder &lt;code&gt;redux&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a Redux Slice
&lt;/h3&gt;

&lt;p&gt;Create a new file and name it &lt;code&gt;userSlice.js&lt;/code&gt;. A slice is simply just a collection of our redux reducer logic and actions for a single feature in your react application defined together in a single file. Type in the following code snippet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {createSlice} from "@reduxjs/toolkit"
export const useeSlice = createSlice ({
  name: "user",
  initialState: {
   username: "Tonie"
   email: "tonie@email.com"
  },
  reducers: {
   update: (state, action) =&amp;gt; {
    state.username = action.payload.username;
    state.email= action.payload.email
   },
  },
})
export const {update} = userSlice.actions;
export default userSlice.reducer

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What is happening here?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The name represents the name of our slice, in this case, we've chosen "user"&lt;/li&gt;
&lt;li&gt;InitialState: This sets the initial or default state of our react element.&lt;/li&gt;
&lt;li&gt;Reducers: This contains all the logic and actions that is used to update our state.&lt;/li&gt;
&lt;li&gt;The action.payload tracks the changes to our state and passes it to the necessary state variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Create a Store
&lt;/h3&gt;

&lt;p&gt;In React, a store is a state container which holds the application's state. Redux can have only a single store in your application and you have to specify or add our reducers from our slice to it. Type in the following in your redux store file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {configureStore} from "@reduxjs/toolkit"
import userReducer from './userSlice'
//this is a default export, that's why we could name it this way. It is our reducer in our slice

export default configureStore ({
 reducer: {
  user: userReducer,
 }
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Provide the Redux Store to React
&lt;/h3&gt;

&lt;p&gt;Once the store has been created, we can make it available to our React components by putting a React-Redux around our application in src/index.js. Import the Redux store we just created, put a around your , and pass the store as a prop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import { store } from './app/store'
import { Provider } from 'react-redux'

ReactDOM.render(
  &amp;lt;Provider store={store}&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/Provider&amp;gt;,
  document.getElementById('root')
)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Proceed to use the store values anywhere across the application.
&lt;/h3&gt;

&lt;p&gt;Now we can use the React-Redux hooks to let React components interact with the Redux store. We can read data from the store with &lt;code&gt;useSelector&lt;/code&gt;, and dispatch actions using &lt;code&gt;useDispatch&lt;/code&gt; hooks respectively.&lt;/p&gt;

&lt;p&gt;To access the data from the store using the useSelector hook in any component, just type in the following code snippet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react"
import { useSelector } from "react-redux"

export function Navbar() {
 const name = useSelector( (state) =&amp;gt; state.user.username)

 const email = useSelector( (state) =&amp;gt; state.user.email)
//Then we can proceed to use these variables to represent the name and email in out
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will assign the variables of name and email to the values contained in the store.&lt;/p&gt;

&lt;p&gt;To change or update the values of our store variables, we make use of the useDispatch hook.&lt;/p&gt;

&lt;p&gt;Let's say we have a form and a button that handles this update on the Update component of our application. And we want to update our user information we do it 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;import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { update } from "../redux/userSlice";

export default function Update () {
 const [name, setName] = useState(" ");
 const [email, setEmail] = useState(" ");
 const user = useSelector ( (state) =&amp;gt; (state.user) )
 const dispatch = useDispatch();

 //Here we de-structure the user object and assign respective values. 
 user {
  username: name,
  email: email
 }

 const handleUpdate = (e) =&amp;gt; {
  e.preventDefault();
  dispatch(update(user))
 };

&amp;lt;&amp;gt;
 &amp;lt;form&amp;gt;
  &amp;lt;input 
   placeholder = "username"
   onChange = {(e) =&amp;gt; setName(e.target.value)} 
   /&amp;gt;
  &amp;lt;input 
   placeholder = "email"
   onChange = {(e) =&amp;gt; setEmail(e.target.value)} 
  /&amp;gt;
  &amp;lt;button onClick = {handleUpdate}&amp;gt;
   Update 
  &amp;lt;button/&amp;gt;
 &amp;lt;form&amp;gt;
&amp;lt;/&amp;gt;
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the name suggests the dispatch simply sends the action of our slice's reducer to the store. Hence performing the necessary updates and changes.&lt;/p&gt;

&lt;p&gt;And that's a wrap, as we have seen, Redux toolkit makes it easier for us to manage state in react.&lt;/p&gt;

&lt;p&gt;Although it might seem complex now, with some practice you should get familiar with it and use it effectively in your application.&lt;/p&gt;

&lt;p&gt;Let me know in the comment section if you have questions or suggestions.&lt;/p&gt;

&lt;p&gt;If you found this insightful, do well to share with your friends across your social media platforms.&lt;/p&gt;

&lt;p&gt;Happy coding 💫&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>rtk</category>
      <category>state</category>
    </item>
    <item>
      <title>How to make your First Open-Source Contribution</title>
      <dc:creator>Tonie</dc:creator>
      <pubDate>Fri, 16 Sep 2022 12:55:45 +0000</pubDate>
      <link>https://dev.to/tonieng/how-to-make-your-first-open-source-contribution-1d1</link>
      <guid>https://dev.to/tonieng/how-to-make-your-first-open-source-contribution-1d1</guid>
      <description>&lt;p&gt;Contributing to open source is an effective way to learn, teach and gain or build real world experience in just about any skill you can think of.&lt;/p&gt;

&lt;p&gt;Open Source refers to any software whose 'source code' is open and accessible to the public. It is a software that anyone can inspect modify or enhance.&lt;/p&gt;

&lt;p&gt;The source code is any code created in a programming language that defines the structure and functionality of a software application.&lt;/p&gt;

&lt;p&gt;And here's the catch, you don't have to know how to code to contribute to open source, there's a ton of opportunities in the space.&lt;/p&gt;

&lt;p&gt;This includes writing documentations, teaching people on how to use the product, designing etc. The opportunities are vast.&lt;/p&gt;

&lt;p&gt;And with this opportunities comes numerous benefits. I've listed some of them below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It helps you improve the software applications you use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Actively contributing to open source helps develop your technical skills.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By contributing to open source, you can also enhance your soft skills like communication and collaboration with people.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Contributing to open source gives you an experience that is akin to the real world experience of a software developer as the skills and process you will be using will be particularly important in the professional world.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  How to find Open Source Projects:
&lt;/h3&gt;

&lt;p&gt;Here's a list of online resources that can help you find open source projects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/explore/"&gt;GitHub Explore&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://opensourcefriday.com/"&gt;Open Source Friday&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://24pullrequests.com/"&gt;24 Pull request&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.firsttimersonly.com/"&gt;First timers only&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://firstcontributions.github.io/"&gt;First Contribution&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are only a few, you can do a manual search on Google and you'll be provided with several options.&lt;/p&gt;

&lt;p&gt;However there are somethings you should look out for in a project before proceeding to make your contribution. The project should meet the following criteria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The project must have a License.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The project should have a clearly defined and documented ReadMe file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The project is ACTIVELY accepting contributions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The project is welcoming and engaging.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Contribute to Open Source?
&lt;/h3&gt;

&lt;p&gt;Now that you've found a project, how do you make your contribution? To contribute to open source, you will have to know how to use Git and GitHub as they are the most popular and effective tools to use.&lt;/p&gt;

&lt;p&gt;Here's how to make your first open source contribution using Git and GitHub:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Find a project&lt;/strong&gt; : The first step is to of course find a project to contribute to, there's a lot of them out there and many ways of finding them as we've discussed earlier.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fork the repository&lt;/strong&gt; : Once you've found a project on github, click on the fork button. This will sort of copy or reproduce the project under a new repository in your GitHub user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clone the repository&lt;/strong&gt; : To do this, copy the link of your newly formed repository, it'll look like this; &lt;code&gt;https://github.com/&amp;lt;YourUsername&amp;gt;/git-demo.git&lt;/code&gt; Now open your terminal on your device and run the following command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create a new remote for the upstream repository&lt;/strong&gt; : This will help keep your code in sync with the original project. To do this, run the following command&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create a new branch&lt;/strong&gt; : Now we need to create and move into a new branch, run the following command&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Make a Change to the code&lt;/strong&gt; : Now it's time to add, remove and modify the code. After you are done, you can proceed to add these changes to the staging area by running the following command:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Commit your code changes&lt;/strong&gt; : After adding your changes to the staging area, it's time to commit them. Run the following command:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Push to your repository&lt;/strong&gt; : Now it's time to move these changes to your repository, run the following command:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create a pull request&lt;/strong&gt; : Once you push to your repository, you can go to that repository on GitHub and click on the "Compare and Pull request" button.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will notify the project owners of your changes and contributions. After inspecting them, they can merge your pull request.&lt;/p&gt;

&lt;h3&gt;
  
  
  And Voila, you've made your first open-source contribution
&lt;/h3&gt;

&lt;p&gt;That's a wrap, if you found this insightful, do well to share it with your friends and colleagues.&lt;/p&gt;

&lt;p&gt;If you're contributing to a project, let me know in the comment section. I'll be buzzing to hear from you.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>git</category>
      <category>github</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
