<?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: Tijani Ayomide</title>
    <description>The latest articles on DEV Community by Tijani Ayomide (@tijan_io).</description>
    <link>https://dev.to/tijan_io</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%2F536293%2F14607891-0444-43c7-9033-72607c9e9293.jpg</url>
      <title>DEV Community: Tijani Ayomide</title>
      <link>https://dev.to/tijan_io</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tijan_io"/>
    <language>en</language>
    <item>
      <title>From Postman to Postman Extension</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Tue, 15 Aug 2023 15:40:10 +0000</pubDate>
      <link>https://dev.to/tijan_io/from-postman-to-postman-extension-2964</link>
      <guid>https://dev.to/tijan_io/from-postman-to-postman-extension-2964</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Once upon a time, during my internship at a startup, I began my software exploration journey. As a newcomer, my initial tasks revolved around simple manual testing and pushing the limits of the application to uncover its vulnerabilities. When I discovered these errors I document them and uncover them during the standup meetings.&lt;/p&gt;

&lt;p&gt;To cut a long story short, my role evolved and I was entrusted with more responsibilities. I was given the task to handle functionality for the feedback service. After familiarizing myself with the framework, one might think it would be an easy task ( looking back it was an easy task) but at the time I was met with a reality check.&lt;/p&gt;

&lt;p&gt;I was queried by the senior developer on my team and it dawned on me that software development was not all about writing code. I also had to test, validate and ensure my implementation meets the business logic. This is where my Postman origin began as this tool became my trusted companion. And so my journey took a turn.&lt;/p&gt;

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

&lt;p&gt;Aside from being my trusted companion, &lt;a href="https://www.postman.com/product/what-is-postman/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; is an API development and testing tool that simplifies designing, testing, and documenting APIs. while offering a clean and easy-to-use interface to collaborate, create, manage, and inspect requests and responses respectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Postman extension?
&lt;/h2&gt;

&lt;p&gt;If you’re a fan of &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;vscode&lt;/a&gt; (Visual Studio Code), you should know how important extensions are in amplifying your development process. Many extensions can be found at the &lt;a href="https://marketplace.visualstudio.com/vscode" rel="noopener noreferrer"&gt;Microsoft marketplace&lt;/a&gt; ranging from &lt;em&gt;auto-formatter&lt;/em&gt;, &lt;em&gt;Dark Dracula themes&lt;/em&gt; to chilled lo-fi cat extensions just chilling at your IDE’s corner. It’s a world where extension possibilities can seem endless.&lt;/p&gt;

&lt;p&gt;But let’s focus on something more exciting — &lt;a href="https://marketplace.visualstudio.com/items?itemName=Postman.postman-for-vscode" rel="noopener noreferrer"&gt;Postman's new extension&lt;/a&gt; that allows you to test your API right from your code editor, without the need to juggle screens or switch windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features and Capabilities
&lt;/h3&gt;

&lt;p&gt;“Basically” everything you can perform on Postman Web and Desktop platform can be done with this extension. If you’re one of those developers who prefer not leaving their development environment think of this extension as a tailored and condensed version.&lt;/p&gt;

&lt;p&gt;Let’s look into some of its features:&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending of HTTP and Multiprotocol Requests
&lt;/h3&gt;

&lt;p&gt;Easily send HTTP, WebSocket, gRPC, and other multiprotocol requests without leaving your work environment. You can fire them off from within your IDE, so there's no need to interrupt your workflow. Everything you need is right at your fingertips.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpuohv503898gmfzqwhmw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpuohv503898gmfzqwhmw.png" alt="Postman Request Types" width="800" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Collection and Workspace Creation
&lt;/h3&gt;

&lt;p&gt;Organize requests easily by grouping them into various collections and workspaces to maintain a tidy and structured workflow environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh0tguc7e67d83b0gla5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh0tguc7e67d83b0gla5.png" alt="workspace creation" width="379" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Managing Environments and more
&lt;/h3&gt;

&lt;p&gt;The extension automatically synchronizes collections, requests, and environments, saving you the hassle of creating them from scratch or having the need to import them. Just ensure that the credentials you use to sign in match the workspace you want to access.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhb3d0apsh20q67sl605d.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhb3d0apsh20q67sl605d.gif" alt="Testing Postman Extension" width="600" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I began this paragraph with &lt;em&gt;basically&lt;/em&gt; quoted, this is because updates are still being made to enhance the functionality of the application, similar to what is available on the Web/Desktop version. Keep an eye out for more updates and newly added features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Postman Extension
&lt;/h2&gt;

&lt;p&gt;Installation of this extension can be done super easily in three simple steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open your vscode extension marketplace by navigating to it directly or using the keyboard shortcut: &lt;strong&gt;ctrl+shift+x&lt;/strong&gt; (Windows/Linux) or &lt;strong&gt;cmd+shift+x&lt;/strong&gt; (Mac). In the extensions tab, search for "&lt;strong&gt;Postman&lt;/strong&gt;".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpx4y8zyo6zinbn128f70.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpx4y8zyo6zinbn128f70.png" alt="postman in marketplace" width="800" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wait for the installation process to be completed successfully, depending on your internet speed the duration may vary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cd10ao469hewd8wqyuq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cd10ao469hewd8wqyuq.png" alt="Install postman extension" width="800" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete the process by signing into your Postman account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7yef9f14ue6eiuaapu8c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7yef9f14ue6eiuaapu8c.png" alt="Sign into postman" width="401" height="830"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;While the surface is merely scratched, the Postman extension offers a glimpse into a future of enhanced productivity and a simplified testing environment. Keep an eye out for new features and improvements that the team at Postman diligently unveils.&lt;/p&gt;

&lt;p&gt;Is this an extension you would use? Leave your thought in the comment section below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Connect
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on &lt;a href="https://www.linkedin.com/in/tijanayo/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on the &lt;a href="https://twitter.com/Tijan_io" rel="noopener noreferrer"&gt;X app&lt;/a&gt; (Formerly &lt;em&gt;Twitter&lt;/em&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And we can also connect in the comment section below ⤵️&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>api</category>
      <category>testing</category>
    </item>
    <item>
      <title>Understanding dependencies and dev-dependencies: Beginner’s Guide</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Mon, 10 Jul 2023 14:10:30 +0000</pubDate>
      <link>https://dev.to/tijan_io/understanding-dependencies-and-dev-dependencies-beginners-guide-248h</link>
      <guid>https://dev.to/tijan_io/understanding-dependencies-and-dev-dependencies-beginners-guide-248h</guid>
      <description>&lt;p&gt;When I first delved into the world of JavaScript, I frequently encountered a file called &lt;code&gt;package.json&lt;/code&gt;. Initially, I understood it to be a file where one simply names their current project. However, as I continued my journey, I discovered that this file holds much more significance than meets the eye.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;package.json&lt;/code&gt; file serves as more than just a repository for descriptions, versions, and scripts for your project. It also functions as a home for the packages utilized within your project, giving rise to the term "&lt;strong&gt;dependencies&lt;/strong&gt;." This is because your project relies on these packages to function effectively.&lt;/p&gt;

&lt;p&gt;Before we delve into learning more about dependencies, it is important to have a brief understanding of the term "&lt;strong&gt;Packages&lt;/strong&gt;" for quick reference. Packages are pre-written libraries or code modules that can be used to enhance the functionality of your project. These packages serve as a ready-made solution to common programming challenges without the need to reinvent the wheel.&lt;/p&gt;

&lt;p&gt;Some basic examples of popular packages in the Javascript community include &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Express&lt;/strong&gt;&lt;/a&gt; (a framework for building server applications) and &lt;a href="https://github.com/expressjs/multer" rel="noopener noreferrer"&gt;&lt;strong&gt;Multer&lt;/strong&gt;&lt;/a&gt; (a middleware for handling file uploads). These packages, when integrated into your project, can significantly streamline your development process.&lt;/p&gt;

&lt;p&gt;However, let's shift our focus away from packages themselves, as today's topic revolves around understanding dependencies and developers who depend on them. (pun intended!).&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a dependency❓
&lt;/h2&gt;

&lt;p&gt;As mentioned above a dependency refers to an external module or library that your project relies on to function correctly. These dependencies are typically third-party packages maintained by other developers or organizations. Let's take the example of installing the &lt;code&gt;Express&lt;/code&gt; package. To install Express, you can execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;express
// or
yarn add express
// Depending on the package manager of your choosing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will fetch the Express package from the npm registry and add it to your project's dependencies. Additionally, it will automatically update your &lt;code&gt;package.json&lt;/code&gt; file to include the specific version of Express that was installed.&lt;/p&gt;

&lt;p&gt;For example, your package.json file may now contain an entry like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.17.1"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, Express is listed as a dependency, and the version specifier "^4.17.1" indicates that your project requires Express version 4.17.1 or any compatible version within the specified major version.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a dev-dependency❓
&lt;/h2&gt;

&lt;p&gt;A dev-dependency, short for development dependency, is another type of dependency that is specific to the development environment. Dev dependencies include tools, libraries, or utilities that are helpful during the development process but are not necessary for the production version of your application.&lt;/p&gt;

&lt;p&gt;Let’s take the example of installing &lt;code&gt;nodemon&lt;/code&gt; package which is a popular tool that automatically restarts your Node.js server whenever a file is modified. To install &lt;code&gt;nodemon&lt;/code&gt; as a dev-dependency, you can run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; nodemon
// or
yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; nodemon
// Depending on your package manager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--save-dev&lt;/code&gt; and &lt;code&gt;-D&lt;/code&gt; flag tells npm and yarn respectively to add &lt;code&gt;nodemon&lt;/code&gt; as a dev-dependency in your project. Similarly, the package.json file will be updated to reflect this addition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nodemon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.0.12"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Updating Dependencies 🔃
&lt;/h2&gt;

&lt;p&gt;Keeping your packages up to date is of utmost importance, as these updates often include fixes, security patches, and new features that can facilitate performance improvements for your project. Let's explore two approaches to updating packages in your project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updating All Dependency
&lt;/h3&gt;

&lt;p&gt;To update all packages in your project, you can use the package manager of your choice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm update
// or
yarn upgrade

// Note: Make sure you have a good understanding of your chosen package manager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, it is important to note that updating all packages at once may not always be advisable. There may be instances where certain libraries and modules have dependencies on specific versions of packages, and updating all dependencies in your project can lead to compatibility issues and potential breakages in your codebase. Therefore, exercise caution and perform thorough testing after the update.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updating a Specific dependency
&lt;/h3&gt;

&lt;p&gt;In some cases, you may need to update a specific package to get the new feature or to resolve an issue in your codebase. To update specific packages you can use the package manager of your choosing followed by the package name and the desired version specifier. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// Node Package Manager &lt;span class="o"&gt;(&lt;/span&gt;NPM&lt;span class="o"&gt;)&lt;/span&gt;
npm update &amp;lt;package-name&amp;gt;

// Yarn Package Manager
yarn up &lt;span class="o"&gt;[&lt;/span&gt;package]
or
yarn up &lt;span class="o"&gt;[&lt;/span&gt;package]@[version]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By specifying the package name, you ensure that only the selected package is updated, reducing the chances of unintended side effects. When updating a specific package, it is also important to consider any potential impacts on your project. Some updates may introduce breaking changes or require adjustments in your codebase. Therefore, it is recommended to review the package's release notes or changelog to understand the changes introduced in the new version. it is a good practice to test your application thoroughly after updating to ensure its continued functionality.&lt;/p&gt;

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

&lt;p&gt;Understanding and managing your dependencies is crucial for efficient project development and deployment. It allows you to gain a clear understanding of which packages are required for your project's functionality and which ones are only necessary during development. It is quite common for developers to mistakenly install packages meant to be dev-dependencies as regular dependencies. However, this can lead to bloated production builds and slower deployment times. By understanding the difference between the two, you can optimize your workflow and avoid unnecessary package inclusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Connect 🔗
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on &lt;a href="https://www.linkedin.com/in/tijanayo/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on the &lt;a href="https://twitter.com/Tijan_io" rel="noopener noreferrer"&gt;Bird's App&lt;/a&gt; 🐦 or the &lt;a href="https://www.threads.net/@tjansama" rel="noopener noreferrer"&gt;Thread's App&lt;/a&gt; 🧵 ( Kindly follow I'll follow back immediately )&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And we can also connect in the comment section below ⤵️&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
      <category>node</category>
    </item>
    <item>
      <title>Which Case is Best for Your Coding Style</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Wed, 07 Jun 2023 05:29:41 +0000</pubDate>
      <link>https://dev.to/tijan_io/which-case-is-best-for-your-coding-style-135o</link>
      <guid>https://dev.to/tijan_io/which-case-is-best-for-your-coding-style-135o</guid>
      <description>&lt;p&gt;Naming variables, functions, and other elements in programming can be a daunting task. It becomes even more difficult when you have to decide which naming convention to follow. One common debate revolves around the choice between snake case and camel case.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxel86ddkv2qnhm6ved04.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxel86ddkv2qnhm6ved04.jpg" alt="I cant decide" width="296" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, this article aims to introduce you to a wider range of casing styles used in programming. While snake case and camel case are well-known, there are other casing conventions worth exploring.&lt;/p&gt;

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

&lt;p&gt;Before we delve into the topic at hand, let’s understand the importance of casing in programming. Casing refers to the practice of using standard conventions for naming variables, functions, classes, and other elements in code. It plays a significant role in enhancing code readability, maintaining consistency, and improving collaboration among developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Snake Case?
&lt;/h2&gt;

&lt;p&gt;snake case involves separating words with underscores. When using snake case each character needs to be lowercase.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;welcome_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello Human&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;You’ll encounter this case-naming convention in programming languages like Python and Ruby. You will also come across it when working with databases, as it is used for creating tables and column names.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;model&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;firstName&lt;/span&gt;       &lt;span class="nb"&gt;String&lt;/span&gt;            &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;lastName&lt;/span&gt;        &lt;span class="nb"&gt;String&lt;/span&gt;            &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;phoneNumber&lt;/span&gt;     &lt;span class="nb"&gt;String&lt;/span&gt;            &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;phone_number&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;There is also the capitalized version of snake case, where all the characters are in upper case, known as &lt;strong&gt;screaming&lt;/strong&gt; &lt;strong&gt;snake case&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;FIRST_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;LAST_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Doe&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;h2&gt;
  
  
  What is Camel Case?
&lt;/h2&gt;

&lt;p&gt;Camel case involves capitalizing the first letter of each word except for the first word, which starts with a lowercase letter. Basically, a capital letter appears at the start of the second word and at each subsequent word that follows it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jane&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This naming convention is widely used in programming languages like Java and JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Pascal Case?
&lt;/h2&gt;

&lt;p&gt;This is also known as the "Upper Camel Case," as it exhibits similarities with the camel case writing style, but in Pascal's naming convention, it capitalizes the first letter of each word, including the first word.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;FirstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="nx"&gt;LastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Doe&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;You’ll see this naming convention in most programming languages, but it is more pronounced in languages like C# (C hashtag) and C++.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Kebab Case?
&lt;/h2&gt;

&lt;p&gt;This is also known as the spinal case, it separates words using hyphens. it is often used in file and URL naming… Although it may not be used as the go-to naming convention, it is worth mentioning for its relevance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;helper&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&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;When choosing a casing style, it is important to consider the programming language or framework you are using. Adhering to these conventions promotes code consistency and enhances collaboration within a development team.&lt;/p&gt;

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

&lt;p&gt;Selecting the appropriate casing style for your coding style is crucial for readability and maintaining a consistent naming convention. Understanding the difference between each case styling will allow you to write clean and readable code that is easier to understand and maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Connect
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on &lt;a href="https://www.linkedin.com/in/tijanayo/" rel="noopener noreferrer"&gt;&lt;strong&gt;Linkedin&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on the &lt;a href="https://twitter.com/Tijan_io" rel="noopener noreferrer"&gt;&lt;strong&gt;Bird app&lt;/strong&gt;&lt;/a&gt; ( Kindly follow I'll follow back immediately )&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can also connect in the comment section below&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>coding</category>
      <category>writing</category>
    </item>
    <item>
      <title>API Limiting: Best Practices and Implementation</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Mon, 01 May 2023 13:17:04 +0000</pubDate>
      <link>https://dev.to/tijan_io/api-limiting-best-practices-and-implementation-49c8</link>
      <guid>https://dev.to/tijan_io/api-limiting-best-practices-and-implementation-49c8</guid>
      <description>&lt;p&gt;As developers, it is crucial to ensure the optimal performance of our APIs. Slow database performance and lags can have severe consequences on our applications. However, performance is not the only reason for implementing API limiting. It can also act as a crucial safety measure against Denial of Service (DDoS) attacks that can overload a server with unlimited API requests.&lt;/p&gt;

&lt;p&gt;However, the unrestrained use of APIs can lead to grave risks, such as overwhelming servers, compromising sensitive data, and even causing service downtime. To counter such issues, API limiting has emerged as a critical measure that controls and manages API usage, promoting the reliability and security of APIs.&lt;/p&gt;

&lt;p&gt;In this article, we will explore the meaning, importance, types, use-case and application of API limiting in a simple API. By the end of this article, you will understand how to rate limit your APIs, thereby enhancing scalability while mitigating risks.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is API Limiting?
&lt;/h2&gt;

&lt;p&gt;API limiting is the process of controlling the rate and frequency at which users can access and use APIs. It is achieved by setting specific thresholds, such as the number of requests per minute or hour, and limiting users' access to the API when they exceed those thresholds. By enforcing API limits, organizations can prevent API abuse and overload, improve service reliability, and enhance security.&lt;/p&gt;

&lt;p&gt;Think of it this way, offering full access to your API is the same as granting unrestricted access to your platform. This can lead to negative consequences, such as users overusing the API and consuming excessive resources, which can diminish its value. While it is great people want to use your API and find it useful, an open-door policy can negatively impact your business's success and hinder scalability. It is essential to recognize the need for rate limiting as a critical component in managing API usage, promoting value, and achieving business objectives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of API Limiting
&lt;/h2&gt;

&lt;p&gt;Given your newfound understanding of API limit and its significance, let's look at the various types kinds of API limiting techniques, they include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;IP-based limiting&lt;/strong&gt;: This method limits API access based on the user's IP address. It restricts API access from a specific IP address, regardless of how many requests come from that address. The pros of IP-based limiting include its simplicity, and it is ease of implementation. However, it has a significant drawback in that it can be bypassed by using proxies or VPNs, which can make it ineffective in preventing malicious attacks. Services such as &lt;strong&gt;CloudFlare&lt;/strong&gt; make use of IP-based limiting to mitigate DDoS attacks. It blocks traffic coming from blacklisted IP addresses to ensure the network's availability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Token-based limiting&lt;/strong&gt;: This method involves assigning a unique token to each user, which is used to track and limit API usage. Tokens are issued for a specific period, and users need to renew them after expiry. The advantage of token-based limiting is that it is more secure than IP-based limiting, and users can only access the API if they have a valid token. However, token management can be challenging, especially for large-scale applications. Services such as &lt;a href="https://www.twilio.com/en-us" rel="noopener noreferrer"&gt;&lt;strong&gt;Twilio&lt;/strong&gt;&lt;/a&gt;, make use of token-based limiting to secure its API. It issues unique API keys to its users, which are used to authenticate API requests and limit usage based on the user's plan.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quota-based limiting&lt;/strong&gt;: This method limits API usage based on the number of requests allowed within a specific time frame, such as per hour or day. It is a flexible method, and it enables developers to customize their API usage limits based on individual user requirements. The downside is that it can be challenging to determine the correct quota limit for each user, and it may require trial and error to find the correct balance. Services such as &lt;a href="https://developers.google.com/maps/get-started" rel="noopener noreferrer"&gt;&lt;strong&gt;Google Maps API&lt;/strong&gt;&lt;/a&gt;, make use of quota-based limiting to limit API usage. It allows developers to set a daily limit on API usage, which can be customized based on the specific application's requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hybrid-based limiting&lt;/strong&gt;: This method combines two or more limiting methods, such as IP, token-based and quota-based limiting. The benefit of hybrid-based limiting is that it leverages the strengths of each limiting method, creating a more comprehensive and robust API limiting strategy. Service such as &lt;strong&gt;Stripe&lt;/strong&gt; makes use of a combination of token and quota-based limiting to secure their API. It assigns unique API keys to its users and limits API usage based on the user's plan and API request type.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  When to use API-Limiting
&lt;/h2&gt;

&lt;p&gt;Implementing rate limiting is one of the most common ways to ensure efficient API performance. When an API is used excessively, it can slow down the database and cause lags, ultimately resulting in a poor user experience. By implementing rate limiting, developers can ensure that API requests are processed efficiently and prevent the overloading of the server.&lt;/p&gt;

&lt;p&gt;Another important use case for API limiting is to protect the API from malicious attacks, such as DDoS attacks, which can flood the server with unlimited requests. By implementing rate limiting, developers can limit the number of requests that a user can make within a specific timeframe, thereby preventing the server from being overwhelmed.&lt;/p&gt;

&lt;p&gt;API limiting can also be used to protect sensitive data and prevent unauthorized access. By controlling and monitoring API usage, developers can ensure that only authorized users have access to sensitive data.&lt;/p&gt;

&lt;p&gt;Furthermore, API limiting can be used to manage and control costs associated with API usage. By limiting the number of requests a user can make, developers can prevent excessive usage, which can result in increased costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practice for API Limiting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Determine appropriate limits
&lt;/h3&gt;

&lt;p&gt;One of the most crucial aspects of implementing API limiting is determining appropriate limits for your API usage. The goal is to find a balance between providing enough access for users while still maintaining control and preventing abuse.&lt;/p&gt;

&lt;p&gt;To determine appropriate limits, you should consider the following factors:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Business Needs:&lt;/strong&gt; Your API usage limits should align with your business needs and goals. It is essential to evaluate how much traffic your API can handle, what level of service you want to provide, and what kind of users you are targeting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User Behavior:&lt;/strong&gt; Your API usage limits should be based on user behavior, such as the number of requests, the rate of requests, and the size of the response. You should also consider how frequently users are accessing the API and the impact on the server resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability:&lt;/strong&gt; As your API usage grows, you should ensure that the limits are scalable to accommodate the increasing traffic.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Set clear and informative error messages
&lt;/h3&gt;

&lt;p&gt;When API requests exceed the set limits, it is important to provide clear and informative error messages to users. These messages should inform users of the limit breach and guide how to resolve the issue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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;statusCode&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&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;Too many request, kindly wait 10 minute before sending another request.&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;h3&gt;
  
  
  Allow for flexibility and exceptions
&lt;/h3&gt;

&lt;p&gt;While it is essential to have appropriate limits in place, you should also allow for flexibility and exceptions. For example, you may need to provide higher limits for premium users or allow temporary increases in usage during peak times. You should also have a process in place for handling exceptions and appeals from users who have exceeded the limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing rate limiting in a node js application
&lt;/h2&gt;

&lt;p&gt;Have you ever been to a buffet and seen that one person who just keeps piling up their plate with food?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fyoh83skj7704ajw6kd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fyoh83skj7704ajw6kd.gif" alt="buffet-giphy" width="480" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While it might seem tempting to follow in their footsteps, it's not fair to the other people waiting in line. Similarly, in API development, it's important to ensure that one client doesn't hog all the resources and leave others waiting.&lt;/p&gt;

&lt;p&gt;That's where rate limiting comes in. By setting a limit on the number of requests a client can make within a certain time frame, we can ensure that everyone gets a fair share of the resources. In our simple CRUD project, we have implemented rate limiting using the &lt;code&gt;express-rate-limit&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;So, just like at a buffet, we encourage everyone to take only what they need and leave some for the other clients. With our simple rate-limiting implementation, we can ensure that everyone gets a fair share of the resources and can enjoy a smooth and efficient experience with our API.&lt;/p&gt;

&lt;p&gt;Let’s create a simple CRUD project called “manga-reader” to demonstrate the implementation of rate limiting.&lt;/p&gt;

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

&lt;p&gt;To follow along with this guide, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Node.js installed on your machine&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A basic understanding of JavaScript and Express.js&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Creating the Project&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Start by creating a new directory for your project and initializing it with yarn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;manga-reader
&lt;span class="nb"&gt;cd &lt;/span&gt;manga-reader
yarn init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the necessary dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add express morgan dotenv prisma @prisma/client express-rate-limit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Schema of the Project&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The schema for the project defines two models - Author and Manga - with a one-to-many relationship between them. The Manga model contains various attributes such as title, description, and language.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// schema.prisma&lt;/span&gt;
&lt;span class="nx"&gt;generator&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prisma-client-js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;datasource&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mysql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DATABASE_URL&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;model&lt;/span&gt; &lt;span class="nx"&gt;Author&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;     &lt;span class="nb"&gt;String&lt;/span&gt;  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;unique&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;   &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;bio&lt;/span&gt;    &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;mangas&lt;/span&gt; &lt;span class="nx"&gt;Manga&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="nx"&gt;Manga&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;          &lt;span class="nb"&gt;String&lt;/span&gt;   &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;unique&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt;       &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;     &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;published&lt;/span&gt;   &lt;span class="nb"&gt;Boolean&lt;/span&gt;  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;pages&lt;/span&gt;       &lt;span class="nx"&gt;Int&lt;/span&gt;
  &lt;span class="nx"&gt;language&lt;/span&gt;    &lt;span class="nx"&gt;Language&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;English&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;author&lt;/span&gt;      &lt;span class="nx"&gt;Author&lt;/span&gt;   &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;relation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;authorId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;references&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="nx"&gt;authorId&lt;/span&gt;    &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;created_on&lt;/span&gt;  &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;updated_on&lt;/span&gt;  &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Language&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;English&lt;/span&gt;
  &lt;span class="nx"&gt;French&lt;/span&gt;
  &lt;span class="nx"&gt;Japanese&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Implementing Rate Limiting&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With the &lt;code&gt;express-rate-limit&lt;/code&gt; package one can implement rate limiting in our project.&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="c1"&gt;// index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;morgan&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;morgan&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;dotenv&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;rateLimit&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express-rate-limit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./routes/index.route.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&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;apiLimiter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rateLimit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;windowMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;900000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 15 minutes&lt;/span&gt;
  &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// limit each client/ IP to 100 requests per 15 minutes&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;Too many requests, please try again later.&lt;/span&gt;&lt;span class="dl"&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;morgan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev&lt;/span&gt;&lt;span class="dl"&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlencoded&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiLimiter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// routes&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/manga&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;apiLimiter&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="c1"&gt;// Home&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="s2"&gt;/&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="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;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;statusCode&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="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Manga Reader Example API`&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// 404 route&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="s2"&gt;*&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="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;404&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;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;404&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="s2"&gt;`Route not found`&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;app&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 code above, a &lt;code&gt;rateLimit&lt;/code&gt; middleware instance was created together with the set of &lt;code&gt;windowMs&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; options. The &lt;code&gt;windowMs&lt;/code&gt; option sets the time interval for which the requests will be counted (in this case, 15 minutes), while &lt;code&gt;max&lt;/code&gt; sets the maximum number of requests that can be made within that time interval (in this case, 100).&lt;/p&gt;

&lt;p&gt;In this simple application, If a client tries to make more than 100 requests within a 15-minute time frame, they will receive an error message stating that they have reached the limit. This helps to prevent one client from overwhelming the system and ensures that all clients have equal access to the resources. To keep things simple and user-friendly, we can include a clear and concise error message along with a status code to provide more information on the cause of the error. This way, clients can easily understand what went wrong and take the necessary steps to rectify the issue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1iaj15fs8gx4ztjdk6ay.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1iaj15fs8gx4ztjdk6ay.PNG" alt="rate-limiting-example" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Implementing API rate limiting in your Node.js project is an important step toward maintaining the stability and reliability of your application. With the use of packages like &lt;a href="https://www.npmjs.com/package/express-rate-limit" rel="noopener noreferrer"&gt;&lt;code&gt;express-rate-limit&lt;/code&gt;&lt;/a&gt; or &lt;a href="https://www.npmjs.com/package/rate-limiter-flexible" rel="noopener noreferrer"&gt;&lt;code&gt;rate-limiter-flexible&lt;/code&gt;&lt;/a&gt;, you can easily set limits on requests and prevent abuse of your API by malicious users.&lt;/p&gt;

&lt;p&gt;It is important to remember that rate limiting is just one aspect of securing your API. There are other security measures you can implement, such as authentication and authorization, to ensure that only authorized users have access to sensitive data.&lt;/p&gt;

&lt;p&gt;So, have fun implementing rate limiting in your Node.js projects, and keep your API secure and stable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Connect
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on &lt;a href="https://www.linkedin.com/in/tijanayo/" rel="noopener noreferrer"&gt;&lt;strong&gt;Linkedin&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on the &lt;a href="https://twitter.com/Tijan_io" rel="noopener noreferrer"&gt;&lt;strong&gt;Bird app&lt;/strong&gt;&lt;/a&gt; ( Kindly follow I'll follow back immediately )&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can also connect in the comment section below&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>api</category>
      <category>javascript</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Understanding the Basics of ACID Principles in Database Management</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Mon, 20 Mar 2023 16:26:49 +0000</pubDate>
      <link>https://dev.to/tijan_io/understanding-the-basics-of-acid-principles-in-database-management-3937</link>
      <guid>https://dev.to/tijan_io/understanding-the-basics-of-acid-principles-in-database-management-3937</guid>
      <description>&lt;p&gt;During a recent interview, I was asked if I was familiar with the term "ACID" in the context of database administration or software development. While I had heard of the term before, I was uncertain of its meaning. I provided the interviewer with a brief explanation of my understanding, to which he replied “Hmm…alright”. In this article, we will delve into the ACID principle, its importance, real-world use cases, and why it is important.&lt;/p&gt;

&lt;p&gt;Let's discuss transaction and its meaning before delving into the ACID principles and their significance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transaction
&lt;/h2&gt;

&lt;p&gt;In the context of a database, a "transaction” is a group of database read-and-write operations that only succeed if all the operations within them succeed. Let’s walk through a classic example to explain this concept. Imagine you made a transfer from a personal account to a work account. Two actions are to take place&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Your account is debited (if you have enough funds to make that transfer) and your account balance is updated accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your work account is credited with the transferred amount, and the account balance is updated accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These two operations have to happen, or neither will happen at all. To keep the system consistent, there cannot be an in-between state during this operation. In a basic sense, that is what a transaction is all about.&lt;/p&gt;

&lt;h2&gt;
  
  
  A.C.I.D Properties of a transaction
&lt;/h2&gt;

&lt;p&gt;ACID is an acronym that stands for &lt;strong&gt;Atomicity&lt;/strong&gt;, &lt;strong&gt;Consistency&lt;/strong&gt;, &lt;strong&gt;Isolation&lt;/strong&gt;, and &lt;strong&gt;Durability&lt;/strong&gt;. which refers to properties that define a transaction. These ACID properties ensure that a set of database operations leaves the database in a valid state even in the event of unexpected errors. ACID transactions guarantee that each read, write, or modification of a table has the following properties:&lt;/p&gt;

&lt;h3&gt;
  
  
  Atomicity
&lt;/h3&gt;

&lt;p&gt;Atomicity ensures that a transaction's operations are handled as an independent unit and will either succeed or fail together. This is important because we can be certain of the status of the database in the event of an unpredictable scenario, such as a crash or power outage. If any aspect of the transaction failed, it would have either been completed successfully or rolled back.&lt;/p&gt;

&lt;p&gt;If we continue with the above example, if money is deducted from the account and the transaction fails, the changes are discarded and the transaction doesn't go through.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consistency
&lt;/h3&gt;

&lt;p&gt;Consistency ensures that transactions only make predetermined, predictable modifications to tables. Transactional consistency makes sure that data corruption or mistakes don't have unintended effects on your table's integrity.&lt;/p&gt;

&lt;p&gt;Let's go back to the earlier scenario and say you want to transfer money from your personal account to a work account once more, but your balance is negative. Even though you are aware that your account does not meet the requirements, you still attempt to make the transfer. You will be breaking the transaction's integrity, and the transaction will fail as a result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Isolation
&lt;/h3&gt;

&lt;p&gt;Isolation is a critical property of a transactional system that manages single or multiple transactions simultaneously. To prevent interference with each other, an isolated environment is created for each transaction. A good example of this is when two transactions for a $150 withdrawal begin at the same time, with each operation being carried out independently. This ensures that when both operations are completed, the balance will be $0 rather than $150.&lt;/p&gt;

&lt;h3&gt;
  
  
  Durability
&lt;/h3&gt;

&lt;p&gt;Durability ensures that changes are maintained after a transaction completes and is written to the database. By doing this, it is guaranteed that data in the system will be saved even in the event of system breakdowns, power outages, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why are ACID Principles important?
&lt;/h2&gt;

&lt;p&gt;ACID principles are important because they ensure that the data remains consistent and trustworthy, even when unexpected errors occur. They provide a reliable way to manage database transactions and ensure that the data is always available and accessible to users. Without the ACID principles, the integrity and consistency of the data would be compromised, leading to a loss of trust in the system and potentially significant consequences for the organization. Therefore, it is essential to understand and implement the ACID principles in any database management or software development project.&lt;/p&gt;

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

&lt;p&gt;ACID principles are crucial for ensuring the integrity and consistency of data in any database management or software development project. By providing a reliable way to manage transactions, ACID principles ensure that data remains available and accessible to users, even in the event of unexpected errors or system failures. As such, organizations need to understand and implement ACID principles to maintain trustworthy and consistent data and avoid the potential consequences of compromised data integrity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Connect
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on &lt;a href="https://www.linkedin.com/in/tijanayo/" rel="noopener noreferrer"&gt;&lt;strong&gt;Linkedin&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on the &lt;a href="https://twitter.com/Tijan_io" rel="noopener noreferrer"&gt;&lt;strong&gt;Bird app&lt;/strong&gt;&lt;/a&gt; ( Kindly follow I'll follow back immediately )&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can also connect in the comment section below&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>database</category>
      <category>architecture</category>
      <category>performance</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Access Token and Refresh Token: A Comprehensive Guide</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Sun, 19 Feb 2023 06:02:10 +0000</pubDate>
      <link>https://dev.to/tijan_io/access-token-and-refresh-token-a-comprehensive-guide-40g7</link>
      <guid>https://dev.to/tijan_io/access-token-and-refresh-token-a-comprehensive-guide-40g7</guid>
      <description>&lt;p&gt;Tokens are essential components of modern web application security. They are used to authenticate and authorize access to protected resources, such as APIs or databases, and ensure that only authorized users can access them. In this article, we will provide a thorough description of what tokens are and the many sorts of tokens, such as access tokens, refresh tokens, and more.&lt;/p&gt;

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

&lt;p&gt;Tokens are digital credentials that allow users and applications to be authenticated and authorized. A token is a string of characters that indicates a specific permission grant and often comprises information about the person or client who receives the token. Tokens can be used to gain access to restricted resources such as APIs or web services, as well as to validate the user's or client's identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Tokens
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Access Token
&lt;/h3&gt;

&lt;p&gt;An access token is a bearer token that is used to grant access to a protected resource. It is typically issued by an authentication server or identity provider and contains information about the user and their permissions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An authentication server can issue JWTs as access tokens that contain information about the user and the permissions granted to the client in order to authenticate users and grant access to protected resources.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The access token is then presented to the resource server whenever the user tries to access a protected resource and is used to verify that the user is authorized to access the resource.&lt;/p&gt;

&lt;p&gt;Access tokens are short-lived and expire after a certain amount of time, typically an hour or less. This ensures that even if an access token is compromised, it can only be used for a limited amount of time before it becomes invalid. Additionally, access tokens can be revoked at any time by the authentication server or the user, which makes them more secure than long-lived tokens.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Refresh Token
&lt;/h3&gt;

&lt;p&gt;Refresh tokens are long-lived tokens that are used to obtain a new access token. They are typically issued along with an access token and can be used to request a new access token when the current one expires. Refresh tokens are more secure than storing credentials on a device or browser, as they can be revoked by the authentication server at any time.&lt;/p&gt;

&lt;p&gt;Refresh tokens are usually kept separate from access tokens and are only used to obtain new access tokens. They are not passed along with API requests or used to authenticate users directly. This ensures that even if a refresh token is compromised, the attacker cannot use it to access protected resources directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. ID Token
&lt;/h3&gt;

&lt;p&gt;ID tokens are tokens that are used to authenticate the user and provide information about the user's identity. ID tokens are typically used in scenarios where a user logs in with an external identity provider (e.g., Google or Facebook). The ID token contains information about the user, such as their name and email address, and can be used by the client to authenticate the user.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Session Token
&lt;/h3&gt;

&lt;p&gt;Session tokens are tokens that are used to maintain a user's session with a web application. When a user logs in to a web application, the server issues a session token that is used to identify the user's session. The session token is typically stored in a cookie on the user's computer and is used to authenticate the user on subsequent requests.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: There are various sorts of tokens used in modern authentication servers; the ones listed above are some of the most common.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Using Access Tokens and Refresh Tokens
&lt;/h2&gt;

&lt;p&gt;A simple illustration of a Node.js application using JavaScript to show how access tokens and refresh tokens work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prep work
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a directory&lt;/span&gt;
&lt;span class="nx"&gt;mkdir&lt;/span&gt; &lt;span class="nx"&gt;desktop&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;access_token_refresh_token&lt;/span&gt;
&lt;span class="c1"&gt;// Change the directory into the folder&lt;/span&gt;
&lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;access_token_refresh_token&lt;/span&gt;
&lt;span class="c1"&gt;// Initialize npm&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the required dependency for this project with the command below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;jsonwebtoken&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because this is a simple app, we'll make two files: &lt;strong&gt;index.js&lt;/strong&gt; will handle all of the app's logic, and &lt;strong&gt;auth.middleware.js&lt;/strong&gt; will handle token authorization and checking.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;touch&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="nx"&gt;touch&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is created let us create the logic for the app&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="c1"&gt;// Index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt; &lt;span class="k"&gt;from&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;authenticateToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./auth.middleware.js&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&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="c1"&gt;// Generate a secret key for signing JWTs (normally this would be a long and random string)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;very_Secure_secret_key&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;refresh_token_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;enter user1 refresh token here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// In a real application, this data would be stored in a database&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&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="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password1&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password2&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;// Index route&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;/&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="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;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&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="s2"&gt;access_token_refresh_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="c1"&gt;// Route for logging in and generating 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;// In a real application, this would be validated against a database&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;u&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;u&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;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="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;u&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;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;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="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="c1"&gt;// Generate an access token with a short expiry time (e.g. 10 minutes)&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;userId&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;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;secret&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;1m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Generate a refresh token with a long expiry time (e.g. 30 days)&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="na"&gt;userId&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;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;secret&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;30d&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="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;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;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;error&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="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// In a real application, this would retrieve data from a database based on the user id&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;authenticateToken&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="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;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&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="s2"&gt;This is the protected message &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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Server listening on port 3000&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;he code above consists of two main parts: a login route and a protected route. When the server starts, it generates a secret key that will be used to sign and verify JWTs. In a real-world application, this key would be kept secret and not hardcoded in the source code.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;users&lt;/code&gt; array contains some hardcoded user data that will be used to validate the login credentials. Again, in a real-world application, this data would typically be stored in a database.&lt;/p&gt;

&lt;p&gt;The root route just returns a simple JSON message that says "access_token_refresh_token" and is used for testing purposes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxmh17k12b7h23astn5xy.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxmh17k12b7h23astn5xy.PNG" alt="index_testing_img" width="639" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/login&lt;/code&gt; route is where the user logs in and receives both an access token and a refresh token. The user's credentials are validated against the &lt;code&gt;users&lt;/code&gt; array, and if they are valid, an access token and a refresh token are generated. The access token has a short expiry time of 1 minute, while the refresh token has a longer expiry time of 30 days. The tokens are signed using the secret key and returned to the client in a JSON response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25w11ojwaz2sgecb6gxn.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25w11ojwaz2sgecb6gxn.PNG" alt="login_route_img" width="632" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/protected&lt;/code&gt; route is where the user can access a protected resource. This route is protected by the &lt;code&gt;authenticateToken&lt;/code&gt; middleware function, which checks the validity of the user's access token. If the access token is valid, the user is allowed to access the protected resource.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1iw4ln8h9ukar306780l.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1iw4ln8h9ukar306780l.PNG" alt="Protected_route_img" width="614" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the client sends a request to the &lt;code&gt;/protected&lt;/code&gt; route, it includes the access token in the &lt;code&gt;Authorization&lt;/code&gt; header. The &lt;code&gt;authenticateToken&lt;/code&gt; middleware function extracts the token from the header, verifies its validity using the secret key, and if the token is valid, allows the request to proceed to the protected route. If the token is not valid, the middleware function returns a 401 Unauthorized status code.&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="c1"&gt;// auth.middleware.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt; &lt;span class="k"&gt;from&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;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;very_Secure_secret_key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;authenticateToken&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="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="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="o"&gt;&amp;amp;&amp;amp;&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="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;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Access token not 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;secret&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;payload&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;403&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;error&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 or expired access 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="c1"&gt;// Attach the user ID to the request object for use in subsequent handlers&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;id&lt;/span&gt; &lt;span class="o"&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;id&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the access token expires, the client can use the refresh token to obtain a new access token without having to log in again. In a real-world application, this would typically involve sending the refresh token to the server in a separate request, which would then generate a new access token if the refresh token is still valid. However, this functionality is not implemented in the code above.&lt;/p&gt;

&lt;p&gt;Let us now use the refresh token that was provided. You will see that the accessToken is configured to expire in 1 minute (intentionally) even if the optimal length in a real-world application exceeds that. When the accessToken expires, the user will no longer be able to request that route, which is where the &lt;code&gt;/refresh&lt;/code&gt; the route comes in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9unyuidz5kiyii6sm9d.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9unyuidz5kiyii6sm9d.gif" alt="token_comes_in_image" width="498" height="298"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Route for refreshing 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;/refresh&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="nx"&gt;refreshToken&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;refreshToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Verify that the refresh token is valid and retrieve the user ID from it&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;secret&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;error&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 refresh 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&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="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Check if the refresh token is in the database and has not expired&lt;/span&gt;
    &lt;span class="c1"&gt;// This would typically be done using a database query&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;userId&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="na"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;refresh_token_1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;expiry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;refresh_token_2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;expiry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&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;storedToken&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;find&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="o"&gt;=&amp;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;refreshToken&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="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;storedToken&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;storedToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;storedToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expiry&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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;error&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 refresh 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="c1"&gt;// Generate a new access token with a short expiry time (e.g. 10 minutes)&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;userId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;secret&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;10m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Generate a new refresh token with a long expiry time (e.g. 30 days)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newRefreshToken&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;userId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;secret&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;30d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Update the refresh token in the database with the new value and expiry time&lt;/span&gt;
    &lt;span class="nx"&gt;storedToken&lt;/span&gt;&lt;span class="p"&gt;.&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;newRefreshToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;storedToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expiry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Return the new access token and refresh 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;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="na"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newRefreshToken&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a client sends a request to this route with a valid refresh token, the server generates a new access token and a new refresh token and returns them to the client.&lt;/p&gt;

&lt;p&gt;The code starts by extracting the refresh token from the request body&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&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;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;refreshToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It then verifies the refresh token by calling &lt;code&gt;jwt.verify()&lt;/code&gt; , this function checks if the token is valid and has not expired. If the token is invalid or has expired, the server returns a 401 response with an error message&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&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;secret&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;error&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 refresh token passed.&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;// If the refresh token is valid, the server extracts the user ID from the decoded token&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&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="nx"&gt;id&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;The server then checks if the refresh token is stored in the database and has not expired. In this example, the refresh tokens are stored in an array of objects&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;userId&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="na"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;refresh_token_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;expiry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// expires in 30 days&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;refresh_token_2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;expiry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// expires in 30 days&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;storedToken&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;find&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="o"&gt;=&amp;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;refreshToken&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="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;storedToken&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;storedToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;storedToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expiry&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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;error&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 refresh 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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server searches the &lt;code&gt;refreshTokens&lt;/code&gt; array for a token that matches the refresh token provided by the client. If a matching token is found, the server checks if the user ID in the token matches the user ID extracted from the decoded token and if the token has not expired. If any of these checks fail, the server returns a 401 response with an error message. If the refresh token is valid and has not expired, the server generates a new access token and a new refresh token and returns them to the client&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&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;userId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;secret&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;10m&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;newRefreshToken&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;userId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;secret&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;30d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;storedToken&lt;/span&gt;&lt;span class="p"&gt;.&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;newRefreshToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;storedToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expiry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;accessToken&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;refreshToken&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newRefreshToken&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server calls &lt;code&gt;jwt.sign()&lt;/code&gt; to generate a new access token and a new refresh token with short and long expiry times, respectively. It then updates the refresh token in the database with the new value and expiry time, and returns the new access token and refresh token to the client in a JSON response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzcv2sgnzlimcyvg6yl1.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzcv2sgnzlimcyvg6yl1.PNG" alt="resfresh_token_route" width="638" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Access tokens and refresh tokens are essential components of modern web applications that require user authentication. A well-designed token-based authentication system can help prevent unwanted access to restricted resources while also providing an efficient approach to managing user authentication across numerous devices and applications. By effectively implementing token-based authentication, developers can protect the security and privacy of user data while providing a seamless and streamlined user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Connect
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on &lt;a href="https://www.linkedin.com/in/tijanayo/" rel="noopener noreferrer"&gt;&lt;strong&gt;Linkedin&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on the &lt;a href="https://twitter.com/Tijan_io" rel="noopener noreferrer"&gt;&lt;strong&gt;Bird app&lt;/strong&gt;&lt;/a&gt; ( Kindly follow I'll follow back immediately )&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can also connect in the comment section below (Also link to the GitHub repo can be found here)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>api</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>node</category>
    </item>
    <item>
      <title>Prisma in 500 Seconds</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Thu, 09 Feb 2023 08:04:39 +0000</pubDate>
      <link>https://dev.to/tijan_io/prisma-in-500-seconds-2bl4</link>
      <guid>https://dev.to/tijan_io/prisma-in-500-seconds-2bl4</guid>
      <description>&lt;p&gt;With so many ORMs available, deciding which one to use for your JavaScript-based project can be difficult. You have a ton of options depending on your objectives or stack, including libraries like &lt;a href="https://typeorm.io/" rel="noopener noreferrer"&gt;TypeORM&lt;/a&gt;, &lt;a href="https://sequelize.org/" rel="noopener noreferrer"&gt;Sequelize&lt;/a&gt;, and &lt;a href="https://mongoosejs.com/" rel="noopener noreferrer"&gt;Mongoose&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this article, we'll be delving deeply into a different choice: one that provides a ton of fascinating features, a distinctive "ORM" experience, and a vibrant, committed team of developers supporting and working on it. It's called Prisma.&lt;/p&gt;

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

&lt;p&gt;Prisma is a modern, open-source tool that enables developers to build scalable, high-performance data access layers with ease. Whether you're building a web or mobile application, Prisma has everything you need to connect to your databases and manage your data with confidence. It consists of the following parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prisma Client&lt;/strong&gt;: Auto-generated and type-safe query builder for Node.js &amp;amp; TypeScript&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prisma Migrate&lt;/strong&gt;: Migration system&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prisma Studio&lt;/strong&gt;: GUI to view and edit data in your database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How does Prisma work?
&lt;/h3&gt;

&lt;p&gt;Prisma makes use of a Prisma Schema File, which allows developers to define their &lt;em&gt;application models&lt;/em&gt; in an intuitive data modeling language. It also contains the connection to a database and defines a &lt;em&gt;generator.&lt;/em&gt;&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="c1"&gt;// Relational Database&lt;/span&gt;
&lt;span class="nx"&gt;datasource&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgresql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DATABASE_URL&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;generator&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prisma-client-js&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;Let's briefly discuss on datasource db and Generator in the schema file&lt;/p&gt;

&lt;p&gt;In Prisma, a "data source" refers to the database that you are connecting to in order to manage your data. This data source could be a relational database such as MySQL or PostgreSQL, or it could be a NoSQL database such as MongoDB or Cassandra. Prisma provides a unified API for connecting to and querying your data source, regardless of the type of database you are using.&lt;/p&gt;

&lt;p&gt;The generator in Prisma is a tool that generates code based on your database schema. In other words, it creates code that corresponds to the structure of your database, including the tables, columns, and relationships between tables.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto-formatting
&lt;/h3&gt;

&lt;p&gt;Prisma provides a dedicated extension that assists with code highlighting and code formatting automatically if you are using an IDE like vscode. Use your IDE's extension pane shortcut or the keyboard shortcut "&lt;strong&gt;ctrl+shift+X&lt;/strong&gt;" to get there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3h7wwn7blk43tpjr3h6o.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3h7wwn7blk43tpjr3h6o.PNG" alt="Vscode Prisma Extension" width="800" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you install this extension, your Prisma files should automatically format; otherwise, just complete the next step to set up auto-formatting.&lt;/p&gt;

&lt;p&gt;File &amp;gt;&amp;gt; Preferences &amp;gt;&amp;gt; edit settings has JSON (top right corner)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdlu0wdpey1qsgykcx2p.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdlu0wdpey1qsgykcx2p.PNG" alt="vscode settings_json" width="800" height="151"&gt;&lt;/a&gt;&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="c1"&gt;// Copy and paste it into your settings.json&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[prisma]&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.defaultFormatter&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;Prisma.prisma&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;editor.formatOnSave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this change, Prisma will automatically format your code upon saving, which I find to be really helpful. And don't worry, Prisma has a built-in formatter if you are unable to do all of this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="nx"&gt;format&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Jumping In
&lt;/h2&gt;

&lt;p&gt;To get started with Prisma, the first step is to install it. Prisma provides a CLI that makes it easy to install and manage the various components of the platform. The installation process is straightforward and only takes a few minutes to complete. Simply run the following command in your terminal:&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="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;
&lt;span class="c1"&gt;// This will install prisma globally on your machine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Initialize
&lt;/h3&gt;

&lt;p&gt;Once you have installed Prisma globally on your machine, you can then initialize it inside your project with the following command in your terminal:&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="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a schema folder in your project directory and a `&lt;code&gt;.env&lt;/code&gt;` file, which will be used to store the database URL. The schema folder will house the database structure or model, which is used to define the desired state of the database.&lt;/p&gt;

&lt;p&gt;It is important to note that the `&lt;code&gt;npx prisma init&lt;/code&gt;` command sets up the necessary infrastructure for using Prisma in your project, including the creation of the schema folder and the .env file. By defining the database structure in the schema folder, you can effectively communicate the desired state of the database to the Prisma CLI, which can then be used to generate the necessary code for accessing and manipulating the database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Migration
&lt;/h3&gt;

&lt;p&gt;The migration system in Prisma is a key feature that allows you to make changes to your database schema over time. Prisma migrations ensure that your database stays in sync with your application's data model, making it easy to add, modify, or delete tables, columns, and relationships. For example, you can use the following code to create a table in your database:&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="nx"&gt;generator&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prisma-client-js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;datasource&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgresql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DATABASE_URL&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;model&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;id&lt;/span&gt;        &lt;span class="nb"&gt;String&lt;/span&gt;   &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;     &lt;span class="nb"&gt;String&lt;/span&gt;   &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;unique&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;      &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;createdAt&lt;/span&gt; &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;updatedAt&lt;/span&gt; &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;updatedAt&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;migrate&lt;/span&gt; &lt;span class="nx"&gt;dev&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command above is used to create a new migration in your Prisma project. The &lt;code&gt;migrate&lt;/code&gt; sub-command is used to manage migrations for your project, and the &lt;code&gt;dev&lt;/code&gt; option specifies that the migration should be created in the development environment. The &lt;code&gt;--name&lt;/code&gt; option is used to specify a custom name for the migration, in this case &lt;code&gt;init&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When you run this command, Prisma will create a new migration in your project's &lt;code&gt;migrations&lt;/code&gt; directory with the specified name. This migration will contain a set of instructions for updating your database schema. You can then use the Prisma CLI to apply the migration to your database by using the &lt;code&gt;npx prisma migrate up&lt;/code&gt; command.&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="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="nx"&gt;migrate&lt;/span&gt; &lt;span class="nx"&gt;up&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;npx prisma migrate up&lt;/code&gt; is a specific sub-command of the &lt;code&gt;migrate&lt;/code&gt; command. It is used to apply pending migrations to your database. When you run &lt;code&gt;npx prisma migrate up&lt;/code&gt;, Prisma will look at the migrations that have been created for your project and apply any that have not yet been executed in your database. This will update your database schema to reflect the changes you have made in your migrations&lt;/p&gt;

&lt;h3&gt;
  
  
  Prisma Client
&lt;/h3&gt;

&lt;p&gt;The Prisma Client is an important component of the Prisma ecosystem and plays a critical role in the interaction between your application and database. It is a client library that provides a type-safe and convenient API for querying and managing your data in Node.js and TypeScript applications.&lt;/p&gt;

&lt;p&gt;To install the Prisma client, you can run the following commands in your terminal:&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="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;dev&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;latest&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;prisma&lt;/span&gt;&lt;span class="sr"&gt;/client@lates&lt;/span&gt;&lt;span class="err"&gt;t
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Prisma client is generated based on the data model defined in your Prisma schema and is always in sync with the structure of your database. This guarantees type safety and prevent runtime errors, making it easier to write and maintain your code.&lt;/p&gt;

&lt;p&gt;Using the Prisma client in your application is straightforward. To get started, you can create an instance of the &lt;code&gt;PrismaClient&lt;/code&gt; class and use its methods to interact with your database.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PrismaClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@prisma/client&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;prisma&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PrismaClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getAllUsers&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;allUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&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="nf"&gt;findMany&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;allUsers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;getAllUsers&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a few lines of code, you can retrieve all the records from the &lt;code&gt;User&lt;/code&gt; table in your database and log the results.&lt;/p&gt;

&lt;p&gt;The Prisma Client also provides a number of other methods for querying, updating, and managing your data, including methods for creating, updating, and deleting records and for working with transactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prisma Studio
&lt;/h3&gt;

&lt;p&gt;Prisma Studio is a graphical user interface (GUI) tool that provides a convenient and intuitive way to interact with your Prisma-powered database. With Prisma Studio, you can view and manage your data, run queries, and perform other database-related tasks, all from a user-friendly web interface.&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="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="nx"&gt;studio&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start a local instance of Prisma Studio, which you can access by navigating to &lt;a href="http://localhost:5555" rel="noopener noreferrer"&gt;&lt;code&gt;http://localhost:5555&lt;/code&gt;&lt;/a&gt; in your web browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff1ifks2zr54vqettyy2l.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff1ifks2zr54vqettyy2l.PNG" alt="Prisma Studio" width="800" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the key features of Prisma Studio is its visual data explorer, which provides an intuitive interface for querying and manipulating your data. You can easily view your data in a tabular format, run queries, and perform other data-related tasks, all from a single interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Relationships
&lt;/h3&gt;

&lt;p&gt;Relationships are an essential aspect of most databases, and Prisma makes it easy to define and manage relationships between tables in your database. Relationships in Prisma can be one-to-one, one-to-many, or many-to-many, and are defined using the &lt;code&gt;@relation&lt;/code&gt; directive in your Prisma schema.&lt;/p&gt;

&lt;p&gt;Let's update our schema a bit in other to grasp the concept around relationships and see how Prisma handles them&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="nx"&gt;model&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;id&lt;/span&gt;               &lt;span class="nb"&gt;String&lt;/span&gt;          &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;            &lt;span class="nb"&gt;String&lt;/span&gt;          &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;unique&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;             &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;posts&lt;/span&gt;            &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="nx"&gt;userPreferences&lt;/span&gt;  &lt;span class="nx"&gt;userPreference&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
  &lt;span class="nx"&gt;createdAt&lt;/span&gt;        &lt;span class="nx"&gt;DateTime&lt;/span&gt;        &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;updatedAt&lt;/span&gt;        &lt;span class="nx"&gt;DateTime&lt;/span&gt;        &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;updatedAt&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;        &lt;span class="nb"&gt;String&lt;/span&gt;   &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt;     &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;   &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;authorId&lt;/span&gt;  &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;author&lt;/span&gt;    &lt;span class="nx"&gt;User&lt;/span&gt;     &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;relation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;authorId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;references&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt;      &lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="nx"&gt;createdAt&lt;/span&gt; &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;updatedAt&lt;/span&gt; &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;updatedAt&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="nx"&gt;Tags&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;    &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt;  &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="nx"&gt;userPreference&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;           &lt;span class="nb"&gt;String&lt;/span&gt;  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;emailUpdate&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;
  &lt;span class="nx"&gt;userId&lt;/span&gt;       &lt;span class="nb"&gt;String&lt;/span&gt;  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;unique&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;         &lt;span class="nx"&gt;User&lt;/span&gt;    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;relation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;references&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&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;I updated the schema with 3 extra models Post, Tags, UserPreference&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;User&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;code&gt;Post&lt;/code&gt;: &lt;em&gt;One-to-Many&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;User&lt;/code&gt; model has a one-to-many relationship with the &lt;code&gt;Post&lt;/code&gt; model. This relationship is established through the &lt;code&gt;posts&lt;/code&gt; field in the &lt;code&gt;User&lt;/code&gt; model and the &lt;code&gt;author&lt;/code&gt; field in the &lt;code&gt;Post&lt;/code&gt; model.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;posts&lt;/code&gt; field in the &lt;code&gt;User&lt;/code&gt; model is an array of &lt;code&gt;Post&lt;/code&gt; records, representing the posts created by that user. On the other hand, the &lt;code&gt;author&lt;/code&gt; field in the &lt;code&gt;Post&lt;/code&gt; model is a single &lt;code&gt;User&lt;/code&gt; record representing the author of the post.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;User&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;code&gt;UserPreference&lt;/code&gt;: &lt;em&gt;One-to-One&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;User&lt;/code&gt; model also has a one-to-one relationship with the &lt;code&gt;UserPreference&lt;/code&gt; model. This relationship is established through the &lt;code&gt;userPreferences&lt;/code&gt; field in the &lt;code&gt;User&lt;/code&gt; model and the &lt;code&gt;user&lt;/code&gt; field in the &lt;code&gt;UserPreference&lt;/code&gt; model.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;userPreferences&lt;/code&gt; field in the &lt;code&gt;User&lt;/code&gt; model is a single &lt;code&gt;UserPreference&lt;/code&gt; record representing the preferences of the user. The &lt;code&gt;user&lt;/code&gt; field in the &lt;code&gt;UserPreference&lt;/code&gt; model is a single &lt;code&gt;User&lt;/code&gt; record representing the user that the preferences belong to.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Post&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;code&gt;Tags&lt;/code&gt;: &lt;em&gt;Many-to-Many&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Finally, the &lt;code&gt;Post&lt;/code&gt; model has a many-to-many relationship with the &lt;code&gt;Tags&lt;/code&gt; model. This relationship is established through the &lt;code&gt;tags&lt;/code&gt; field in the &lt;code&gt;Post&lt;/code&gt; model and the &lt;code&gt;posts&lt;/code&gt; field in the &lt;code&gt;Tags&lt;/code&gt; model.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;tags&lt;/code&gt; field in the &lt;code&gt;Post&lt;/code&gt; model is an array of &lt;code&gt;Tags&lt;/code&gt; records representing the tags associated with the post. The &lt;code&gt;posts&lt;/code&gt; field in the &lt;code&gt;Tags&lt;/code&gt; model is an array of &lt;code&gt;Post&lt;/code&gt; records representing the posts associated with the tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Prisma opens up a wealth of opportunities for creating and maintaining efficient and effective data structures. With its rich set of features and intuitive syntax, Prisma makes it easier than ever to connect, store, and manipulate data in a way that's both powerful and straightforward. If you want to dig deeper and expand on what we talked about, check out the &lt;a href="https://www.prisma.io/docs" rel="noopener noreferrer"&gt;Prisma Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's Connect
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on &lt;a href="https://www.linkedin.com/in/tijanayo/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on the &lt;a href="https://twitter.com/Tijan_io" rel="noopener noreferrer"&gt;Bird app&lt;/a&gt; ( Kindly follow I'll follow back immediately )&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can also connect in the comment section below (Also link to the GitHub repo can be found here)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>prisma</category>
      <category>orm</category>
      <category>typescript</category>
      <category>api</category>
    </item>
    <item>
      <title>SSL 101 - Securing Your Online Presence</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Sat, 21 Jan 2023 15:49:23 +0000</pubDate>
      <link>https://dev.to/tijan_io/ssl-101-4koh</link>
      <guid>https://dev.to/tijan_io/ssl-101-4koh</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When you visit a website, the information that you share, such as your personal or financial data, needs to be kept private and secure. That's where Secure Socket Layer (SSL) certificates come in. These certificates are an essential component of online security and are necessary to establish a secure connection between a website and its visitors. In this article, we will discuss the importance of SSL certificates, how they work, the different types available, the difference between SSL and its successor, Transport Layer Security (TLS), and the various ways to obtain an SSL certificate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do you need an SSL certificate?
&lt;/h2&gt;

&lt;p&gt;An SSL certificate is necessary to establish a secure connection between a website and its visitors. This is particularly important when sensitive information, such as personal or financial data, is exchanged. Without an SSL certificate, this information can be intercepted and read by third parties (attackers), leading to potential fraud or identity theft. In addition, many modern web browsers will display a warning message when attempting to access a website without an SSL certificate, which can damage the trust of the website's visitors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding how SSL certificates work
&lt;/h2&gt;

&lt;p&gt;An SSL certificate works by creating an encrypted connection between a website's server and the visitor's web browser. When a visitor accesses a website with an SSL certificate, their browser verifies the certificate's authenticity and establishes an encrypted connection. This encrypted connection ensures that any information exchanged between the website and the visitor is kept private and secure.&lt;/p&gt;

&lt;p&gt;Under the hood the browser verifies that the certificate provided by the website:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Is valid for the same domain as the one being accessed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is been issued by a trusted CA (Certificate Authority).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is valid and has not passed its expiration date.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the user's browser has verified the validity of the SSL certification, the connection continues to be secure. If not, you will get a “not secure” warning in your browser, or it will deny access to the site. If successful, the browser and website server exchange the necessary details to form a secure connection and the site loads.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the different kinds of SSL?
&lt;/h2&gt;

&lt;p&gt;There are several different types of SSL certificates available, each with varying levels of security and validation. They include&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain Validated (DV) Certificates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the most basic type of SSL certificate and only verifies the ownership of the domain. The certificate authority (CA) will check that the person requesting the certificate has the authority to request it for the domain. Once the domain ownership is verified, the CA will issue the certificate. DV certificates are typically the quickest and easiest to obtain, but they offer the lowest level of trust and security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Organization Validated (OV) Certificates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;OV certificates provide a higher level of validation than DV certificates. In addition to verifying the ownership of the domain, the CA will also verify the organization behind the domain. This includes checking the organization's legal existence, address, and phone number. OV certificates take a bit longer to obtain than DV certificates, but they offer a higher level of trust and security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extended Validation (EV) Certificates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;EV certificates offer the highest level of validation and trust. In addition to verifying the ownership of the domain and the organization behind the domain, the CA will also conduct a rigorous vetting process to verify the organization's identity. This process includes checking government-issued documentation, conducting background checks on the organization's officers, and physically verifying the organization's address. EV certificates can take several days to a couple of weeks to obtain, but they offer the highest level of trust and security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wildcard Certificates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Wildcard certificate is a type of certificate that allows the certificate holder to secure any subdomains under a single domain name. For example, if you own the domain "&lt;a href="http://example.com" rel="noopener noreferrer"&gt;example.com&lt;/a&gt;" and have a wildcard certificate, you can secure "&lt;a href="http://sub1.example.com" rel="noopener noreferrer"&gt;sub1.example.com&lt;/a&gt;", "&lt;a href="http://sub2.example.com" rel="noopener noreferrer"&gt;sub2.example.com&lt;/a&gt;", "&lt;a href="http://sub3.example.com" rel="noopener noreferrer"&gt;sub3.example.com&lt;/a&gt;" etc. with a single certificate. It can be a cost-effective solution for organizations that have multiple subdomains and want to secure them all with a single certificate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-Domain Certificates (SAN)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Multi-Domain Certificates (SAN) are also called “Subject Alternative Name” (SAN) certificates. It allows the certificate holder to secure multiple domain names with a single certificate. For example, if you own the domains "&lt;a href="http://example.com" rel="noopener noreferrer"&gt;example.com&lt;/a&gt;" and "&lt;a href="http://example.net" rel="noopener noreferrer"&gt;example.net&lt;/a&gt;," you can secure both of them with a single SAN certificate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-Signed Certificates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Self-signed certificates are issued by the entity that runs the server rather than a trusted third-party CA. These types of certificates are suitable for internal use and testing, but they are not recommended for public-facing websites because they are not trusted by web browsers and may generate security warnings for visitors.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's important to note that, depending on the level of security and trust you need, you should choose the appropriate type of SSL certificate for your website&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is TLS and how does it differ from SSL?
&lt;/h2&gt;

&lt;p&gt;Transport Layer Security (TLS) is the successor to SSL and is considered to be more secure. Both SSL and TLS are cryptographic protocols that provide secure communication over the internet, but TLS has several key differences. One of the main differences is that TLS uses a stronger encryption algorithm, making it more difficult for third parties to intercept and read the information exchanged between a website and its visitors. Additionally, TLS requires the use of a certificate for server identification, which is not required for SSL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Different ways one can obtain an SSL certificate
&lt;/h2&gt;

&lt;p&gt;There are several ways to obtain an SSL certificate, including purchasing one from a reputable certificate authority (CA) such as &lt;strong&gt;DigiCert&lt;/strong&gt;, &lt;strong&gt;GlobalSign&lt;/strong&gt;, or &lt;strong&gt;Comodo&lt;/strong&gt;, or using a free certificate from &lt;strong&gt;Let's Encrypt&lt;/strong&gt;. Additionally, some web hosting providers may offer SSL certificates as part of their hosting packages.&lt;/p&gt;

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

&lt;p&gt;SSL certificates are a vital component of online security, ensuring that sensitive information exchanged between a website and its visitors is kept private and secure. There are various types of SSL certificates available, each with varying levels of security and validation. Its successor, TLS, provides a stronger encryption algorithm and requires a certificate for server identification. Obtaining an SSL certificate can be done by purchasing it from a reputable certificate authority, using a free certificate, or using one that some web hosting providers offer as part of their hosting package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Connect
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on &lt;a href="https://www.linkedin.com/in/tijanayo/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on the &lt;a href="https://twitter.com/Tijan_io" rel="noopener noreferrer"&gt;Bird app&lt;/a&gt; ( Kindly follow I'll follow back immediately )&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can also connect in the comment section below (Leave your thought...)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>Building your own LinkedIn Profile Scraper</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Tue, 17 Jan 2023 19:15:55 +0000</pubDate>
      <link>https://dev.to/tijan_io/building-your-own-linkedin-profile-scraper-30i</link>
      <guid>https://dev.to/tijan_io/building-your-own-linkedin-profile-scraper-30i</guid>
      <description>&lt;p&gt;Scraping is a computer technique for retrieving information from a web page and reusing it in another context.&lt;/p&gt;

&lt;p&gt;Using bots to retrieve and extract information and content from a website is known as "web scraping." Web scrapers are programs that search databases for information by using software, scripts, and other methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Scrape LinkedIn ❓
&lt;/h2&gt;

&lt;p&gt;As was already indicated, scraping can be a helpful tool for extracting information from a website. Online data can be retrieved by scraping. For instance, you can utilize LinkedIn's enormous user base of more than 828 million members by gathering data from its members' public profiles...&lt;/p&gt;

&lt;p&gt;These members' profiles can then be queried in an excel or CSV file, allowing you to undertake operations that are specific to your needs. For instance, I discovered that it may be quite time-consuming to search through a ton of recruiter profiles in an effort to find any information, such as emails, contact information, and more. As a result, I considered how I could use Python to help automate this process. We all have different reasons for doing things, and yours might include gathering contact information for people who work at a company you'd love to work for and obtaining their emails so you can set up phone calls and start a conversation, among other things.&lt;/p&gt;

&lt;p&gt;People have a misperception about scraping that makes it appear criminal; nonetheless, web scraping is completely legal. Although it has drawbacks, those won't be covered in this post; instead, you'll learn how to use Python packages and tools to make a LinkedIn profile scraper.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites 🔎
&lt;/h3&gt;

&lt;p&gt;Make sure you have the following libraries and languages installed on your machine&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Python&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BeautifulSoup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Selenium&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chrome WebDriver&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/" rel="noopener noreferrer"&gt;Beautiful Soup&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Beautiful Soup is a Python library for pulling data out of HTML and XML files. It creates parse trees from the XML or HTML file for easy traversal and manipulation, and allows the user to search the parse tree using a variety of filters and search queries to extract the desired data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;beautifulsoup4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;a href="https://www.selenium.dev/documentation/" rel="noopener noreferrer"&gt;Selenium&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Selenium is a popular open-source tool that is commonly used for automated testing of web applications. Selenium provides a way to interact with web pages through a web driver, which can simulate a user interacting with the page, such as clicking buttons, filling out forms, and navigating through pages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;selenium&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;a href="https://chromedriver.chromium.org/downloads" rel="noopener noreferrer"&gt;Chrome WebDriver&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Chrome WebDriver is a separate executable that WebDriver clients can use to interact with the Chrome browser. It is a part of the Selenium project and is used for automating web applications for testing purposes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S&lt;/strong&gt;  Find your browser's version on the settings page, then download the driver for the particular version you own.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.python.org/downloads/" rel="noopener noreferrer"&gt;Python&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Python is a high-level, interpreted programming language that is widely used for a variety of tasks such as web development, data analysis, artificial intelligence, and scientific computing. Python is a cross-platform language, which means that it can run on multiple operating systems such as Windows, macOS, and Linux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation 🛠️
&lt;/h2&gt;

&lt;p&gt;We can start putting our scraper into action to scrape profiles as soon as you have the essential libraries loaded into your machine.&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="c1"&gt;// Importing modules&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;selenium&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;webdriver&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;selenium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;common&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Keys&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;selenium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;common&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;by&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;By&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;selenium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;support&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;expected_condition&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;EC&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;selenium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;support&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;webDriverWait&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;bs4&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;BeautifulSoup&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;bs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"""&lt;/span&gt;&lt;span class="s2"&gt;
Note: The path included is the current location of the driver downloaded
&lt;/span&gt;&lt;span class="dl"&gt;"""&lt;/span&gt;
&lt;span class="c1"&gt;// The location where my driver is installed&lt;/span&gt;
&lt;span class="nx"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C:Program Files (x86)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;  &lt;span class="nx"&gt;chromedriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; 
driver = webdriver.Chrome(PATH)

// Webpage to be accessed
driver.get("https://www.linkedin.com/")
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The task can be completed more rapidly by splitting the steps the bot will take. The breakdown consists of the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Authentication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accessing a profile URL&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Getting useful information from the accessed profile and storing them inside a CSV file&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

&lt;p&gt;Create a function to handle the authentication aspect of the process&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="nx"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;email_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;XPATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;//*[@id=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;session_key&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="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;email_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User/email address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Program should sleep for 3 secs&lt;/span&gt;
        &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nx"&gt;password_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;XPATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;//*[@id=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;session_password&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="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;password_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nx"&gt;login_button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;XPATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;//*[@id=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;]/section[1]/div/div/form/button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;login_button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;An error occurred&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The XPATH is used to access each field (email, username, and password) in the authentication function above. This can be obtained by "inspecting" the field you've specified using your browser's "inspect" menu.&lt;/p&gt;

&lt;p&gt;Selenium by default gives us access to attributes that can be used to access particular HTML components. i.e.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;By.CLASS_NAME&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By.XPATH&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By. ID&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By.TAG_NAME&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By.NAME&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Search
&lt;/h3&gt;

&lt;p&gt;The next step in the breakdown process is searching; you can query the role of jobs and then filter by people to get a list of profiles that have that role in their profile.&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="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// Confirm the page is loaded before searching&lt;/span&gt;
        &lt;span class="nc"&gt;WebDriverWait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;EC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;presence_of_element_located&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLASS_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authentication-outlet&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;search&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;XPATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;//*[@id="global-nav-typeahead"]/input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Search Input&lt;/span&gt;
        &lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Software Developer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Search Input: ENTER&lt;/span&gt;
        &lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RETURN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nc"&gt;WebDriverWait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;EC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;presence_of_element_located&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;XPATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/html/body/div[6]/div[3]/div[2]/section/div/nav/div/ul/li[2]/button&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;people_btn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;XPATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/html/body/div[6]/div[3]/div[2]/section/div/nav/div/ul/li[2]/button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;people_btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;An error occurred&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The purpose of using &lt;code&gt;time.sleep()&lt;/code&gt; is to simulate human time lag behavior; otherwise, the bot will execute all of its orders immediately, raising a flag that could result in your profile being blocked by Linkedin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessing Profiles
&lt;/h3&gt;

&lt;p&gt;Taking each profile URL and saving it in a list so that it may be retrieved&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="nx"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nc"&gt;WebDriverWait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;EC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;presence_of_element_located&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLASS_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;search-results-container&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;page_source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;page_source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lxml&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;profiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;page_source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;class_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-aware-link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;all_profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nx"&gt;profile_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;profile&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;href&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;profile_ID&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;all_profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nx"&gt;all_profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile_ID&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;all_profile&lt;/span&gt;
    &lt;span class="nx"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;An error occurred&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Getting useful information
&lt;/h3&gt;

&lt;p&gt;Looping over each profile URL to retrieve certain attributes that will be included in the CSV file&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="c1"&gt;// import the CSV module&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;csv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;convert_into_csv&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;page_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;urls&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;page_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nx"&gt;driver&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="nx"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nx"&gt;soup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;page_source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lxml&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nx"&gt;profiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;soup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;class_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ph0 pv2 artdeco-card mb2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   
                &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;profile&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;class_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-heading-xlarge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;
                &lt;span class="nx"&gt;current_position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;profile&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;class_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-body-medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
                &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;profile&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;class_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pb2 pv-text-details__left-panel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;

                &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output.csv&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="s1"&gt;w&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;file_output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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="s1"&gt;Postion&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="s1"&gt;Location&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="s1"&gt;URL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="nx"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DictWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file_output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delimiter&lt;/span&gt;&lt;span class="o"&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="nx"&gt;lineterminator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fieldnames&lt;/span&gt;&lt;span class="o"&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;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeheader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

                    &lt;span class="nx"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerow&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;name&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;current_position&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;location&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;An error occurred)
        driver.quit()

convert_into_csv()
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The Selenium module provides a simple API for Selenium WebDriver function writing. The HTML can then be parsed using a different tool called Beautiful Soup. Both packages are dependable and useful companions for your web scraping endeavors.&lt;/p&gt;

&lt;p&gt;In this article, you learned how to use Selenium and Beautiful Soup to scrape data from LinkedIn. You completed the entire web scraping procedure from beginning to end and created a script that retrieves and stores user profile data from LinkedIn. Feel free to explore the possibilities with this extensive pipeline in mind and these two strong libraries in your toolkit.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: It is worth noting that scraping data from a website without permission is a violation of the website's terms of service and can be illegal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Let's Connect
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on &lt;a href="https://www.linkedin.com/in/tijanayo/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reach out to me on the &lt;a href="https://twitter.com/Tijan_io" rel="noopener noreferrer"&gt;Bird app&lt;/a&gt; ( Kindly follow I'll follow back immediately )&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can also connect in the comment section below (Leave your thought...)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
      <category>softwaredevelopment</category>
      <category>cloud</category>
    </item>
    <item>
      <title>What is versioning all about?</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Sat, 07 Jan 2023 15:55:31 +0000</pubDate>
      <link>https://dev.to/tijan_io/what-is-versioning-all-about-1lob</link>
      <guid>https://dev.to/tijan_io/what-is-versioning-all-about-1lob</guid>
      <description>&lt;p&gt;I found the name "versioning" in an article I read not long ago. The article talked about best practices when creating a REST API. I assume we are all tech-savvy here😉 but for those who aren't find below the Wikipedia version of what a REST API is&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A REST API (also known as a "RESTful API") is an application programming interface (API or web API) that conforms to the constraints of the REST architectural style and allows for interaction with RESTful web services.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Quite cumbersome if you would agree… In simpler terms, a REST API is a way for two computer systems to communicate with each other over the internet. It stands for "&lt;strong&gt;Representational State Transfer&lt;/strong&gt;" and is a set of rules for how the systems should send data back and forth to each other.&lt;/p&gt;

&lt;p&gt;Imagine you are trying to get a glass of water from the kitchen. You would go to the kitchen and ask someone to give you a glass of water. They would then get a glass and fill it with water from the tap before giving it to you. In this situation, you are like a computer system, and the person in the kitchen is like another computer system. You are sending a request for a glass of water, and the other system is responding by giving you the water.&lt;/p&gt;

&lt;p&gt;A REST API works in a similar way. One system (like a website) can send a request to another system (like a server) and ask it to do something, like get some data or save some information. The second system will then do what was asked and send a response back to the first system with the result.&lt;/p&gt;

&lt;p&gt;Does that make sense?&lt;/p&gt;

&lt;p&gt;Let’s try not to stray too much from the topic. Like any good developer, I searched Google for the ambiguous term at hand and discovered that I had already been using “versioning” in some of my projects; however, I hadn't given it much thought at the time or had chosen to use it because I saw others using it in their code. (p.s. : If there is a term you don't seem to understand, try searching for it before implementing.)&lt;/p&gt;

&lt;h2&gt;
  
  
  What is versioning ❓
&lt;/h2&gt;

&lt;p&gt;"Versioning" refers to the technique of making different versions of a web API available and accessible to developers. This enables the API to adapt and expand over time while remaining backward-compatible with existing integrations.&lt;/p&gt;

&lt;p&gt;There are several standard techniques for API versioning. One common approach is to include the API's version number in the base URL. For instance, an API might have a base URL of "&lt;a href="https://api.example.com/v1" rel="noopener noreferrer"&gt;https://api.example.com/v1&lt;/a&gt;" for version 1 and "&lt;a href="https://api.example.com/v2" rel="noopener noreferrer"&gt;https://api.example.com/v2&lt;/a&gt;" for version 2. A developer only needs to use the correct base URL to use a certain version of the API.&lt;/p&gt;

&lt;p&gt;Another common approach is to utilize the HTTP request's Accept header to identify the version of the API that the client wants to use. The server will then respond with the appropriate version of the API.&lt;/p&gt;

&lt;p&gt;To elaborate on the techniques I briefly mentioned above, there are four common approaches you might take when versioning.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;URI Path Versioning&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;URL Parameter Versioning&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Versioning with Content-Type in Accept Header&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Versioning with Custom Header&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  URI Path Versioning
&lt;/h3&gt;

&lt;p&gt;In URI path versioning, the version of the API is included in the URL path. For example, an API might have a base URL &lt;a href="https://api.example.com/v1" rel="noopener noreferrer"&gt;&lt;code&gt;https://api.example.com/v1&lt;/code&gt;&lt;/a&gt; for version 1, and a base URL &lt;a href="https://api.example.com/v2" rel="noopener noreferrer"&gt;&lt;code&gt;https://api.example.com/v2&lt;/code&gt;&lt;/a&gt; for version 2. When a developer wants to use a specific version of the API, they just need to use the corresponding base URL.&lt;/p&gt;

&lt;p&gt;Here is an example of making a request to version 1 of an API using URI path versioning&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/v1/endpoint&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  URL Parameter Versioning
&lt;/h3&gt;

&lt;p&gt;In URL parameter versioning, the version of the API is included as a query parameter in the URL. For example, an API might have a base URL of &lt;a href="https://api.example.com" rel="noopener noreferrer"&gt;&lt;code&gt;https://api.example.com&lt;/code&gt;&lt;/a&gt; and the version could be specified using a &lt;code&gt;version&lt;/code&gt; query parameter, like &lt;a href="https://api.example.com?version=1" rel="noopener noreferrer"&gt;&lt;code&gt;https://api.example.com?version=1&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is an example of making a request to version 1 of an API using URL parameter versioning&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;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;version&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/endpoint&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;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Versioning with Content-Type in Accept Header
&lt;/h3&gt;

&lt;p&gt;In this approach, the version of the API is specified using the &lt;code&gt;Accept&lt;/code&gt; header of the HTTP request. The server will then return the appropriate version of the API in the response.&lt;/p&gt;

&lt;p&gt;Here is an example of making a request to version 1 of an API using the &lt;code&gt;Accept&lt;/code&gt; 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/app.v1.categories&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/endpoint&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;headers&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Versioning with Custom Header
&lt;/h3&gt;

&lt;p&gt;In this approach, a custom header is used to specify the version of the API that the client wants to use. The server will then return the appropriate version of the API in the response.&lt;/p&gt;

&lt;p&gt;Here is an example of making a request to version 1 of an API using a custom 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X-API-Version&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/endpoint&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;headers&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use this approach, the server will need to be configured to look for the custom header and return the appropriate version of the API based on the value of the header.&lt;/p&gt;

&lt;p&gt;This approach can be useful if the API needs to support multiple versions and the other approaches (such as URI path versioning or URL parameter versioning) are not suitable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is versioning important ❓
&lt;/h2&gt;

&lt;p&gt;Versioning is important because it allows an API to change and evolve over time without breaking existing integrations. When a client (such as a website or mobile app) integrates with an API, it usually depends on the API to function properly. If the API changes in a way that is not backward-compatible, it can break the client's integration and cause the client to stop working.&lt;/p&gt;

&lt;p&gt;Versioning helps to prevent this problem by allowing multiple versions of the API to exist and be used concurrently. This means that when a new version of the API is released, existing clients can continue to use the old version until they are able to update their integration to use the new version.&lt;/p&gt;

&lt;p&gt;Versioning is also important because it allows developers to understand the changes that have been made to the API over time. By clearly documenting the changes made in each version of the API, developers can more easily understand how to use the latest version of the API and how it differs from previous versions.&lt;/p&gt;

&lt;p&gt;Overall, versioning helps to ensure that an API can change and improve over time without causing problems for existing clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices to remember 🤔💭
&lt;/h2&gt;

&lt;p&gt;There are a few best practices to keep in mind when versioning an API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use versioning to make backward-compatible changes to the API. If you need to make breaking changes, create a new version of the API rather than changing the existing version.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make it easy for developers to discover and use the latest version of the API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clearly document the changes made in each version of the API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note : It's crucial to thoroughly outline the changes made in each API version so that developers may understand how the most recent version differs from earlier versions and choose which version to use.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.dotnetnakama.com%2Fassets%2Fposts%2F021%2F021-000-notime-for-documentation-meme.webp%2520align%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.dotnetnakama.com%2Fassets%2Fposts%2F021%2F021-000-notime-for-documentation-meme.webp%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When not to use versioning ❌✋
&lt;/h2&gt;

&lt;p&gt;There are a few situations when it might not be necessary to use versioning in an API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the API is still in the early stages of development and is not yet being used by any external clients, versioning may not be necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the API is not expected to change significantly over time, versioning may not be necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the API is intended to be used by a small group of developers who are able to quickly update their integrations in response to changes, versioning may not be necessary.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That being said, it's generally a good idea to version an API from the start, even if it's not expected to change much. This allows the API to evolve over time without breaking existing integrations. It's easier to add versioning from the beginning than it is to retroactively add it later on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion ✍🏽🚶🏽
&lt;/h2&gt;

&lt;p&gt;In the preceding article, you learned why versioning is an important technique while developing and maintaining a REST API, approaches to versioning, the value of versioning, when not to use versioning, and so on. It's crucial to choose the appropriate approach for your API and to fully outline the changes made in each API version to improve developers experience.&lt;/p&gt;

&lt;p&gt;I'd love to receive feedback of any kind. If there's anything you'd like to tell me don't hesitate to reach out. Thanks for reading!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>vim</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>Stealth Startups and the Power of Proxycurl</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Fri, 30 Dec 2022 13:46:49 +0000</pubDate>
      <link>https://dev.to/tijan_io/stealth-startups-and-the-power-of-proxycurl-104j</link>
      <guid>https://dev.to/tijan_io/stealth-startups-and-the-power-of-proxycurl-104j</guid>
      <description>&lt;h2&gt;
  
  
  What is a stealth startup?
&lt;/h2&gt;

&lt;p&gt;Stealth startups are companies that operate in secret, often keeping their business plans and products under wraps until they are ready to launch them or reveal them to the public.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why go stealth?
&lt;/h2&gt;

&lt;p&gt;Why would a company go stealthy? A company may decide to run as a stealth startup for a number of reasons, including:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;To perfect their product or service:&lt;/strong&gt; By operating in secret, a company can focus on developing and refining their product or service without the pressure or scrutiny of the public or competitors. This can help ensure that the product or service is as high-quality as possible before it is released to the market.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;To maintain a competitive advantage:&lt;/strong&gt; By keeping its plans d progress secret, a company can maintain a competitive advantage over its rivals. In fields where innovation or technology is a major differentiator, this can be extremely crucial.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;To avoid drawing attention from competitors:&lt;/strong&gt; By operating in secret, a company can avoid drawing attention from competitors who might try to copy their ideas or disrupt their plans. This can give the company time to build a strong foundation and establish a foothold in the market before facing significant competition.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;To attract top talent:&lt;/strong&gt; By operating in secret, a company can attract top talent drawn to the excitement and challenge of working on a secret project. This can help the company build a strong team and work towards its goals more effectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;To build anticipation for the product or service:&lt;/strong&gt; By operating in secret, a company can build anticipation and interest in its product or service before it is released to the public. This can generate buzz and interest in the product, which helps drive demand and sales when it is finally launched.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is not to say that the company that took the stealth approach had a perfect outcome. There are also several potential drawbacks to operating as a stealth startup, including&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Difficulty attracting investment:&lt;/strong&gt; It can be difficult for a stealth startup to attract investment or funding without being able to share details about the company or its plans. Without a thorough understanding of a company's business model or product, investors could be hesitant to invest in it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Difficulty attracting and retaining top talent&lt;/strong&gt;: It can also be difficult for a stealth startup to attract and retain top talent if the company cannot share details about the work it will be doing. This can limit the company's ability to build a strong team and work towards its goals effectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Limited ability to build buzz or anticipation:&lt;/strong&gt; Operating in secret can also limit a company's ability to build buzz or anticipation for its product or service before it is released. This can make it harder for the company to generate demand and sales when the product is finally launched.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Increased pressure to succeed:&lt;/strong&gt; Finally, operating as a stealth startup can increase the pressure on the company to succeed, as it may have limited opportunities to build buzz or anticipation for its product or service before it is released. This can add additional stress and pressure on the company's founders and employees.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where does ProxyCurl fit in all of these?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nubela.co/proxycurl/" rel="noopener noreferrer"&gt;Proxycurl &lt;/a&gt;is a tool that can scrape publicly available data from the internet to gather information about individuals or companies. It can be used to track the movements of entrepreneurial talents by collecting data about their professional experience, education, and current employment. This information can be useful for companies looking to identify potential candidates for employment or investment opportunities.&lt;/p&gt;

&lt;p&gt;Proxycurl can also be used to follow the movements of current employees by collecting data about their professional experience and current employment. This can be useful for companies looking to track the career progression of their employees or identify potential retention risks. Check out how their product can be used to “&lt;a href="https://nubela.co/proxycurl/solutions/alternative-data-for-investment-firms?utm_campaign=writers%20domain&amp;amp;utm_source=website&amp;amp;utm_medium=review&amp;amp;utm_content=stealth%20startups%20good%20bad%20find" rel="noopener noreferrer"&gt;Uncover wealth of opportunities with stealth startups&lt;/a&gt;”&lt;/p&gt;

&lt;p&gt;Finally, Proxycurl can be used to identify investment signals by collecting data about a company's financial performance, funding rounds, and partnerships. This information can be useful for investors looking to identify promising investment opportunities.&lt;/p&gt;

&lt;p&gt;Curious Minded? Check out &lt;a href="https://nubela.co/blog/stealth-startups-the-good-the-bad-where-to-find-them/?utm_campaign=writers%20domain&amp;amp;utm_source=website&amp;amp;utm_medium=review&amp;amp;utm_content=stealth%20startups%20good%20bad%20find" rel="noopener noreferrer"&gt;here&lt;/a&gt; for more information about stealth startups.&lt;/p&gt;

</description>
      <category>startup</category>
      <category>productivity</category>
      <category>testing</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Data Bias: From Question to Conclusion</title>
      <dc:creator>Tijani Ayomide</dc:creator>
      <pubDate>Sat, 17 Sep 2022 08:00:47 +0000</pubDate>
      <link>https://dev.to/tijan_io/data-bias-from-question-to-conclusion-36on</link>
      <guid>https://dev.to/tijan_io/data-bias-from-question-to-conclusion-36on</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;So, recently, I've been learning a lot about data analysis, and it's been a wild ride thanks to the &lt;strong&gt;GoogleXCoursera scholarship program&lt;/strong&gt;. You will be amazed by what you discover about data, from how it is turned from its raw state into actual information to how it may be used to help business decision-makers make more educated choices. &lt;/p&gt;

&lt;h3&gt;
  
  
  Did you know ❓❓
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Between the beginning of time and 2003, Google generated five exabytes of data. This quantity of data was being generated every two days in 2010, and every 40 minutes by 2021.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Data analysis is somewhat similar to software development (Backend), where you evaluate the logic of things and try to determine how an application should flow. However, in this context, instead of thinking about the flow, you think about the data and try to figure out if that particular data is answering the question, you need it to answer, and if so, how can you modify that data into valuable information.&lt;/p&gt;

&lt;p&gt;A lot of things are overlooked during the process which can cause your data to be biased.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why are we talking about data bias ❓
&lt;/h2&gt;

&lt;p&gt;As a data analyst, business owner, or as general person you must consider bias and fairness from the moment you begin data collection until the point at which you offer your conclusion. &lt;/p&gt;

&lt;p&gt;An example of bias is when you are asked to participate in a poll to determine the number of people who would like to go fishing. You go ahead and presume you asked every student in the class, but you omitted the impacted (wheelchair-bound, disabled, etc.) individuals. That survey's data collection is systematically biased.&lt;/p&gt;

&lt;p&gt;Another example is being asked to take part in a survey of employees in your organization to see how much employees enjoy working from the office rather than working remotely, but ever since the Covid 19 incident, businesses have adopted a work-from-home/ hybrid policy. As a result, the survey was only taken by those who were present in the office at the time. You can tell right away that the data is biased since it does not fully represent the population (people at the office).&lt;/p&gt;

&lt;h2&gt;
  
  
  What does bias mean ❓
&lt;/h2&gt;

&lt;p&gt;Before providing more context, it is essential to understand what bias is. Using the above examples, you can see how being biased can cause data to be skewed.&lt;/p&gt;

&lt;p&gt;Simply put, bias refers to a preference for or against a person, group of people, or object. Since our perspective is more data analytical, data bias is an error that methodically skews outcomes in one direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Forms of Bias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sample Bias&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a sample doesn't accurately reflect the entire population. This can be avoided by ensuring that the sample is chosen at random.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unbiased Sampling&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A sample that is representative of the population being studied.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;Comment&lt;/span&gt; &lt;span class="nx"&gt;down&lt;/span&gt; &lt;span class="nx"&gt;below&lt;/span&gt; &lt;span class="nx"&gt;an&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;an&lt;/span&gt; &lt;span class="nx"&gt;unbiased&lt;/span&gt; &lt;span class="nx"&gt;sample&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Observer Bias&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are sometimes referred to as experimental bias or research bias. This is the tendency for two persons working on a project together to see things differently. It is more like the 6-9 case.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt1a0cztgca8sh3k92zz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt1a0cztgca8sh3k92zz.png" alt="Observer-bias-img" width="774" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Interpretation Bias&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tendency to interpret ambiguous situations in either a good or negative light.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qzg0hxi9ak271m44uhf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qzg0hxi9ak271m44uhf.gif" alt="Interpretation-bias-gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Confirmation Bias&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tendency to seek out or interpret information in a way that reinforces pre-existing ideas. People see what they want to see and ignore other types of information/data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfwx6zup93z5js5k4zv3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfwx6zup93z5js5k4zv3.png" alt="Confirmation-bias-img" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explore data credibility
&lt;/h2&gt;

&lt;p&gt;The more high-quality data you have the more confidence you can when making data-driven decisions. You can rest assured that your data is credible if you follow a methodology called &lt;strong&gt;ROCCC&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Which is an acronym for &lt;strong&gt;Reliable&lt;/strong&gt;, &lt;strong&gt;Original&lt;/strong&gt;, &lt;strong&gt;Comprehensive&lt;/strong&gt;, &lt;strong&gt;Cited&lt;/strong&gt; and &lt;strong&gt;Current&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R&lt;/strong&gt; - With this kind of data, you can be sure that you're getting unbiased and precise information because it comes from a trusted source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O&lt;/strong&gt; - You will eventually have to work with first party to third-party data; to ensure that you are working with reliable data and confirm with the original source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C&lt;/strong&gt; - The most accurate data has all the relevant details required to provide an answer or a solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C&lt;/strong&gt; - Consider these three factors when picking a data source: Who developed the dataset? Does it belong to a reputable organization? when the information was last updated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C&lt;/strong&gt; - The usefulness of data diminishes with time, and the finest data sources are current and relevant to the task at hand.&lt;/p&gt;

&lt;p&gt;If your data source has all these attributes, then your data “&lt;strong&gt;ROCCC&lt;/strong&gt;” pun intended 😄.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Connect 🖇️
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Reach out to me on &lt;strong&gt;&lt;a href="https://www.linkedin.com/in/tijanayo/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Reach out to me on the &lt;strong&gt;&lt;a href="https://twitter.com/Tijan_io" rel="noopener noreferrer"&gt;Bird app&lt;/a&gt;&lt;/strong&gt; (Kindly follow I'll follow back immediately)&lt;/li&gt;
&lt;li&gt;We can also connect in the comment section below (Leave your thought...)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>datascience</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
