<?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>Forem: Arnav Chauhan</title>
    <description>The latest articles on Forem by Arnav Chauhan (@foxy17).</description>
    <link>https://forem.com/foxy17</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%2F882000%2F88dbc47c-1c1e-4837-9c63-a39c1fc5d868.png</url>
      <title>Forem: Arnav Chauhan</title>
      <link>https://forem.com/foxy17</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/foxy17"/>
    <language>en</language>
    <item>
      <title>Bun 1.0 , is the Hype Justified?</title>
      <dc:creator>Arnav Chauhan</dc:creator>
      <pubDate>Fri, 15 Sep 2023 10:47:52 +0000</pubDate>
      <link>https://forem.com/foxy17/bun-10-is-the-hype-justified-af8</link>
      <guid>https://forem.com/foxy17/bun-10-is-the-hype-justified-af8</guid>
      <description>&lt;p&gt;Bun.js is a new JavaScript runtime that was released in v1.0 in September 2023. It has been met with a lot of hype, with some people calling it the "future of JavaScript." But is the hype justified?&lt;/p&gt;

&lt;p&gt;I came across Bun.js in a Fireship.io video back in July of 2022 and it read that it was going to be the fastest runtime. I dismissed it at that time as another Javascript framework like Deno without looking much into it. But with version 1.0 out with the benchmarks and a small hands on preview I have defiantly changed my mind. Fun fact &lt;a href="https://github.com/oven-sh/bun/commit/025fe36defe2468ca1ed224855aa1effa09001ca"&gt;first commit&lt;/a&gt; to Bun was done on 18 April 2021.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XblTKfES--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4s8963q9zo0yuughsrmv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XblTKfES--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4s8963q9zo0yuughsrmv.png" alt="Bun.js Github repo" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bun.js Introduction
&lt;/h2&gt;

&lt;p&gt;Fundamentally, Bun.js is a server-side JavaScript runtime similar to Node. A bundler/transpiler and a package management are built on top of this. Unlike Node, which uses the V8 engine, Bun is designed from the ground up using the WebKit/Safari JavaScriptCore engine. It does not diverge from Node. The libraries are created using C and Zig, and they specifically avoid relying on Node or NPM, reducing the amount of JavaScript in their stack. All of these choices are made to maximize performance. Huge performance improvements result by rewriting all JavaScript-implemented APIs, such as network and disk IO, in a lower level language.&lt;/p&gt;

&lt;p&gt;There are many features Bun provides, but to get started we should take note of the following features(taken from official documentation):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In &lt;code&gt;bun.js&lt;/code&gt;, every file is transpiled. TypeScript &amp;amp; JSX are simple to use out of the box without any configration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bun.js&lt;/code&gt; automatically loads environment variables from .env files&lt;/li&gt;
&lt;li&gt;Web APIs like fetch, WebSocket, and ReadableStream are builtin&lt;/li&gt;
&lt;li&gt;Node-API bun.js implements most of Node-API (N-API). Many Node.js native modules work out of the box.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;node:fs&lt;/code&gt; &lt;code&gt;node:path&lt;/code&gt; bun.js natively supports a growing list of Node.js core modules along with globals like Buffer and process&lt;/li&gt;
&lt;li&gt;Bun's plugin API is universal, meaning it works for both the bundler and the runtime. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o9fjMimc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cyk6dmokg2co21viwk5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o9fjMimc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cyk6dmokg2co21viwk5k.png" alt="Bun is Fun" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Bun has all the Fun
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Rapid startup: Bun.js starts up incredibly quickly, usually in less than one millisecond. This makes it perfect for applications that require responsiveness and for running on low-powered devices. &lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better DX : Another thing we need to talk about though is the bun package manager that's up to 25 times faster than NPM. And it's actually a standalone tool that can be used in any no Js project today.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Small memory footprint: The memory footprint of Bun.js is typically 10MB or less. It is therefore perfect for programs that must be memory-efficient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimal API surface area: Bun.js has a small number of APIs, making it simple to understand and utilize.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bun.js's support for WebAssembly enables it to execute code that has been compiled into native machine code. This can dramatically boost some applications' performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Bun Developer expirience
&lt;/h2&gt;

&lt;p&gt;Developer experience plays a big role in any framework or library that is out there. And I was shocked at how simple it is to work with bun, and how is support JSX out of the box.&lt;/p&gt;

&lt;p&gt;Here is an example code for a simple JSX preview hello world website.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bun.serve({
  fetch(req: Request) {
    return new Response(`&amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;h1&amp;gt;Hello World from bun JSX 🤩&amp;lt;/h1&amp;gt;
    `, {
        headers: {
            'Content-Type': 'text/html',
        }
    });
  },
  error(error: Error) {
    return new Response("Oops \n" + error.toString(), { status: 500 });
  },
  port: 4000
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kgkN_XA5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l9yl8ewmbpk42n418soo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kgkN_XA5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l9yl8ewmbpk42n418soo.png" alt="Impressed" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Overall, I am very impressed with Bun.js. It is a promising new JavaScript runtime that has a lot of potential. I believe that it is worth trying out if you are looking for a fast, efficient, and easy-to-use JavaScript runtime.&lt;/p&gt;

&lt;p&gt;I hope this blog post was helpful! Do checkout the official website to learn more about Bun.js, please visit the official website: &lt;a href="https://bun.sh/"&gt;https://bun.sh/&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>bunjs</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Why everyone is talking about Astro and island Architecture? 🚀</title>
      <dc:creator>Arnav Chauhan</dc:creator>
      <pubDate>Thu, 18 Aug 2022 08:47:00 +0000</pubDate>
      <link>https://forem.com/foxy17/why-everyone-is-talking-about-astro-and-island-architecture-1762</link>
      <guid>https://forem.com/foxy17/why-everyone-is-talking-about-astro-and-island-architecture-1762</guid>
      <description>&lt;p&gt;If you love exploring different technologies in the web development ocean I am sure &lt;strong&gt;Astro&lt;/strong&gt; must have been popping up a lot in your feed since few months. Astro's V1.0 got launched recently and a lot of people are testing out its capabilities by migrating their blogs or portfolio sites to Astro. &lt;/p&gt;

&lt;p&gt;But there are so frameworks that offer good SEO and lighthouse score so why are people still so hyped up about Astro. Well how would you react if someone told you that you can ship your simple website with zero JavaScript. When I heard this I was blown away but also had many doubts since there are scenarios where I need JavaScript and scenarios where loading JavaScript in a static pages just slows down the site.  &lt;/p&gt;

&lt;p&gt;To understand more about this lets deep dive into what Astro does differently than Next.js one of the widely used framework for static site generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Astro is a meta framework 🚀
&lt;/h2&gt;

&lt;p&gt;Unlike other frameworks like Gatsby or Next.js which are built on top of React , you can use components from React, Vue, Svelte and Solid.js directly in Astro. This makes it easy to migrate to Astro when you already have components written in this frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero JavaScript for static pages
&lt;/h2&gt;

&lt;p&gt;If you load a statically generated Next.js site which does not required any JavaScript based interaction you will still see that in the network tab your browser still loads many JavaScript file that are required by the framework as you can see in the image below.&lt;/p&gt;

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

&lt;p&gt;The main problem with this is that most of the time the JavaScript being loaded is not actually being used. You can see that almost 50% of my JavaScript is unused on my &lt;a href="https://www.carnav.in/" rel="noopener noreferrer"&gt;portfolio website &lt;/a&gt; which is made using Next.js.&lt;/p&gt;

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

&lt;p&gt;Now one may argue that this can be minimized by using suspense and lazy loading but even after using those techniques that JavaScript is still loaded later which is not required at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Astro&lt;/strong&gt;⚡ by default ships zero JavaScript to the browser. To achieve this Astro renders HTML on the server and strips away any remaining, unused JavaScript. This decreases the sites &lt;a href="https://web.dev/interactive/" rel="noopener noreferrer"&gt;Time to interactive&lt;/a&gt; resulting in faster load time for content based websites. Here is one example of the decrease in size by using Astro&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1437195415439360003-911" src="https://platform.twitter.com/embed/Tweet.html?id=1437195415439360003"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1437195415439360003-911');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1437195415439360003&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  How does Astro 🐱‍🚀 achieve this?
&lt;/h2&gt;

&lt;p&gt;We all know that Next.js also uses static site generation just like Astro but still ships with JavaScript so how does Astro manager to ship zero JavaScript. Unlike Next.js which still keeps JavaScript in the HTML statically rendered. Astro strips all of the JavaScript. Next.js requires JavaScript since it runs on top of React and creates a Single Page Application that means JavaScript is loaded every time when the page changes. On the other hand Astro render a Multiple Page Application that means each route in your Astro site is a different HTML page with only static HTML and CSS.&lt;/p&gt;

&lt;p&gt;But what if we required JavaScript like in a search bar or image carousel.&lt;/p&gt;

&lt;p&gt;This is done by a technique called &lt;strong&gt;&lt;a href="https://docs.astro.build/en/concepts/islands/#concept-partial-hydration" rel="noopener noreferrer"&gt;Partial Hydration&lt;/a&gt;&lt;/strong&gt; 🐳. Astro allows you to ship JavaScript explicitly only for those components which you want to run in the browser. Astro lets you hydrate only the required individual component without interrupting the rest of the static site. Other SSG frameworks like Gatsby and Next.js do not this feature as they consider your entire website as a single JavaScript application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Island Architecture in Astro 🏝️
&lt;/h2&gt;

&lt;p&gt;Astro uses the idea of Island structure, which is about building entire websites using partial hydration. In frameworks like Next.js a website is built into client-side rendered Html, CSS and JavaScript bundles which are then shipped to the user. In &lt;strong&gt;island architecture&lt;/strong&gt; static HTML pages are rendered on the server and  slots/placeholders are added around highly dynamic areas for interactivity. These slots contain server-rendered HTML output from the corresponding widgets, which are then hydrated on demand at the client side. &lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Source: &lt;a href="https://docs.astro.build/en/concepts/islands/" rel="noopener noreferrer"&gt;Astro Docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This pattern isolates each page into separate small islands, any performance issue in one islands won’t cause any direct impact upon other units and also ensures that  faster faster loading and rendering of lightweight components individually without being barred by other heavier components are loaded individually without being barred by other heavier components.&lt;/p&gt;

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

&lt;p&gt;Combination of all the features listed above make Astro a good choice for sites which have a lot of static content like  marketing sites, publishing sites, documentation sites and blogs. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>astro</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Common Engineering mistakes new Software developers to make: Part-1</title>
      <dc:creator>Arnav Chauhan</dc:creator>
      <pubDate>Sat, 06 Aug 2022 11:38:00 +0000</pubDate>
      <link>https://forem.com/foxy17/common-engineering-mistakes-new-software-developers-to-make-part-1-3p5b</link>
      <guid>https://forem.com/foxy17/common-engineering-mistakes-new-software-developers-to-make-part-1-3p5b</guid>
      <description>&lt;p&gt;As new software developers, people tend to think of themselves just as a developer and often forget about the engineering aspect of their profession. Software development involves writing and understand code to build a software. Software engineering means using engineering concepts to develop software that is scalable, extensible, and maintainable in long run.&lt;/p&gt;

&lt;p&gt;Many software engineers especially the ones who have just started with development often focus solely on the development problem and thus their software is rarely scalable or maintainable in long run. A lot of developers have a tough time understanding their own code which they would have written a month back which does not scale well when they start working in a team. In a team often others stumble upon your code when they have to use it or refactor it. It would be a big hassle if you have to explain what you have written to someone new every time such a situation arises. Thus when working in a team with senior engineers who review your code new developers often end up with multiple comments and requested changes on their review. Trust me I have been there, my PR once had around 40+ comments on GitHub when I was doing my first internship.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7OKf2we5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ovwkrb7b3fw6lzwh1ikz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7OKf2we5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ovwkrb7b3fw6lzwh1ikz.png" alt="My first PR as an inter" width="880" height="45"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So far I have worked in multiple early stage startups and done few freelancing gigs and have seen many new developers struggle with few points that I will share. I recommend developers to read the book &lt;strong&gt;Clean Code : Robert C Martin&lt;/strong&gt; as it's more approachable, especially for new developers.&lt;/p&gt;
&lt;h2&gt;
  
  
  Mistake 1 - Most widespread mistake
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Poorly naming variables, functions, or any such identifiers.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Inevitably, code comments become lies over time. In practice, few people update comments when things change. Strive to make your code readable and self-documenting through good naming practices and known programming style.&lt;br&gt;
&lt;a href="https://opensource.com/article/17/5/30-best-practices-software-development-and-testing"&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I cannot stress this enough but name your variables according to what they are being used for. I have seen some people using variable names like -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var a , final c, const b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this is not at all scalable when you work in a team. For example, suppose you have written a function that doubles a number only if it is a multiple of 3. There are two ways to name the function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function double(num){//code to double multiple of 3}

function doubleMultipleOfThree(num){//code to double multiple of 3}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose someone in your team has used the first function name and you come across a code block where it is used while debugging the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(number &amp;gt; 0) double(number);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would expect the end result of this line to be double of whatever number is passed. But then you run it , the end result is not the same. So then you would have to go to the function body of double and read the whole function to understand what it does. This increases the time and effort for debugging/refactoring the code.&lt;/p&gt;

&lt;p&gt;Supposed if the function name would have been &lt;code&gt;doubleMultipleOfThree&lt;/code&gt; you would have easily figured out by the name itself what the function does and would not have to go to the function definition to understand it. Same principle applies to naming variables in your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake 2 - Not understand GIT
&lt;/h2&gt;

&lt;p&gt;Two main advantages of using Git at software development:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Tracking the changes and updates. We are able to see who made which changes. Git also provides when and why a change was made.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allowing to work collaboratively. Software development projects usually require many people to work together. Git provides the developers with a systematic way of doing that. Thus, the developers focus on the project instead of extensive communication sessions between the other developers.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most of the people are proficient with using GIT to achieve the first point, they can push, pull, commit and create a branch. This works fine when you are working alone, but when working in teams there are bunch of other commands and concepts that are used.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Since in teams many people are working on the same code there may be cases that changes in same files are made by two people. Which create merge conflicts. &lt;/li&gt;
&lt;li&gt;Sometimes you may need to rebase a branch instead of merging to it to keep the GIT history clean. &lt;/li&gt;
&lt;li&gt;You may need to stash your changes so that you can quicky switch to other branch without losing your changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are few of the many scenarios that happen in team. So one need to have at least basic understanding of commands like :- &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rebase &lt;/li&gt;
&lt;li&gt;Stash&lt;/li&gt;
&lt;li&gt;Merge&lt;/li&gt;
&lt;li&gt;Status &lt;/li&gt;
&lt;li&gt;Log&lt;/li&gt;
&lt;li&gt;Diff&lt;/li&gt;
&lt;li&gt;Revert&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are the ones I can list but there are many more commands that a developer should know the functionality of even if they don't remember the syntax or arguments for them. Its even better if you understand how GIT branching works and how commands like merge and rebase affect it.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>programming</category>
    </item>
    <item>
      <title>Nodejs GraphQl Authentication with JWT, Apollo-server, MySql and Sequelize ORM.</title>
      <dc:creator>Arnav Chauhan</dc:creator>
      <pubDate>Sun, 24 Jul 2022 16:33:08 +0000</pubDate>
      <link>https://forem.com/foxy17/nodejs-graphql-authentication-with-jwt-apollo-server-mysql-and-sequelize-orm-3af8</link>
      <guid>https://forem.com/foxy17/nodejs-graphql-authentication-with-jwt-apollo-server-mysql-and-sequelize-orm-3af8</guid>
      <description>&lt;p&gt;For past few years we have witnessed the growth of Microservice architecture at a whole different level.It focuses on developing software systems that tries to focus on building single-function modules with well-defined interfaces and operations. Along with it we have also seen a massive growth of Agile, Devops and APIs. Until few years back REST APIs were the industry standard and hot topic but in 2015 Facebook introduced GraphQL and in 2018 they released the first stable version of it.&lt;/p&gt;

&lt;p&gt;Github Repo - &lt;a href="https://github.com/foxy17/GraphQl-Authentication" rel="noopener noreferrer"&gt;GraphQL Authentication&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, we’ll focus on local authentication with JWT token.For database you can use any MySql database.Apollo-server is an open-source GraphQL server that is compatible with any kind of GraphQL client.I will use apollo to expose the API insted of express.&lt;/p&gt;

&lt;p&gt;We will be making a simple authentication in which a user will have a first name, last name, email, password, company and unique employeeId. Company will be stored on another table so that we can explore fetching associations with GraphQL. Lets install the necessary packages first:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i apollo-server bcrpytjs dotenv jsonwebtoken sequelize mysql2 graphql&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i -D sequelize-cli nodemon&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getUser = token =&amp;gt; {
    try {
        if (token) {
            return jwt.verify(token, JWT_SECRET)
        }
        return null
    } catch (error) {
        return null
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the first line after the imports, this is how we have defined out JWT middle-ware which will verify if our JWT token is valid.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const server = new ApolloServer({
    typeDefs,
    resolvers,
    context: ({ req }) =&amp;gt; {
        const token = req.get('Authorization') || ''
        return { user: getUser(token.replace('Bearer', ''))}
    },
    introspection: true,
    playground


: true
})
server.listen({ port: PORT || 8080 }).then(({ url }) =&amp;gt; {
    console.log(`🚀 Server ready at ${url}`);
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this we define our Apollo server which we have to pass an object which contains:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;typeDefs&lt;/em&gt;: which is the schema for the graphQL API, it defined the query and mutations we can call on the API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;resolvers&lt;/em&gt;: these are functions which are responsible for returning a result for respective API calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;context&lt;/em&gt;: it is an object shared by all the resolvers of a specific execution.This is where we retrieve the JWT token from header and run the getUser function we defined earlier to check if its valid and store the result in user variable which can be accessed by any resolver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;introspection&lt;/em&gt;: it defines whether we can query the schema for information about what queries it supports and their structure.(usually false in production)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;playground&lt;/em&gt;: is a graphical, interactive, in-browser GraphQL IDE we can use to run queries.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Lets checkout our typeDefs or Schema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const typeDefs = gql`
    input Pagination {
        page: Int!
        items: Int!
    }
    input UserFilter {
        employeeId: Int
        firstName: String
        lastName: String
    }
    type User {
        employeeId: Int!
        firstName: String!
        lastName: String!
        password: String!
        email: String!
        company: String!
    }
    type AuthPayload {
        token: String!
        user: User!
    }
    type Query {
        getUserList(search:UserFilter, pagination:Pagination, sort:String): [User]
    }
    type Mutation {
        registerUser(firstName: String!, lastName: String!, employeeId: Int!, email: String!, password: String!, company: String!): AuthPayload!
        login (email: String!, password: String!): AuthPayload!
    }
`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;gql&lt;/code&gt; template literal tag can be used to concisely write a GraphQL query that is parsed into a standard GraphQL &lt;a href="https://stackoverflow.com/questions/46163036/what-is-ast-in-graphql/46164403" rel="noopener noreferrer"&gt;AST&lt;/a&gt;. &lt;code&gt;type&lt;/code&gt; defines a object with its parameters. The &lt;code&gt;!&lt;/code&gt; mark means that the parameters are compulsory and cannot be undefined or null. There are two distinct types, query and mutation. In simple words the query is SELECT statement and mutation is INSERT Operation.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtb3o3t3v1doqz9ujw59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtb3o3t3v1doqz9ujw59.png" alt="Breaking down a mutaion"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apart from scalar types of &lt;code&gt;String, Int, Float, Boolean, and ID&lt;/code&gt; which we can directly assign as a type to argument or parameter we can have our own defined complex types as input. For that we use the input tag. The &lt;code&gt;UserFilter&lt;/code&gt; input is a custom input which is being passed to get user list query. The &lt;code&gt;[User]&lt;/code&gt; means that an array of type Users will be returned.&lt;/p&gt;

&lt;p&gt;All this was the main crust of GraphQL whats left now is the database models which will change according to your database choice and the resolver functions which are just like functions you define for REST API on a specific route.Lets look at the sequelize models.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//User.js
module.exports = (sequelize, DataTypes) =&amp;gt; {
    const User = sequelize.define('User', {
        firstName: { type: DataTypes.STRING, allowNull: true },
        lastName: { type: DataTypes.STRING, allowNull: true },
        email: { type: DataTypes.STRING, allowNull: false, unique: true },
        password: {type: DataTypes.STRING,allowNull: false},
        employeeId:{ type: DataTypes.INTEGER, allowNull: false, primaryKey: true, unique: true },
    }, {timestamps: false,
        hooks: {
            beforeCreate: async (user) =&amp;gt; {
             if (user.password) {
              const salt = await bcrypt.genSaltSync(10, 'a');
              user.password = bcrypt.hashSync(user.password, salt);
             }
            },
            beforeUpdate:async (user) =&amp;gt; {
             if (user.password) {
              const salt = await bcrypt.genSaltSync(10, 'a');
              user.password = bcrypt.hashSync(user.password, salt);
             }
            }
           }
    });
    User.associate = function (models) {
        User.hasOne(models.Company, { foreignKey: "employeeId" });
      };
    User.validPassword = async (password, hash) =&amp;gt; {
        return await bcrypt.compareSync(password, hash);
       }
    return User;
  };
//Company.js
module.exports = (sequelize, DataTypes) =&amp;gt; {
    const Company = sequelize.define('Company', {
        company: {type: DataTypes.STRING,allowNull: false},
        employeeId:{ type: DataTypes.INTEGER, allowNull: false, primaryKey: true, unique: true },
    }, {
      timestamps: false,
      freezeTableName: true,
    });
    Company.associate = function (models) {
        Company.belongsTo(models.User, { foreignKey: "employeeId" });
      };
    return Company;
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;beforeCreate&lt;/code&gt; is a hook is called when create query is being called. The hook contains logic to hash the password with a salt so that we don’t store un-encrypted password in database. &lt;code&gt;beforeUpdate&lt;/code&gt; this hook is called when update query is being called on user table. Just as before it hashesh the updated password. &lt;code&gt;User.validPassword&lt;/code&gt; is a class Methods which users bcrypt to compare the hash stored in db against a string to check if both are same. &lt;code&gt;User.associate&lt;/code&gt; is one-to-one association with company table with employeeId foreign key.&lt;code&gt;Timestamp:false&lt;/code&gt; by default sequelize includes a &lt;code&gt;createdAt&lt;/code&gt; and &lt;code&gt;updateAt&lt;/code&gt; record in SQL table but this sets that to false. &lt;code&gt;freezeTableName&lt;/code&gt; by defaults sequelize makes the table name plural which results in errors unless we have them set like that by default. Since I am not doing that &lt;code&gt;freezeTableName&lt;/code&gt; helps me keep the table names exactly what I have defined and not changed the &lt;strong&gt;User to Users&lt;/strong&gt; or &lt;strong&gt;Company to Companies&lt;/strong&gt;. Index.js is just the default seqelize files to connect to database. It also takes all the models defined in the models folder, and it applies them to the “db” object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const resolvers = {
    Query: {
        async getUserList(root, args, { user }) {
            try {
                if(!user) throw new Error('You are not authenticated!')
                const {search,pagination,sort} =args;
                var query={
                    offset:0,
                    limit:5,
                    raw: true,
                    //this is done to flaten out the join command
                    attributes: ['firstName','lastName','email','employeeId','Company.company',],
                    include: [{ model: models.Company,attributes:[]}]
                    }
                    //by defaults query is paginated to limit 5 items
                if(pagination){
                    query.limit=pagination.items;
                    query.offset=pagination.items*(pagination.page-1)
                }
                if(search){
                    query.where={
                        [Op.or]: [
                            search.firstName?{ firstName: search.firstName }:null,
                            search.lastName?{ lastName: search.lastName}:null,
                            search.employeeId?{ employeeId: search.employeeId}:null
                        ] 
                    }
                }
                if(sort){
                    query.order= [
                        [sort, 'ASC'],
                    ];
                }
                return await models.User.findAll(query);
            } catch (error) {
                throw new Error(error.message)
            }
        }
    },

    Mutation: {
        async registerUser(root, { firstName, lastName, email, password, employeeId,company }) {
            try {
                const userCheck = await models.User.findOne({ 
                    where: { 
                        [Op.or]: [
                            { email: email },
                            { employeeId: employeeId }
                    ] 
                }})
                if (userCheck) {
                    throw new Error('Email or Employee id already exists')
                }
                const user = await models.User.create({
                    firstName,
                    lastName,
                    employeeId,
                    email,
                    password
                })
                const companyModel = await models.Company.create({
                    employeeId,
                    company
                })
                const token = jsonwebtoken.sign(
                    { employeeId: user.employeeId, email: user.email},
                    process.env.JWT_SECRET,
                    { expiresIn: '1y' }
                )
                let createdUser={
                    company:companyModel.company,
                    employeeId: user.employeeId,
                    firstName: user.firstName, 
                    lastName: user.lastName, 
                    email: user.email
                }

                return {
                    token, user:createdUser, message: "Registration succesfull"
                }
            } catch (error) {
                throw new Error(error.message)
            }
        },

        async login(_, { email, password }) {
            try {
                const user = await models.User.findOne({ where: { email }})

                if (!user) {
                    throw new Error('No user with that email')
                }
                const isValid = await models.User.validPassword(password, user.password)
                if (!isValid) {
                    throw new Error('Incorrect password')
                }

                // return jwt
                const token = jsonwebtoken.sign(
                    { employeeId: user.employeeId, email: user.email},
                    process.env.JWT_SECRET,
                    { expiresIn: '1d'}
                )

                return {
                   token, user
                }
            } catch (error) {
                throw new Error(error.message)
            }
        }

    },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resolvers contain the functions that are called for respective query and mutation. They take in 4 arguments&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;root&lt;/code&gt; contains the result returned from the resolver on the parent field.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;args&lt;/code&gt; arguments passed into the field in the query.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;context&lt;/code&gt; object shared by all resolvers in a particular query.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;info&lt;/code&gt; contains information about the execution state of the query.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;code&gt;query&lt;/code&gt; object in &lt;code&gt;getUserList&lt;/code&gt; is a dynamic object which changes values based on arguments passed to the query. All arguments are optional. All queries require an Authorization header with valid jwt token. This is being validated by the&lt;br&gt;
&lt;code&gt;if(!user) throw new Error(‘You are not authenticated!’)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is user variables is being retrieved from context which we passes earlier in server.js. If we don’t want a route to be authenticated we just have to get rid of this line. Lets get the basic query explained. &lt;code&gt;offset&lt;/code&gt; and &lt;code&gt;limit&lt;/code&gt; are the pagination parameters. &lt;code&gt;raw&lt;/code&gt; is used to return a JSON object instead of a sequelize object so that it is easier to parase. Attributes lets us define what columns we want to be returned from SQL. Include is how we apply join between Company and User table so that we cant fetch the company name for a particular user. You will notice that we have set the attributes for include as empty. This means although they will be returned in query they will not be displayed. They would look something like this if returned &lt;code&gt;{Company.company:"name",Company.employeeId:2}&lt;/code&gt; and this throws and error when we try to parase it using graphQL schema since there we have defined the User to have company key and not &lt;code&gt;Company.company&lt;/code&gt; as the key. Thus to solve this we select &lt;code&gt;’Company.company’&lt;/code&gt; as an attribute of user which gets mapped to the company.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
“Authorization”:”eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbXBsb3llZUlkIjoyLCJlbWFpbCI6ImJAZ21haWwuY29tIiwiaWF0IjoxNjIyNTMwNTAyLCJleHAiOjE2MjI2MTY5MDJ9.3qQOHPzhKOjM6r5JNRWoMsvyt2IzwX8aa7Bj7s1zEZw”
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>node</category>
      <category>javascript</category>
      <category>mysql</category>
      <category>graphql</category>
    </item>
  </channel>
</rss>
