<?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: Diogo Souza</title>
    <description>The latest articles on DEV Community by Diogo Souza (@diogosouza).</description>
    <link>https://dev.to/diogosouza</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%2F416036%2F21fe8794-21e0-462a-a650-b55cd6bb9131.png</url>
      <title>DEV Community: Diogo Souza</title>
      <link>https://dev.to/diogosouza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/diogosouza"/>
    <language>en</language>
    <item>
      <title>Server-side Rendering in JavaScript: A Modern Approach</title>
      <dc:creator>Diogo Souza</dc:creator>
      <pubDate>Wed, 23 Dec 2020 10:47:03 +0000</pubDate>
      <link>https://dev.to/appsignal/server-side-rendering-in-javascript-a-modern-approach-2e0g</link>
      <guid>https://dev.to/appsignal/server-side-rendering-in-javascript-a-modern-approach-2e0g</guid>
      <description>&lt;p&gt;Let's talk about SPAs. It all starts from a blank page which is subsequently filled with HTML and JavaScript.&lt;/p&gt;

&lt;p&gt;If we take PHP pages as an example, they already come bundled with the server, which is an advantage in terms of performance, right?&lt;/p&gt;

&lt;p&gt;For situations like these, server-side rendering frameworks (such as &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;) come to the rescue. They process the code on the server-side to pre-fill the HTML result page with something (if not the whole page) before it reaches the browser.&lt;/p&gt;

&lt;p&gt;But is that all? Are there any other options, different paradigms or approaches to deal with this?!&lt;/p&gt;

&lt;p&gt;In this article, we're going to explore a few alternatives brewing in the community regarding server-side rendering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do You Know What JAMStack Is?
&lt;/h2&gt;

&lt;p&gt;Jamstack is a public effort to design an architecture that makes the web faster and scalable in terms of tools and workflows that us developers use today.&lt;/p&gt;

&lt;p&gt;It's built on top of some core principles that include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Pre-rendering&lt;/em&gt;: in order to become a Jamstack-compliant developer, you'll need to dominate pre-rendering tools such as Gatsby and Next.js, and deliver your websites through prebuilt static pages.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Decoupling&lt;/em&gt;: a famous concept that requires services and components to be clearly separated within your apps, reducing complexity and enhancing component independence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can read more on the movement &lt;a href="https://jamstack.org/what-is-jamstack/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Some of the things we'll discuss below are Jamstack-related, so give it a read if possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  What if the Clients Stop Data Fetching by Default?
&lt;/h2&gt;

&lt;p&gt;What do you mean? By default, most front-end frameworks today preach a complete separation between the front-end code and the back-end API that provides the endpoints that feed the client pages.&lt;/p&gt;

&lt;p&gt;What if we take a step back and let the server deal with data fetching by allowing it to generate client interfaces (GraphQL-based, for example) that handle everything 一 from routing to ORM management.&lt;/p&gt;

&lt;p&gt;Let's see an example with &lt;a href="https://redwoodjs.com/" rel="noopener noreferrer"&gt;RedwoodJS&lt;/a&gt; as the framework of choice. Redwood is an opinionated, full-stack, serverless web framework that easily allows the development of JAMstack apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does It Work?
&lt;/h2&gt;

&lt;p&gt;Rather than splitting the front and back-end sides of the application, Redwood aims to connect them through predefined GraphQL standards. Its goal is to be the full-stack framework you'd pick to create your SPAs. Take a look at the following graph:&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%2Fredwoodjs.com%2Fimages%2Fstructure.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%2Fredwoodjs.com%2Fimages%2Fstructure.png" alt="How Redwood works"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;How Redwood works. Source: &lt;a href="https://redwoodjs.com/" rel="noopener noreferrer"&gt;https://redwoodjs.com/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As you can see, both front and back-end worlds coexist within the same code repo. As we used to (and still) do with frameworks like Rails, .NET, etc. Yet, React is the front-end library of choice for the client-side.&lt;/p&gt;

&lt;p&gt;Redwood divides itself into two main containers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;/web&lt;/em&gt;: which contains the front-end stuff such as components, cells, forms, CSS, etc.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;/api&lt;/em&gt;: which contains the back-end API (built with GraphQL by default), as well as other optional services and lambdas.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Main Parts
&lt;/h2&gt;

&lt;p&gt;To achieve that, Redwood makes use of a bunch of features at its core. Like most of the frameworks, it comes with a custom routing system very similar to React Router, to take one example.&lt;/p&gt;

&lt;p&gt;However, one of the most important parts refers to the concept of &lt;em&gt;Cells&lt;/em&gt;. Redwood cells work as a scaffolded component that embraces the most common phases of an ordinary React component, such as retrieving data from the server, showing/hiding a loading placeholder, dealing with errors and success messages, and displaying the results in a proper listing component.&lt;/p&gt;

&lt;p&gt;Take a look at the following cell example extracted from the official docs:&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;QUERY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  query USERS {
    users {
      id
      name
    }
  }
`&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Loading&lt;/span&gt; &lt;span class="o"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Empty&lt;/span&gt; &lt;span class="o"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="nx"&gt;yet&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Failure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Success&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;users&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&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;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&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;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="o"&gt;|&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;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Since the components are attached to the GraphQL architecture, they must also embrace the gql schema structure within.&lt;/p&gt;

&lt;p&gt;Each of the phases (&lt;em&gt;loading&lt;/em&gt;, &lt;em&gt;empty&lt;/em&gt;, &lt;em&gt;failure&lt;/em&gt;, &lt;em&gt;success&lt;/em&gt;) is automatically managed by Redwood. You only need to overwrite them with your code or remove them in case they're not needed.&lt;/p&gt;

&lt;p&gt;Great! I got it. But, how does it work on the back-end side?&lt;/p&gt;

&lt;p&gt;Redwood is GraphQL-based by default, which means that you'll need to define a GraphQL SDL. Usually, you need to write resolvers to let GraphQL understand where to route the incoming requests and deliver the outgoing responses.&lt;/p&gt;

&lt;p&gt;Redwood simplifies this by doing it automatically. Based on your SDL specifications, services are auto-generated and each &lt;em&gt;query&lt;/em&gt; or &lt;em&gt;mutation&lt;/em&gt; is redirected to the specific service method. Take the following SDL as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="err"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;schema&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gql&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Post&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="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DateTime&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="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&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="n"&gt;posts&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="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;!]!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Post&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="k"&gt;input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CreatePostInput&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="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&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="k"&gt;input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UpdatePostInput&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="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&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="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Mutation&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="n"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CreatePostInput&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;updatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UpdatePostInput&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;deletePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Post&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="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It simply exposes two queries and three mutations to create a CRUD API over the posts' domain.&lt;/p&gt;

&lt;p&gt;The generated services usually work directly with the database to retrieve and update the information, but you can customize the service with whatever actions you want:&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;db&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;src/lib/db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&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="k"&gt;return&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;post&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&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="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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&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;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;input&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&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="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can customize these functions to retrieve data from a database, other API services, serverless lambdas, etc. Whatever you prefer.&lt;/p&gt;

&lt;p&gt;Each operation will also automatically provide successful results within the &lt;code&gt;Success&lt;/code&gt; cell component that we've previously seen. As simple as that!&lt;/p&gt;

&lt;p&gt;Redwood also offers other features like generators to avoid boilerplate code and forms to simplify the development of web forms along with React. For more on what you can do, please refer to its &lt;a href="https://redwoodjs.com/docs/" rel="noopener noreferrer"&gt;official docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turbine Your SPAs Without JavaScript Frameworks
&lt;/h2&gt;

&lt;p&gt;Have you ever found yourself uncomfortable with the "blinks" when transitioning from one SPA page to another? Have you ever heard about &lt;a href="https://github.com/turbolinks/turbolinks" rel="noopener noreferrer"&gt;Turbolinks&lt;/a&gt;? &lt;/p&gt;

&lt;p&gt;It is a small and lightweight library that coexists with your current server-rendered apps and makes navigating between pages faster by replacing the usual full page loads with partial page loads.&lt;/p&gt;

&lt;p&gt;It works by intercepting the clicks within your page that target the same domain, i.e., the same server-based application. When the click is intercepted, the browser is prevented from requesting it and, instead, Turbolinks changes the browser's URL via history API.&lt;/p&gt;

&lt;p&gt;Then it processes the request through an AJAX call and renders the response in the form of HTML.&lt;/p&gt;

&lt;p&gt;It sounds simple, doesn't it? It is, in fact, simple.&lt;/p&gt;

&lt;p&gt;Import the script into your &lt;code&gt;head&lt;/code&gt; tag or add the npm package to your Node.js project, and you're ready to go:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;While you don't need to reload the whole page and, consequently, improve performance; you also need to pay attention to your code design. You can't rely on page loads to restart a state anymore and must be aware that your JavaScript global objects (like &lt;code&gt;window&lt;/code&gt;) will retain the in-memory state. So, be careful.&lt;/p&gt;

&lt;p&gt;Other than that, Turbolinks also provides awesome features like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Caching&lt;/em&gt;. It keeps a cache of the recently visited pages. If you go back to some of the history pages, it'll optimize the experience to make sure no call to the server is performed.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;On-demand Scripts&lt;/em&gt;. If the subsequent pages you navigate to need to load new &lt;code&gt;script&lt;/code&gt; elements, Turbolinks will handle that by appending them to the &lt;code&gt;head&lt;/code&gt; tag. That's great to have — loaded on-demand scripts — they enhance the overall performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure to refer to the &lt;a href="https://github.com/turbolinks/turbolinks" rel="noopener noreferrer"&gt;official docs&lt;/a&gt; for the API Reference and some nice examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  What if We Don't Use JavaScript at All?
&lt;/h2&gt;

&lt;p&gt;I know, that sounds disruptive, not to mention too contrarian, but there are some guys revisiting the past to create new stuff, like &lt;a href="https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html" rel="noopener noreferrer"&gt;Phoenix LiveView&lt;/a&gt;, for example.&lt;/p&gt;

&lt;p&gt;Some parts of the web community has critics debating the number of languages (or tools) needed to create something for the web. For example, is it really necessary to replicate the same JavaScript logic developed in the front-end to the Node.js back-end?&lt;/p&gt;

&lt;p&gt;What if the state becomes fully controlled by the back-end rather than having agnostic APIs to provide endpoints for every change performed by the client?&lt;/p&gt;

&lt;p&gt;Take the LiveView use case. LiveView is a server-state framework, which means that the state is kept under the server, and managed within it.&lt;/p&gt;

&lt;p&gt;In other words, LiveView controls the state of the app — watching for changes made by the client and re-rendering the partial chunks related to that interaction back to the browser. The browser, in turn, will have a mechanism that understands these dynamics and updates the pages accordingly.&lt;/p&gt;

&lt;p&gt;This means that we don't need to track down every single change happening to the client. We create the client HTML, program the server capabilities, and leave the change listening to the framework.&lt;/p&gt;

&lt;p&gt;That's just one framework example (made in Elixir) out of many fermenting out there, such as &lt;a href="https://docs.stimulusreflex.com/" rel="noopener noreferrer"&gt;Stimulus&lt;/a&gt;, and Laravel Livewire. &lt;/p&gt;

&lt;p&gt;There are some work-in-progress Node.js ones, like &lt;a href="https://github.com/karthikv/purview" rel="noopener noreferrer"&gt;Purview&lt;/a&gt;, but it's still in the early stages. Take this example from the official repo:&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="nx"&gt;Purview&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;purview&lt;/span&gt;&lt;span class="dl"&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;Sequelize&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;sequelize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&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;Sequelize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sqlite:purview.db&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Purview&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&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;async&lt;/span&gt; &lt;span class="nf"&gt;getInitialState&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&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;// Query the current count from the database.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;]&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT count FROM counters LIMIT 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;rows&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;count&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPDATE counters SET count = count + 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInitialState&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;JSX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;increment&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;Click&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember that this code exists within the back-end side of the application, which is really cool. &lt;/p&gt;

&lt;p&gt;It resembles a bit of what we have with Redwood. The server code communicates directly with the database, has some well-defined phases (like the init state from React), and sets up a render method with the HTML output.&lt;/p&gt;

&lt;p&gt;Chances are that Next.js is going to provide similar features in the near future, which would be groundbreaking for the Node.js universe.&lt;/p&gt;

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

&lt;p&gt;Where to go from here? There are so many options that it's hard sometimes to choose a path... we know!&lt;/p&gt;

&lt;p&gt;The first tip I'll give you is to measure and discuss what's the purpose of the app you're building. Not every framework and library may suit your app's needs every time.&lt;/p&gt;

&lt;p&gt;Take the &lt;a href="https://htmx.org/" rel="noopener noreferrer"&gt;htmx&lt;/a&gt; library as an example. It is a super small ~8k dependency-free lib that helps you to easily perform AJAX calls and deal with WebSockets and SSE in your HTML. There's no need for a full SPA framework here.&lt;/p&gt;

&lt;p&gt;You first import it and then, program your HTML elements to perform a POST request via AJAX updating the DOM once it's finished. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Load from unpkg --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/htmx.org@0.3.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- have a button POST a click via AJAX --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;hx-post=&lt;/span&gt;&lt;span class="s"&gt;"/clicked"&lt;/span&gt; &lt;span class="na"&gt;hx-swap=&lt;/span&gt;&lt;span class="s"&gt;"outerHTML"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Click Me
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chances are that you've never heard of some of the tools we've talked about here. Whatever the case, they represent strong alternatives that you can try and figure out if they fit your reality or not. Give them a try!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S. If you liked this post, &lt;a href="https://blog.appsignal.com/javascript-sorcery" rel="noopener noreferrer"&gt;subscribe to our new JavaScript Sorcery list&lt;/a&gt; for a monthly deep dive into more magical JavaScript tips and tricks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.P.S. If you'd love an all-in-one APM for Node.js or you're already familiar with AppSignal, go and &lt;a href="https://www.appsignal.com/nodejs" rel="noopener noreferrer"&gt;check out AppSignal for Node.js&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Diogo Souza has been passionate about clean code, software design and development for more than ten years. If he is not programming or writing about these things, you'll usually find him watching cartoons.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>jamstack</category>
    </item>
    <item>
      <title>JavaScript Internals: Garbage Collection</title>
      <dc:creator>Diogo Souza</dc:creator>
      <pubDate>Tue, 15 Dec 2020 15:28:03 +0000</pubDate>
      <link>https://dev.to/appsignal/javascript-internals-garbage-collection-1lg5</link>
      <guid>https://dev.to/appsignal/javascript-internals-garbage-collection-1lg5</guid>
      <description>&lt;p&gt;Garbage collection (GC) is a very important process for all programming languages, whether it's done manually (in low-level languages like C), or automatically.&lt;/p&gt;

&lt;p&gt;The curious thing is that most of us barely stop to think about how JavaScript — which is a programming language, and hence, needs to GC — does the trick.&lt;/p&gt;

&lt;p&gt;Like the majority of high-level languages, JavaScript allocates its objects and values to memory and releases them when they’re no longer needed.&lt;/p&gt;

&lt;p&gt;But, how? How does it work internally?&lt;/p&gt;

&lt;p&gt;Well, this article aims to tackle this particular side of the language. Let’s go, then!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👋 Did you know that &lt;a href="https://blog.appsignal.com/2020/10/20/appsignal-is-free-for-open-source-software-and-for-good-projects.html"&gt;AppSignal gives away free accounts for amazing OSS projects&lt;/a&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  JavaScript Memory Lifecycle
&lt;/h2&gt;

&lt;p&gt;First of all, let’s clarify that this article is targeting how JavaScript tackles GC on web browsers. We’ve already covered GC on Node.js’s V8 in &lt;a href="https://blog.appsignal.com/2020/07/01/a-deep-dive-into-v8.html"&gt;another article&lt;/a&gt;. Yep, go for it too!&lt;/p&gt;

&lt;p&gt;The memory lifecycle for pretty much every programming language works as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SpLWNnBG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SpLWNnBG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure1.png" alt="Memory Lifecycle" width="880" height="335"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Languages’ memory lifecycle.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The differences reside in the way they do it (i.e. what algorithms they use) and how each phase must be addressed (manually or automatically).&lt;/p&gt;

&lt;p&gt;In JavaScript, the allocation and deallocation phases are automatic. However, it doesn’t mean that developers should only care about the use of the available memory.&lt;/p&gt;

&lt;p&gt;Stuff like infinite loops, badly-implemented recursion, and &lt;a href="http://callbackhell.com/"&gt;callback hells&lt;/a&gt; can drown your memory in no time and lead to &lt;a href="https://en.wikipedia.org/wiki/Memory_leak"&gt;memory leaks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, yes, the way you code — and, therefore, allocate/release memory slots — is also very important in avoiding such scenarios from happening.&lt;/p&gt;

&lt;p&gt;Back to the cycle.&lt;/p&gt;

&lt;p&gt;JavaScript works pretty much this way. It allocates space when new variables are created:&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;var&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when the memory is no longer being used, respecting the language limitations in terms of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var"&gt;variable scopes&lt;/a&gt;, the memory is released.&lt;/p&gt;

&lt;p&gt;But, how does JavaScript know the memory that's no longer in use? Through its Garbage Collector.&lt;/p&gt;

&lt;h2&gt;
  
  
  Garbage Collection Strategies
&lt;/h2&gt;

&lt;p&gt;JavaScript uses two famous strategies to perform GC: the Reference-counting technique and the Mark-and-sweep algorithm.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Reference_counting"&gt;reference-counting&lt;/a&gt;&lt;/strong&gt; approach is known for its versatility. You can count the number of references pointing to each allocated resource, whether it's a bunch of files, sockets, or memory slots.&lt;/p&gt;

&lt;p&gt;It considers that each allocated object in memory will contain a &lt;em&gt;count&lt;/em&gt; field (that works as a reference) attached to it. Whenever the object has no references pointing to it anymore, then it is automatically collected.&lt;/p&gt;

&lt;p&gt;Consider the following example:&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;var&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;bar&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two objects are created here: &lt;code&gt;bar&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt;. Since &lt;code&gt;bar&lt;/code&gt; is receiving a new value on the last line, then &lt;code&gt;name&lt;/code&gt; can be garbage collected.&lt;/p&gt;

&lt;p&gt;Simple, isn’t it? Now, imagine that your code evolves to the following:&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;var&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="nx"&gt;bar&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;foo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;foo&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;bar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript is a reference-based language when it comes to its objects, which means that the object names point to in-memory instantiated values. More than that, children’s objects/variables are automatically referenced by their parents.&lt;/p&gt;

&lt;p&gt;In the above example, we have a cycle being created. The &lt;code&gt;bar&lt;/code&gt; inside the &lt;code&gt;check&lt;/code&gt; function is referencing &lt;code&gt;foo&lt;/code&gt; and vice versa.&lt;/p&gt;

&lt;p&gt;Usually, when a function finishes its execution, its inner elements are garbage collected. However, in this case, the GC is unable to do it since the objects are still referenced to one another.&lt;/p&gt;

&lt;p&gt;And that’s where the second JavaScript GC actor comes into the scene: the &lt;strong&gt;mark-and-sweep&lt;/strong&gt; algorithm.&lt;/p&gt;

&lt;p&gt;This algorithm works by searching for objects that are unreachable from JavaScript’s top object — the &lt;code&gt;root&lt;/code&gt;’s global object.&lt;/p&gt;

&lt;p&gt;Take the following representation of the previous &lt;code&gt;bar&lt;/code&gt; object:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cLgKruMU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cLgKruMU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure2.png" alt="Tracking objects" width="880" height="297"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;How JavaScript tracks its objects.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As you can see, JavaScript can easily track down the &lt;code&gt;name&lt;/code&gt; object since its hierarchy is well defined.&lt;/p&gt;

&lt;p&gt;What happens, then, when the following code snippet runs?&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;var&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&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;Here you go:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v_fNyPUU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v_fNyPUU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure3.png" alt="no longer reaching the object" width="880" height="309"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;No longer reachable object.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;See? We can’t track the object from the root anymore. &lt;/p&gt;

&lt;p&gt;The rest of the process is pretty intuitive: the algorithm will go a couple of times, from the root to the bottom objects (and their respective hierarchies) &lt;strong&gt;marking&lt;/strong&gt; — to be ignored — all the objects that are reachable and &lt;strong&gt;sweeping&lt;/strong&gt; from memory at the end of the process, the ones that are not. Like the &lt;code&gt;name&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;It actually makes a lot of sense, doesn’t it?&lt;/p&gt;

&lt;p&gt;This process is repeated over and over through some internal conditions that only JavaScript’s GC knows, which is common to most of the GCs out there.&lt;/p&gt;
&lt;h2&gt;
  
  
  Node.js Garbage Collection
&lt;/h2&gt;

&lt;p&gt;Before we can jump right into the details of how Node.js performs garbage collection, we need to understand two special actors on the set: the &lt;strong&gt;heap&lt;/strong&gt; and &lt;strong&gt;stack&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The heap refers to the portion of memory dedicated to the storage of reference types. Reference types are everything that includes objects, strings, closures, etc.&lt;/p&gt;

&lt;p&gt;So, whenever you see an object created in JavaScript, this object will be placed on the heap:&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;myCat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Joshua&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;Meanwhile, the stack is the place where references to those objects created on the heap are contained. Function arguments, for example, are good examples of references existing on the stack:&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;function&lt;/span&gt; &lt;span class="nx"&gt;Cat&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="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;this&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;name&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;With all that said, how does &lt;a href="https://v8.dev/"&gt;V8&lt;/a&gt;, which is the JavaScript engine behind Node.js, perform GC?&lt;/p&gt;

&lt;p&gt;The heap is divided into two main parts called &lt;strong&gt;New Space&lt;/strong&gt; and &lt;strong&gt;Old Space&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IlWWAtPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IlWWAtPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure4.png" alt="New Space vs Old Space" width="880" height="481"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;New Space vs Old Space.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The New Space is the region of memory that allocates new objects and variables and, therefore, is way faster to GC since everything is fresh. As the name suggests, objects living here belong to the Young Generation.&lt;/p&gt;

&lt;p&gt;The Old Space is the place that the objects that weren't collected in the New Space head to after some time. They're called the Old Generation. It also stores other types of objects here like too large objects and V8 compiled code, but we won't focus on them.&lt;/p&gt;

&lt;p&gt;Node.js will do the best it can to avoid GC into the Old Space since it costs more to do so. This is why only up to 20% of the objects migrate from the Young to the Old Generation. That is also the reason why we have two different algorithms to deal with each generation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scavenge: this garbage collector takes care of the Young Generation by cleaning up small portions of memory every time it runs. It is super fast, which fits very well with the Young Generation nature.&lt;/li&gt;
&lt;li&gt;Mark-and-Sweep: we know this guy already. Since it is slower, it's the perfect choice for the Old Generation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Identifying Memory Leaks in Node.js
&lt;/h2&gt;

&lt;p&gt;A great way to see how JavaScript deals with memory in Node.js is through a classic memory leak example. Remember that a memory leak happens when all GC strategies have failed to find the object because it lost its connection to the root object. Other than that, we can also have a leak when an object is always referenced by other objects and, at the same time, continues to grow in size.&lt;/p&gt;

&lt;p&gt;For example, imagine that you have a simple Node.js server that you manually created and you want to store some important data from all the requests, as seen below:&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;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http&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;ml_Var&lt;/span&gt; &lt;span class="o"&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;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createServer&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;let&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;url&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;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;now&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;ml_Var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&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;writeHead&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ml_Var&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;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, we're creating a manual audit log from our requests. The variable &lt;code&gt;ml_Var&lt;/code&gt; is the dangerous spot in our code since it is a global variable and, therefore, is going to live in memory until the server shuts down (which can take a long time).&lt;/p&gt;

&lt;p&gt;Objects like that can become a huge problem in your apps, especially because other developers can add items to the array in other places that you won't be able to monitor.&lt;/p&gt;

&lt;p&gt;To simulate the scenario, we're going to make use of the Google Chrome DevTools. Wait, but this is a Node.js application... right? Yes, because both Chrome and Node.js uses the same JavaScript Engine (V8), the DevTools can understand how to debug and memory inspect both universes. Isn't it great?&lt;/p&gt;

&lt;p&gt;All that you need to do is to start your Node.js server with an &lt;code&gt;--inspect&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;After that, you may see the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Debugger listening on ws://127.0.0.1:9229/16ee16bb-f142-4836-b9cf-859799ce8ced
For help, see: https://nodejs.org/en/docs/inspector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, head to your Chrome (or Chromium) browser and enter the &lt;code&gt;chrome://inspect&lt;/code&gt; address. The following screen may appear:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Yp7WtRjG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Yp7WtRjG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure5.png" alt="Google Chrome DevTools Remote Target" width="589" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Google Chrome DevTools Remote Target.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Within the "Remote Target" section, there's an "inspect" link. When you click on it, the DevTools extension may open up with a direct session for your Node.js application. You'll be able to see the logs, sources, perform CPU profiling and memory analysis as well.&lt;/p&gt;

&lt;p&gt;If you head to the &lt;em&gt;Memory&lt;/em&gt; tab, you'll see a "Take snapshot" button located at the bottom of the page. Click on it and the DevTools will generate a heap snapshot profile (a memory dump) of our current running application. Since the goal is to compare the memory before and after the leak happens, that's our first step in the process.&lt;/p&gt;

&lt;p&gt;However, before we can take the other memory dumps, we need an auxiliary tool to help with benchmarking. In other words, we need to stress the application with many requests to validate the memory leak. And &lt;a href="https://www.npmjs.com/package/siege"&gt;siege.js&lt;/a&gt; is the perfect tool for that.&lt;/p&gt;

&lt;p&gt;Siege is a Node.js benchmarking tool that simplifies the task of running hundreds or thousands of requests against an endpoint.&lt;/p&gt;

&lt;p&gt;First, we'll need to run the &lt;code&gt;npm install siege --save&lt;/code&gt; command to get it installed and then, create another JavaScript file called &lt;em&gt;benchmark.js&lt;/em&gt; and add the following content:&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;siege&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;siege&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;siege&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&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="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;times&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&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;attack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we're asking &lt;em&gt;siege.js&lt;/em&gt; to run a total of 2000 requests on the root endpoint located under port 3000. As simple as that!&lt;/p&gt;

&lt;p&gt;Great! Now, we can move on to the other heap snapshots. Run the benchmark file:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Wait until it finishes. It'll produce the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET:/
    done:2000
    200 OK: 2000
    rps: 1709
    response: 5ms(min)  23ms(max)   9ms(avg)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Get back to DevTools and hit the "Take snapshot" button again. Just for safety, let's repeat the process once again until we have 3 snapshots. This will help to fine-tune the overall memory analysis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VY4U--gT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VY4U--gT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-10/figure6.png" alt="DevTools results" width="880" height="521"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;DevTools results.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are a couple of points to clarify here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The list of head snapshots. Select the third one to compare against the second.&lt;/li&gt;
&lt;li&gt;We need to select "Comparison" to enable the DevTools comparison features.&lt;/li&gt;
&lt;li&gt;Select the snapshot you'd like to compare with.&lt;/li&gt;
&lt;li&gt;The list of constructors created within the memory. The "# New" column will show the number of new objects created from the previous snapshot to the current one. Pay attention to the content of each string, they correspond to the JSON request logs we've created.&lt;/li&gt;
&lt;li&gt;The "Object" section brings details over the stack that has created each object. For the JSON strings, &lt;code&gt;ml_Var&lt;/code&gt; is the context in which they were created.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's interesting to see that 2014 string objects were created from one snapshot to another. The 2k refers to the request logs we introduced, the other 14 are strings created and managed by Node.js itself.&lt;/p&gt;

&lt;p&gt;In our example, only 3 executions led to 4k new objects in memory. Imagine such a scenario in a real application running in production. In no time, the memory would leak until there was nothing left.&lt;/p&gt;

&lt;p&gt;Now that you've identified the leak, the solution is quite simple. Just make sure to store those logs &lt;a href="https://www.npmjs.com/package/simple-node-logger"&gt;into a file&lt;/a&gt;, to an external service (like Splunk) or even to a database.&lt;/p&gt;

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

&lt;p&gt;Do you now understand the importance of proper attention when coding your JavaScript applications in terms of object allocation and deallocation?&lt;/p&gt;

&lt;p&gt;As further reading, I’d recommend the famous IBM &lt;a href="https://www.ibm.com/developerworks/web/library/wa-memleak/"&gt;study&lt;/a&gt; of memory leak patterns in JavaScript, which explores the consequences of circular references in the language.&lt;/p&gt;

&lt;p&gt;If you'd like to read more about memory leaks in Node.js, I strongly recommend &lt;a href="https://blog.appsignal.com/2020/05/06/avoiding-memory-leaks-in-nodejs-best-practices-for-performance.html"&gt;Deepu Sasidharan's article&lt;/a&gt; in which he talks about the best practices for performance in Node.js.&lt;/p&gt;

&lt;p&gt;Mozilla's official docs also bring a handful of great &lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Performance"&gt;articles&lt;/a&gt; about performance, including profiling, performance measurements, and automation. See you around!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S. If you liked this post, &lt;a href="https://blog.appsignal.com/javascript-sorcery"&gt;subscribe to our new JavaScript Sorcery list&lt;/a&gt; for a monthly deep dive into more magical JavaScript tips and tricks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.P.S. If you'd love an all-in-one APM for Node.js or you're already familiar with AppSignal, go and &lt;a href="https://www.appsignal.com/nodejs"&gt;check out AppSignal for Node.js&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Diogo Souza has been passionate about clean code, software design and development for more than ten years. If he is not programming or writing about these things, you'll usually find him watching cartoons.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Getting Started With Web Vitals in Next.js</title>
      <dc:creator>Diogo Souza</dc:creator>
      <pubDate>Thu, 01 Oct 2020 13:04:15 +0000</pubDate>
      <link>https://dev.to/appsignal/getting-started-with-web-vitals-in-next-js-1obg</link>
      <guid>https://dev.to/appsignal/getting-started-with-web-vitals-in-next-js-1obg</guid>
      <description>&lt;p&gt;In this article, I’ll try to guide you through some examples and definitions that aim to clarify the Web Vitals landscape from a Next.js perspective. Let's dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  How Google Grades Your Websites
&lt;/h2&gt;

&lt;p&gt;User experience is something that Google appreciates when its robots scan your website. They perform checks to make sure your website deserves a good spot on Google's famous search engine results page.&lt;/p&gt;

&lt;p&gt;They look for quality indicators such as performance, interactivity, the structure of the pages, responsiveness, safety (e.g. HTTPS), etc.&lt;/p&gt;

&lt;p&gt;If you've ever ventured into SEO waters, chances are that at first, you felt overwhelmed by the amount of stuff to worry about.&lt;/p&gt;

&lt;p&gt;For this reason, Google came to the rescue with &lt;a href="https://web.dev/vitals/" rel="noopener noreferrer"&gt;Web Vitals&lt;/a&gt;. They are a new way of analyzing your web pages and checking beforehand for things you might need to address and improve.&lt;/p&gt;

&lt;p&gt;Web vitals are a guide made with everybody in mind so that you can easily find out how your website performs. In case there are issues, you should be able to figure out how to address them with ease.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Web Vitals?
&lt;/h2&gt;

&lt;p&gt;To describe this a bit better, let’s check out a Chrome tool called &lt;a href="https://developers.google.com/web/tools/lighthouse" rel="noopener noreferrer"&gt;Lighthouse&lt;/a&gt;. If you’ve never heard about it, it’s an open-source automated tool that analyzes and collects quality metrics of web pages; and, yes, it makes use of Web Vitals principles.&lt;/p&gt;

&lt;p&gt;The tool is pretty straightforward. On the page that you want to analyze, right-click -&amp;gt; inspect -&amp;gt; look for Lighthouse in the top bar. From there, there are a few options you can choose from:&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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage1.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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage1.png" alt="Lighouse Preferences"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Picking up your Lighthouse preferences.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When we run the tool against the AppSignal homepage, we’ll get similar results to these:&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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage2.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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage2.png" alt="AppSignal metrics"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AppSignal’s performance metrics.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here, we’re just showing the metrics related to the &lt;em&gt;Performance&lt;/em&gt; section because they embrace more of what Web Vitals do. However, Lighthouse does more.&lt;/p&gt;

&lt;p&gt;In short, Web Vitals are divided into six main categories, among which, three are classified as Core Web Vitals to know:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Graph reference&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://web.dev/lcp/" rel="noopener noreferrer"&gt;Largest Contentful Paint (LCP)&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Here, Google tries to analyze the page loading time as it is perceived by the user, i.e., how long does it take for the main content of your page to load? &lt;br&gt; If the answer is &lt;strong&gt;&amp;gt;2.5s&lt;/strong&gt; then it needs to be improved. Of course, the lower the better.&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage3.png" alt="LCP"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://web.dev/fid/" rel="noopener noreferrer"&gt;First Input Delay (FID)&lt;/a&gt; / &lt;a href="https://web.dev/tbt/" rel="noopener noreferrer"&gt;Total Blocking Time (TBT)&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Now, let’s measure how long it takes for the first user interaction to happen within your page. Whether it is through a button click, a page scroll, your browser needs to be ready to respond to those commands in no time, even if the page is not fully loaded. If the time is greater than 100ms, Google asks you to work on that. &lt;br&gt; Oh, yes, the second indicator, &lt;em&gt;TBT&lt;/em&gt;, is an auxiliary measurement that analyzes the difference between the &lt;em&gt;FCP&lt;/em&gt; and the &lt;em&gt;TTI&lt;/em&gt; 一 more on them soon. In the end, they’re birds of a feather.&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage4.png" alt="FID"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://web.dev/cls/" rel="noopener noreferrer"&gt;Cumulative Layout Shift (CLS)&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;This one counts the number of times that stuff or components within a page move (shift) around during the loading. &lt;br&gt; Have you ever entered a website in which the elements start to “dance” alone before we can even figure out what’s the website about? So, the more you have this, the poorer the experience.&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage5.png" alt="CLS"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Graph’s source: &lt;a href="https://web.dev/vitals/" rel="noopener noreferrer"&gt;https://web.dev/vitals/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As you may have perceived, The Core Web Vitals are worried about three main points: the loading time, the responsiveness (interactivity), and the stability of the page.&lt;/p&gt;

&lt;p&gt;The other three non-Core Web Vitals are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://web.dev/time-to-first-byte/" rel="noopener noreferrer"&gt;Time to First Byte (TTFB)&lt;/a&gt;: it’s the time the browser takes to receive the first byte of page content.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://web.dev/fcp/" rel="noopener noreferrer"&gt;First Contentful Paint (FCP)&lt;/a&gt;: calculates the time it takes for any content on the page to first appear on the screen.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://web.dev/tti/" rel="noopener noreferrer"&gt;Time to Interactive (TTI)&lt;/a&gt;: it’s a metric of the time from when the page loading gets started until it reliably responds to user input.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those Vitals are considered more as of auxiliary since they help the Core ones (as well as Lighthouse) to calculate their scores.&lt;/p&gt;

&lt;p&gt;Now that you understand a bit more about them, you can refer back to AppSignal’s Lighthouse metrics in the previous figure and recognize what all the indicators, along with their values, are for.&lt;/p&gt;

&lt;p&gt;For more details on how Google calculates these metrics behind-the-scenes, please refer to the &lt;a href="https://web.dev/vitals/" rel="noopener noreferrer"&gt;official docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Vitals With Next.js
&lt;/h2&gt;

&lt;p&gt;Yes, since version 9.4.0, Next.js comes with a built-in layer that understands Web Vitals and allows you to collect such metrics within your Next apps.&lt;/p&gt;

&lt;p&gt;Let’s see how it works. First, we need a Next.js app. We’ll be making use of &lt;a href="https://yarnpkg.com/" rel="noopener noreferrer"&gt;Yarn&lt;/a&gt; as the package manager.&lt;/p&gt;

&lt;p&gt;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;yarn create next-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When it prompts you to fill in the app name, give it the value “web-vitals-next”. Once the creation is finished, open your project with VS Code and run the build command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, run the project with the &lt;code&gt;yarn dev&lt;/code&gt; command. It’ll be available, by default, at &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Introducing Web Vitals to your Next.js app is very simple. You just need to make sure you have a &lt;a href="https://nextjs.org/docs/advanced-features/custom-app" rel="noopener noreferrer"&gt;custom App&lt;/a&gt; component (which our yarn creation command already did) and add the following function to your &lt;em&gt;pages/_app.js&lt;/em&gt; (or .ts, for TypeScript) 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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;reportWebVitals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;web-vital&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;metric&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;This function alone will execute whenever one of the Web Vitals metrics takes place. In the image below, you get to see how it works by logging to the browser’s console, the metrics as they happen:&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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage6.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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage6.png" alt="Browser console logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Web Vitals metrics logged in the browser’s console.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The structure of a metric object follows this pattern:&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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage7.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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage7.png" alt="Web Vitals metric object"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Web Vitals metric object.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It’s important to sort your logs by the &lt;code&gt;label&lt;/code&gt; value, especially because Next.js also logs some &lt;a href="https://nextjs.org/docs/advanced-features/measuring-performance#custom-metrics" rel="noopener noreferrer"&gt;custom metrics&lt;/a&gt; that you may not need.&lt;/p&gt;

&lt;p&gt;However, metrics in the browser’s console are not useful. We need to send them to an analytics platform so they can be processed and digested to generate real-time and accountable information.&lt;/p&gt;

&lt;p&gt;If you use Google Analytics as such tool, sending the data would be as simple as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;reportWebVitals&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;ga&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;send&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;event&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;eventCategory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;web-vital&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;Web Vitals&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;Next.js custom metric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;eventAction&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="na"&gt;eventValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CLS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;value&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;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// values must be integers&lt;/span&gt;
    &lt;span class="na"&gt;eventLabel&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;// id unique to current page load&lt;/span&gt;
    &lt;span class="na"&gt;nonInteraction&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;span class="c1"&gt;// avoids affecting bounce rate.&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;h2&gt;
  
  
  Sending Metrics to AppSignal
&lt;/h2&gt;

&lt;p&gt;To have a better view of the metrics, let’s take our example to send Web Vitals metrics to AppSignal dashboards as shown 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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage8.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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2020-09%2Fimage8.png" alt="AppSignal dashboards"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pushing metrics to AppSignal is super easy and fast!&lt;/p&gt;

&lt;p&gt;First, you need an &lt;a href="https://www.appsignal.com/" rel="noopener noreferrer"&gt;AppSignal account&lt;/a&gt; 一 you have a 30-days free trial. Once you’ve logged in, you’ll be redirected to the startup page, on which you get to choose the language of the app you desire AppSignal to be installed to.&lt;/p&gt;

&lt;p&gt;Select &lt;em&gt;Node.js.&lt;/em&gt; The page that follows will show the instructions to install AppSignal to your Node.js project. Keep the &lt;em&gt;APPSIGNAL_PUSH_API_KEY&lt;/em&gt; key, since it’s going to be important later on.&lt;/p&gt;

&lt;p&gt;Let’s move on to the app changes. You first need to add the AppSignal npm packages by running:&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 @appsignal/nodejs @appsignal/nextjs
yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pay attention to the log results and check if it finished successfully.&lt;/p&gt;

&lt;p&gt;Secondly, AppSignal integration doesn’t work with &lt;a href="https://nextjs.org/docs/api-reference/cli" rel="noopener noreferrer"&gt;Next CLI&lt;/a&gt;, which is the tool that our example app was built with. That means that we have to create our own &lt;a href="https://nextjs.org/docs/advanced-features/custom-server" rel="noopener noreferrer"&gt;custom server script&lt;/a&gt; file and start the application through it.&lt;/p&gt;

&lt;p&gt;Go ahead and create a new file called &lt;em&gt;server.js&lt;/em&gt; into the app’s root folder. This is the content it must have:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Appsignal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@appsignal/nodejs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&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;appsignal&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;Appsignal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;active&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;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;web-vitals-next&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PUT_YOUR_KEY_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;// &amp;lt;&amp;lt;-- Change this!!&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getRequestHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;EXPERIMENTAL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getWebVitalsHandler&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@appsignal/nextjs&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&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;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next&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;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&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="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&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;dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&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;next&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;dev&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;handle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getRequestHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appsignal&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;vitals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getWebVitalsHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appsignal&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;prepare&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&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;// Be sure to pass `true` as the second argument to `url.parse`.&lt;/span&gt;
    &lt;span class="c1"&gt;// This tells it to parse the query portion of the URL.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsedUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&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;url&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parsedUrl&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;pathname&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/__appsignal-web-vitals&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;vitals&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="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="nf"&gt;handle&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;parsedUrl&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="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="nx"&gt;err&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="k"&gt;throw&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;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="s2"&gt;&amp;gt; Ready on http://localhost: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;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Attention: Don’t forget to change the &lt;code&gt;apiKey&lt;/code&gt; in the code listing to yours.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Note that this is creating a new server with custom settings, but it’s still Next-only based. You can also configure the whole thing with Express if you want to.&lt;/p&gt;

&lt;p&gt;Special attention to the &lt;code&gt;Appsignal&lt;/code&gt; object, which is where AppSignal’s Node.js library tries to connect to the remote API for the first time. If anything goes wrong, this is the place where you should inspect errors.&lt;/p&gt;

&lt;p&gt;We’re setting up the app with minimal configs, but you can find a list with all the available config options &lt;a href="https://docs.appsignal.com/nodejs/configuration" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note also that, within the server setup, we’re checking if the pathname equals to &lt;em&gt;/&lt;/em&gt;&lt;em&gt;appsignal-web-vitals&lt;/em&gt;. This is necessary because the feature works by providing a handler function, which is designed to be used as an endpoint in your application.&lt;/p&gt;

&lt;p&gt;This handler function, in turn, is the &lt;code&gt;reportWebVitals&lt;/code&gt; we’ve seen before. Here’s its new content:&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;reportWebVitals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;web-vital&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;metric&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metric&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/__appsignal-web-vitals&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Use `navigator.sendBeacon()` if available, falling back to `fetch()`.&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendBeacon&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendBeacon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&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="o"&gt;||&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&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="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;keepalive&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you may remove the console logging if you don’t want to see the logs in the browser.&lt;/p&gt;

&lt;p&gt;The implementation makes use of the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon" rel="noopener noreferrer"&gt;&lt;code&gt;sendBeacon&lt;/code&gt;&lt;/a&gt; function with a fallback to a POST request to the AppSignal API. As simple as that!&lt;/p&gt;

&lt;p&gt;Finally, let’s go to the &lt;em&gt;package.json&lt;/em&gt; file and change our generated scripts:&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;"scripts"&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;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node server.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NODE_ENV=production node server.js"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, start the project locally via &lt;code&gt;yarn dev&lt;/code&gt; command, get back to the AppSignal setup wizard and click &lt;em&gt;Next step&lt;/em&gt;. After that, another page will appear with a 60s timer waiting for the requests to arrive from your Next app.&lt;/p&gt;

&lt;p&gt;Always good to remember that the usage of this feature is EXPERIMENTAL and may change or be deprecated in future releases. So, be aware!&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In terms of web quality measuring, Web Vitals represent the best of what’s available in the community. It’s Google’s child and has been largely embraced by the community as a trustworthy metric system to check whether your apps are good enough or still need more work.&lt;/p&gt;

&lt;p&gt;Obviously, it’s continuously evolving, that’s why closely watching the &lt;a href="https://web.dev/vitals/" rel="noopener noreferrer"&gt;official docs&lt;/a&gt; and repo is always recommended.&lt;/p&gt;

&lt;p&gt;Apart from that, since it's not bulletproof, be sure to make other tests and/or check out the results over different platforms to ensure that the quality is what you expected. Good luck!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S. If you liked this post, &lt;a href="https://blog.appsignal.com/javascript-sorcery" rel="noopener noreferrer"&gt;subscribe to our new JavaScript Sorcery list&lt;/a&gt; for a monthly deep dive into more magical JavaScript tips and tricks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.P.S. If you'd love an all-in-one APM for Node or you're already familiar with AppSignal, go and &lt;a href="https://www.appsignal.com/nodejs" rel="noopener noreferrer"&gt;check out AppSignal for Node.js&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>nextjs</category>
      <category>javascript</category>
      <category>performance</category>
    </item>
    <item>
      <title>Security Best Practices for Node.js</title>
      <dc:creator>Diogo Souza</dc:creator>
      <pubDate>Thu, 03 Sep 2020 15:30:31 +0000</pubDate>
      <link>https://dev.to/appsignal/security-best-practices-for-node-js-5f4i</link>
      <guid>https://dev.to/appsignal/security-best-practices-for-node-js-5f4i</guid>
      <description>&lt;p&gt;Because a lot of systems are connected to the web these days (or, at least, communicate/integrate with it at some level), companies are giving more and more attention to web security.&lt;/p&gt;

&lt;p&gt;Web security usually comes to public attention when certain events reach the news, for example, security leakages, hacker activities, and/or data-stealing over big companies, some of them really large (like Google, LinkedIn, etc.).&lt;/p&gt;

&lt;p&gt;Apart from that showbiz world of giant players that most of us are probably not working for, implementing security on your systems is not only important but impressively underestimated or even forgotten by many devs.&lt;/p&gt;

&lt;p&gt;Setup, best practices, performance, testing, and metrics are probably things that you consider in your daily programming life. However, unfortunately, that’s not the same for security best practices.&lt;/p&gt;

&lt;p&gt;And it’s not due to warnings. If you work in the open-source universe, within GitHub’s protective arms, chances are that you’ve faced some of its &lt;a href="https://docs.github.com/en/github/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies"&gt;alerts&lt;/a&gt; for vulnerable dependencies. The code community platform is becoming increasingly good – as well as worried – at detecting vulnerabilities in thousands of different libs across many different languages.&lt;/p&gt;

&lt;p&gt;Today, it’s way more accessible for small and medium companies to afford security tools (or perhaps whole platforms) to assist their developers with the gaps in their code and apps.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👋 AppSignal now supports Node.js as well. We've added a whole array of integrations i.e. support more things to be instrumented right out-of-the-box. We already had support for Next.js, PostgreSQL, Redis, and Express and just added Apollo. &lt;a href="https://www.appsignal.com/nodejs"&gt;Learn more about AppSignal for Node.js&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nevertheless, whether you use or don't use such security platforms, understanding and being aware of the security threats that your apps may suffer from and fighting against them through simple (but powerful) best practices is the main goal of this article.&lt;/p&gt;

&lt;p&gt;Actually, we’ll pick Node.js as the analysis guinea pig, but many of the items here perfectly align with other platforms as well.&lt;/p&gt;

&lt;p&gt;As a matter of reference, the &lt;a href="https://owasp.org/"&gt;OWASP&lt;/a&gt; (&lt;em&gt;Open Web Application Security Project&lt;/em&gt;) will guide us through its &lt;a href="https://owasp.org/www-project-top-ten/"&gt;Top Ten&lt;/a&gt; most critical security risks for web applications, in general. It is a consensus board created out of the analysis of its broad list of members. Let’s face it under the light of Node then.&lt;/p&gt;

&lt;h2&gt;
  
  
  Injection Attacks
&lt;/h2&gt;

&lt;p&gt;One of the most famous threats to web applications relates to the possibility of an attacker sending pieces of SQL to your back-end code.&lt;/p&gt;

&lt;p&gt;It usually happens when developers concatenate important SQL statements directly into their database layers, like so:&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;// "id" comes directly from the request's params&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;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;select * from MyTable where id = &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&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;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;users&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;// return the users into the response&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 developer didn’t sanitize the input parameters arriving within the request, an attacker could pass more than a single integer id, like an SQL instruction that could retrieve sensitive information or even delete it (not to mention the importance of proper backup policies here).&lt;/p&gt;

&lt;p&gt;Most of the programming languages, and their respective ORM frameworks, provide ways to avoid SQL injection usually by parameterizing inputs into query statements that, before executing directly into the database, will be validated by the inner logic of your language libs machinery.&lt;/p&gt;

&lt;p&gt;In this case, it’s very important to know your language/framework closely in order to learn how they do this.&lt;/p&gt;

&lt;p&gt;If you make use of &lt;a href="https://sequelize.org/"&gt;Sequelize&lt;/a&gt;, for example, a simple way to do it would be:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;QueryTypes&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sequelize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sequelize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;select * from MyTable where id = :p1&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;replacements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;p1&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;// id comes from the request's param&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;QueryTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SELECT&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;h2&gt;
  
  
  Authentication Pitfalls
&lt;/h2&gt;

&lt;p&gt;Authentication is usually a part of the system that requires a lot of attention, especially if you make use of frameworks or tools that easily allow developers to expose sensitive user’s information.&lt;/p&gt;

&lt;p&gt;OWASP considers this item critical. Standards like &lt;a href="https://oauth.net/"&gt;OAuth&lt;/a&gt; (on its 2nd version now, working on the &lt;a href="https://oauth.net/3/"&gt;3rd&lt;/a&gt;) are constantly evolving in an attempt to embrace as much as possible the many different realities of the web world.&lt;/p&gt;

&lt;p&gt;Its implementation can be tricky, depending on your project’s scenarios or on how your company decides to customize the standard usage.&lt;/p&gt;

&lt;p&gt;If your team (and company) can afford to add big – and therefore, mature – players like &lt;a href="https://auth0.com/"&gt;Auth0&lt;/a&gt;, &lt;a href="https://aws.amazon.com/cognito/"&gt;Amazon Cognito&lt;/a&gt;, and &lt;a href="https://stackshare.io/auth0/alternatives"&gt;many others&lt;/a&gt; in the market to your projects, that would be halfway there.&lt;/p&gt;

&lt;p&gt;When it comes to &lt;a href="https://blog.logrocket.com/implementing-oauth-2-0-in-node-js/"&gt;implementing OAuth2&lt;/a&gt; in Node.js, there’s plenty of compliant and open source options that can help you with not starting from scratch. Like the famous &lt;a href="https://github.com/oauthjs/node-oauth2-server"&gt;node-oauth2-server&lt;/a&gt; module.&lt;/p&gt;

&lt;p&gt;Make sure to always refer to the official docs of whatever module or framework you’re adding to your projects (whether it's open source or paid). Plus, when adding security to your auth flows, never go with small and recent open-source projects (it’s too much of a critical part of the app to take that kind of risk).&lt;/p&gt;

&lt;h2&gt;
  
  
  Sensitive Data Exposure
&lt;/h2&gt;

&lt;p&gt;It’s important to define what sensitive data is. Depending on the type of project, it can vary. However, regardless of the app nature, things like credit card and document ids will always be sensitive, for sure.&lt;/p&gt;

&lt;p&gt;How is that information going to transit over to your system? Is it encrypted? No? Really?&lt;/p&gt;

&lt;p&gt;After you’ve separated what’s “&lt;strong&gt;really important&lt;/strong&gt;” from the rest, it’s time to decide what needs to be stored, and for how long.&lt;/p&gt;

&lt;p&gt;You’d be amazed at the number of apps out there that store sensitive information for no further use, or worse, without the user’s consent. That can easily break the laws of data privacy which, by the way, are different depending on the country your app is running on (another thing to worry about).&lt;/p&gt;

&lt;p&gt;Let’s go to the to-do (&lt;em&gt;aka&lt;/em&gt; must-to) list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Encrypt your sensitive data. Forget about MD5, your data deserves to be strongly protected under the right algorithms. So go for &lt;a href="https://www.npmjs.com/package/scrypt"&gt;Scrypt&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  Warn your users about how your application deals with sensitive info. You can periodically mail them with explaining infographics, pop up some informative modals when logging in, and yes, your terms of use must state this too.&lt;/li&gt;
&lt;li&gt;  Go for HTTPS. Period. Google won’t like you nowadays if you’re not.&lt;/li&gt;
&lt;li&gt;  If you can, go a bit further and do &lt;a href="https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security"&gt;HSTS&lt;/a&gt;. It is a policy mechanism that enhances your web security against the famous &lt;a href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack"&gt;man-in-the-middle&lt;/a&gt; attacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Setting HSTS in a Node app is as easy as:&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;hsts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hsts&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="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hsts&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;maxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15552000&lt;/span&gt;  &lt;span class="c1"&gt;// 180 days in seconds&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can fine-tune your settings by defining, for example, if subdomains should be included or not:&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hsts&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;maxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15552000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;includeSubDomains&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll need, obviously, the &lt;a href="https://www.npmjs.com/package/hsts"&gt;hsts&lt;/a&gt; npm package. Make sure to refer to its &lt;a href="https://helmetjs.github.io/docs/hsts/"&gt;official docs&lt;/a&gt; for more info.&lt;/p&gt;

&lt;h2&gt;
  
  
  Old XML External Entities (XXE)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing"&gt;XXE attacks&lt;/a&gt; occur by exploring the vulnerabilities that older XML processors have, in which they allow attackers to specify external entities and send them to applications that parse XML inputs.&lt;/p&gt;

&lt;p&gt;If the parser is weakly configured, the attacker could have access to sensitive information, confidential data like passwords in a server, among others.&lt;/p&gt;

&lt;p&gt;Consider, as an example, an XML-based Web Service that receives the following XML content as input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="ISO-8859-1"?&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;attacker@email.com&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
   ...
&lt;span class="nt"&gt;&amp;lt;/xml&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first sight, it looks just like all the other inputs you’ve seen so far. However, if your app that's hosted on a server is not prepared to deal with attacks, something like this could be sent over:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="ISO-8859-1"?&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE foo [
  &amp;lt;!ELEMENT foo ANY &amp;gt;&lt;/span&gt;
  &lt;span class="cp"&gt;&amp;lt;!ENTITY xxe SYSTEM "file:///c:/boot.ini" &amp;gt;&lt;/span&gt;]&amp;gt;
    &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;attacker@email.com&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    ...
  &lt;span class="nt"&gt;&amp;lt;foo&amp;gt;&lt;/span&gt;&lt;span class="ni"&gt;&amp;amp;xxe;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/foo&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/xml&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this would return in the response the &lt;em&gt;boot.ini&lt;/em&gt; file content.&lt;/p&gt;

&lt;p&gt;Another good example is if your app deals with uploading files. If, for example, you restrict it to only accepting some group of files, then XML-based formats like DOCX or the famous SVG for images could be accepted and carry on malicious code as well.&lt;/p&gt;

&lt;p&gt;The easiest way to prevent such attacks is by disabling your library’s parsing features. The &lt;a href="https://www.npmjs.com/package/node-libxml"&gt;node-libxml&lt;/a&gt; npm package, for instance, provides a bunch of functions to validate your DTD and helps you secure your apps against these attacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Broken Access Control
&lt;/h2&gt;

&lt;p&gt;This item is mostly related to how well-tested an application has been when it comes to user permissions to different areas (or URLs) of it.&lt;/p&gt;

&lt;p&gt;In other words, if you’re supposed to have restricted areas on the application, like an admin dashboard, for example, and ordinary users without a proper role can access it anyway, then you have an access vulnerability.&lt;/p&gt;

&lt;p&gt;It is easily correctable and doesn’t require any specific solution, you can go with whatever you’re using already. The only point is the attention to implement it correctly and cover it with proper tests that guarantee the coverage over new endpoints as well.&lt;/p&gt;

&lt;p&gt;Node provides plenty of libraries to help with that, as well as middleware to check for the current user’s permissions and you can also implement one on your own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Misconfiguration
&lt;/h2&gt;

&lt;p&gt;It’s common, in the early stages of an app’s life, to define three major environments (development – or stage, QA, and production) and leave the settings equal among them.&lt;/p&gt;

&lt;p&gt;This type of misconfiguration sometimes goes on for ages without being noticed and can lead to critical attacks, since the app is vulnerable considering that staging and QA configurations are weakly protected most of the time.&lt;/p&gt;

&lt;p&gt;When we talk about configurations, make sure to associate them to all types of dependencies (databases, external integrations, APIs, gateways, etc.).&lt;/p&gt;

&lt;p&gt;It’s fundamental to have well-defined setups, distinct and separated from each other. Also, consider storing your credentials (and sensitive setting’s data) in remote places apart from the project files.&lt;/p&gt;

&lt;p&gt;The cultural aspects of your company may take place here as well. If you use &lt;a href="https://www.splunk.com/"&gt;Splunk&lt;/a&gt;, for example, or any other logging tool, make sure to have policies (and ways to check that) that force the devs to not log sensitive data since Splunk can be way more easily accessed than the database that stores the same data.&lt;/p&gt;

&lt;p&gt;That reminds me of a time in a company in which the main database’s password went up to a public GitHub repo due to a developer that “innocently” copied one of the company’s repo to study at home. And don’t get me wrong... I’m not saying that the biggest error was his; it was not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Notorious XSS
&lt;/h2&gt;

&lt;p&gt;XSS is a notorious rebel. Even though it's insanely famous, everyday rush can easily make you forget about it.&lt;/p&gt;

&lt;p&gt;The problem here resembles SQL injection. You have an endpoint in your web app that receives a request and returns a response. Not a big deal. However, it becomes one when you concatenate the request data with the response without sanitizing it.&lt;/p&gt;

&lt;p&gt;A classic example would be:&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&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;/users&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;user&lt;/span&gt; &lt;span class="o"&gt;=&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;getUserById&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;query&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;span&amp;gt;Sorry, the user "&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;" was not found!&amp;lt;/span&amp;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="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;Guess what's going to happen when the client sends a request with the following &lt;em&gt;id&lt;/em&gt; param:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Uh&lt;/span&gt; &lt;span class="nx"&gt;la&lt;/span&gt; &lt;span class="nx"&gt;la&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s me! XSS!!)&amp;lt;/script&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For now, it’s just an innocent alert message, but we all know that an attacker would put a bit more of JavaScript code in there.&lt;/p&gt;

&lt;p&gt;Node’s &lt;a href="https://openbase.io/packages/top-nodejs-xss-libraries"&gt;full of options&lt;/a&gt; to address this issue by simply adding a new middleware. Pick one, implement it properly, and move on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insecure Deserialization
&lt;/h2&gt;

&lt;p&gt;This breach takes place mostly when applications accept serialized objects from untrusted sources that could be tampered with by attackers.&lt;/p&gt;

&lt;p&gt;Imagine, for example, that your Node web app communicates with the client and returns after the user has logged in, a serialized object to be persisted in a cookie that will work as the user's session, storing data like the user id and permissions.&lt;/p&gt;

&lt;p&gt;An attacker could then change the cookie object and give an admin role to himself, for example.&lt;/p&gt;

&lt;p&gt;Here’s where terms like &lt;a href="https://github.com/pillarjs/understanding-csrf"&gt;CSRF&lt;/a&gt; (&lt;em&gt;Cross-site Request Forgery&lt;/em&gt;) pop up. Basically, the server app generates a token (known as CSRF token) and sends it to the client in every request to be saved in a form’s hidden input.&lt;/p&gt;

&lt;p&gt;Every time the form is submitted it sends the token along and the server can check if it has changed or is absent. If that happens, the server will reject the request. In order to get this token, the attacker would have to make use of JavaScript code. If your app, however, doesn’t support &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"&gt;CORS&lt;/a&gt;, the attacker has his hands tied and the threat is eliminated.&lt;/p&gt;

&lt;p&gt;Again, Node has some great middleware packages to help you out, like the &lt;a href="https://github.com/expressjs/csurf"&gt;csurf&lt;/a&gt;, one of the most famous. Within less than 2 minutes, you’re safe and sound.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insufficient Logging &amp;amp; Monitoring
&lt;/h2&gt;

&lt;p&gt;This item speaks for itself. We’ve talked about Splunk before, but this is just the tip of the iceberg in terms of available options.&lt;/p&gt;

&lt;p&gt;Tons of different tools, plenty of them even integrating and talking to each other, provide the perfect layers to enhance your system’s protection, based on information.&lt;/p&gt;

&lt;p&gt;Information is crucial to analyze and detect possible invasions and vulnerabilities of your app. You can create lots of routines that execute based on some predefined behaviors of your system.&lt;/p&gt;

&lt;p&gt;The logs speak for what’s happening inside your app. So the monitoring represents the voice of it that’ll come at you whenever something wrong is detected.&lt;/p&gt;

&lt;p&gt;Here, we won’t talk about specific tools. It’s an open field and you can play with the sea of great solutions out there.&lt;/p&gt;

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

&lt;p&gt;We’ve taken a look at the &lt;a href="https://owasp.org/www-project-top-ten/"&gt;OWASP Top Ten&lt;/a&gt; Web Application Security Risks at the time of writing. But obviously, they’re not the only ones you should pay attention to.&lt;/p&gt;

&lt;p&gt;The list works as a compass for developers, especially beginners, to better understand how threats exist on the web and how they can affect your apps, even though you disbelieve someone would try to hack you.&lt;/p&gt;

&lt;p&gt;Remember, the bigger and important your applications are, the more susceptible to security breaches and bad-intended people they are.&lt;/p&gt;

&lt;p&gt;As further reading, I’d very much recommend a tour over the &lt;a href="https://owasp.org/"&gt;OWASP website&lt;/a&gt;, as well as at its &lt;a href="https://owasp.org/www-community/Source_Code_Analysis_Tools"&gt;Source Code Analysis Tools&lt;/a&gt; page. Good luck!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Diogo Souza has been passionate about clean code, software design and development for more than ten years. If he is not programming or writing about these things, you'll usually find him watching cartoons.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S. If you liked this post, &lt;a href="https://blog.appsignal.com/javascript-sorcery"&gt;subscribe to our new JavaScript Sorcery list&lt;/a&gt; for a monthly deep dive into more magical JavaScript tips and tricks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.P.S. If you'd love an all-in-one APM for Node or you're already familiar with AppSignal, go and &lt;a href="https://www.appsignal.com/nodejs"&gt;check out AppSignal for Node.js&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>security</category>
      <category>javascript</category>
    </item>
    <item>
      <title>A Deep Dive Into V8</title>
      <dc:creator>Diogo Souza</dc:creator>
      <pubDate>Thu, 16 Jul 2020 10:05:22 +0000</pubDate>
      <link>https://dev.to/appsignal/a-deep-dive-into-v8-3ioc</link>
      <guid>https://dev.to/appsignal/a-deep-dive-into-v8-3ioc</guid>
      <description>&lt;p&gt;A majority of front-end developers deal with this buzzword all the time: V8. A big part of its popularity is due to the fact that it led JavaScript to a new level of performance.&lt;/p&gt;

&lt;p&gt;Yes, V8 is very fast. But, how does it perform its magic and why is it so responsive?&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://v8.dev/"&gt;official docs&lt;/a&gt; state that “V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++. It is used in Chrome and Node.js, among others”.&lt;/p&gt;

&lt;p&gt;In other words, V8 is a software developed in C++ that translates JavaScript into executable code i.e. machine code.&lt;/p&gt;

&lt;p&gt;In this epiphanic moment, we start seeing things more clearly. Both Google Chrome and Node.js are just bridges to transport the JavaScript code to its final destination: machine code running in that specific machine.&lt;/p&gt;

&lt;p&gt;Another important role in V8's performance play belongs to its generational and super accurate Garbage Collector. It was optimized to collect the objects that JavaScript no longer needs, using low memory.&lt;/p&gt;

&lt;p&gt;Besides that, V8 counts on a set of other tools and features to improve some inherent JavaScript functionalities that historically, make the language slow (like its dynamic nature, for example).&lt;/p&gt;

&lt;p&gt;In this article, we'll explore those tools (Ignition and TurboFan) and features in more detail. More than that, we'll cover the basics of V8's internal functioning, compilation and garbage collection processes, single-threaded nature, and more.&lt;/p&gt;

&lt;p&gt;Let's go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting With the Basics
&lt;/h2&gt;

&lt;p&gt;How does machine code work? Machine code, in short, is a bunch of very low-level instructions that execute in specific parts of the machine’s memory.&lt;/p&gt;

&lt;p&gt;The process of generating it, using C++ language as a reference, is similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vUU0ACNx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vUU0ACNx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure01.png" alt="Compilation process"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before going any further, it’s important to point out that this is a compilation process, which is different from the JavaScript interpretation process. While the compiler, in fact, generates a whole program at the end of the process, the interpreter works as a program itself that does the job by reading the instructions (usually as scripts, like the JavaScript scripts) and translating them into executable commands.&lt;/p&gt;

&lt;p&gt;The interpreting process can happen both on-the-fly (on which the interpreter parses and runs only the current command) or fully-parsed (that’s when the interpreter first translates the script entirely before proceeding with the respective machine instructions).&lt;/p&gt;

&lt;p&gt;Back to the figure, the compilation process usually starts with the source code, as you know. You implement the code, save it and run. The running process, in turn, starts at the compiler. The compiler is a program, like any other, running on your machine. It then goes through all the code and generates object files. Those files are the machine code. They’re optimized code that runs in that specific machine, that’s why you’ll have to use a specific compiler when you move from one OS to another.&lt;/p&gt;

&lt;p&gt;But you can’t execute separate object files, you need to combine them into a single file, the well-known &lt;em&gt;.exe&lt;/em&gt; file (the executable file). That’s the linker’s job.&lt;/p&gt;

&lt;p&gt;Finally, the loader is the agent responsible for transferring the code inside of that &lt;em&gt;exe&lt;/em&gt; file to the virtual memory of your OS. It is basically a transporter. And here, you have your program finally up and running.&lt;/p&gt;

&lt;p&gt;Sounds like a lengthy process, isn't it?&lt;/p&gt;

&lt;p&gt;Most of the time (unless you’re a developer working with Assembly in a bank’s mainframe) you’ll spend your time programming in high-level languages: Java, C#, Ruby, JavaScript, etc.&lt;/p&gt;

&lt;p&gt;The higher the language is, the slower it is. That’s why C and C++ are so much faster, they’re very close to the machine code language: the assembly language.&lt;/p&gt;

&lt;p&gt;One of the main benefits of V8, apart from the performance, is the possibility of going beyond the &lt;a href="https://www.ecma-international.org/publications/standards/Ecma-262.htm"&gt;ECMAScript standards&lt;/a&gt; and understand, for example, C++ as well:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S9TrF1zA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S9TrF1zA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure02.png" alt="JavaScript + V8 C++"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JavaScript is restricted to ECMAScript. And V8, in order to exist, must be compliant but not restricted to it.&lt;/p&gt;

&lt;p&gt;Having the ability to incorporate C++ features into V8 is great. Since C++ has evolved to be very good at specificities of the OS — like file manipulation and memory/threads handling — having all this power in JavaScript's hands is very useful.&lt;/p&gt;

&lt;p&gt;If you think about it, Node.js itself was born in a similar way. It followed a similar path to V8’s plus the server and networking capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Single-Threaded
&lt;/h2&gt;

&lt;p&gt;If you’re a Node developer, you’ll be familiar with V8’s single-threaded nature. Each JavaScript execution context is directly proportional to one thread.&lt;/p&gt;

&lt;p&gt;Of course, V8 manages the OS threading mechanism behind the scenes. It works with more than one thread because it’s a complex software and executes lots of stuff at the same time.&lt;/p&gt;

&lt;p&gt;We have the main thread that executes the code, another one to compile the code (yes, we can’t stop the execution every time new code has to be compiled), some others to deal with garbage collection, and so on.&lt;/p&gt;

&lt;p&gt;However, V8 creates an environment of a single thread for each of JavaScript’s execution context. The rest is kept under its control.&lt;/p&gt;

&lt;p&gt;Imagine the stack of function calls your JavaScript code is supposed to make. JavaScript works by stacking one function on top of another, following the order by which each one was inserted/called. Before reaching each function’s content, we can’t know if it calls other functions. If and when that happens, then the called functions will be placed right after the caller in the stack.&lt;/p&gt;

&lt;p&gt;When it comes to callbacks, for example, they are placed at the end of the pile.&lt;/p&gt;

&lt;p&gt;The management of this stack organization and the memory the process will need is one of the main tasks of V8.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ignition and TurboFan
&lt;/h2&gt;

&lt;p&gt;Since version 5.9, &lt;a href="https://v8.dev/blog/launching-ignition-and-turbofan"&gt;released in May 2017&lt;/a&gt;, V8 comes with a new JavaScript execution pipeline that was built on top of &lt;a href="https://v8.dev/docs/ignition"&gt;Ignition&lt;/a&gt;, V8’s interpreter. It also includes a newer and better optimizing compiler ⁠— &lt;a href="https://v8.dev/docs/turbofan"&gt;TurboFan&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These changes were totally focused on the overall performance and the difficulties Google developers were facing when adapting the engine to all the quick and considerable changes that the JavaScript universe brought up.&lt;/p&gt;

&lt;p&gt;From the very beginning of the project, V8 maintainers were always worried about finding a good way to improve V8’s performance at the same pace JavaScript was evolving.&lt;/p&gt;

&lt;p&gt;Now we can see huge improvements when running the new engine against the biggest benchmarks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EE7RgZug--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EE7RgZug--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure03.png" alt="TurboFan and Ignition performance metrics"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Source: &lt;a href="https://v8.dev/blog/launching-ignition-and-turbofan"&gt;https://v8.dev/blog/launching-ignition-and-turbofan&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can read more about Ignition and TurboFan &lt;a href="https://v8.dev/docs/ignition"&gt;here&lt;/a&gt; and &lt;a href="https://v8.dev/docs/turbofan"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hidden Classes
&lt;/h2&gt;

&lt;p&gt;This is another one of V8's magic tricks. JavaScript is a dynamic language. That means that new properties can be added, replaced and removed during execution time. This is not possible with languages like Java, for example, in which everything (classes, method, objects and variables) must be defined before program execution and can’t be dynamically changed after the app starts.&lt;/p&gt;

&lt;p&gt;Because of its particular nature, the JavaScript interpreters usually perform a dictionary lookup based on a hash function to know exactly where this variable or that object is allocated in memory.&lt;/p&gt;

&lt;p&gt;This costs a lot to the final process. In other languages, when objects are created, they receive an address (a pointer) as one of their implicit attributes. This way, we know exactly where they’re placed in memory and how much space to allocate.&lt;/p&gt;

&lt;p&gt;With JavaScript, that’s impossible since we can’t map what doesn't exist yet. That’s where the hidden classes reign.&lt;/p&gt;

&lt;p&gt;Hidden classes are almost the same as they are in Java: static and fixed classes with a unique address to locate them. However, rather than doing it before program execution, V8 will do it during runtime, every time we have a “dynamic change” in the object’s structure.&lt;/p&gt;

&lt;p&gt;Let’s look at an example to clarify things. Consider the following code snippet:&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;function&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;this&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;name&lt;/span&gt;
   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt;
   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within JavaScript’s prototype-based nature, every time we instantiate a new &lt;code&gt;User&lt;/code&gt; object, let’s say:&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;var&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John May&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;+1 (555) 555-1234&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;123 3rd Ave&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;Then V8 creates a new hidden class. Let’s call it &lt;code&gt;_User0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z3JarHj7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z3JarHj7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure04.png" alt="Creating first hidden class"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each object has a reference to its class representation in memory. It’s the class pointer. At this point, since we just instantiated a new object, only a hidden class was created in memory. It is empty for now.&lt;/p&gt;

&lt;p&gt;When you execute the first line of code in this function, a new hidden class is going to be created based on the previous one, this time &lt;code&gt;_User1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9YqCaOKE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9YqCaOKE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure05.png" alt="Creating second hidden class"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is basically the memory address of a &lt;code&gt;User&lt;/code&gt; that has a &lt;code&gt;name&lt;/code&gt; property. In our example, we’re not using users with just a name as an attribute, but every time you do it, this is the hidden class V8 will load as reference.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;name&lt;/code&gt; property is added to the offset 0 of your memory buffer, which means this will be considered our first attribute in the final order.&lt;/p&gt;

&lt;p&gt;V8 will also add a transition value to the &lt;code&gt;_User0&lt;/code&gt; hidden class. This helps the interpreter to understand that every time a &lt;code&gt;name&lt;/code&gt; property is added to a &lt;code&gt;User&lt;/code&gt; object, the transition from &lt;code&gt;_User0&lt;/code&gt; to &lt;code&gt;_User1&lt;/code&gt; must be addressed.&lt;/p&gt;

&lt;p&gt;When the second line in the function is called, the same process happens again and a new hidden class is created:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tOSgZuwX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tOSgZuwX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-07/Figure06.png" alt="Creating third hidden class"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that the hidden classes keep track of the stack. One hidden class leads to another one in a chain maintained by the transition values.&lt;/p&gt;

&lt;p&gt;The order in which the properties are added determines how many hidden classes V8 is going to create. If you change the order of the lines in the code snippet we’ve created, different hidden classes will be created as well. That’s why some developers try to maintain the order to reuse hidden classes and therefore, reduce the overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inline Caching
&lt;/h2&gt;

&lt;p&gt;This is a term very common in the JIT (&lt;em&gt;Just In Time&lt;/em&gt;) compilers world. And it connects directly with the concept of hidden classes.&lt;/p&gt;

&lt;p&gt;Every time you call a function passing an object as a parameter, for example, V8 will take a look at this action and think: “Hmm, this object was successfully passed twice or more as a param to this function… why not store it in my cache for future calls rather than perform the whole time-consuming-hidden-class-validation process again?”&lt;/p&gt;

&lt;p&gt;Let’s recap our last example:&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;function&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Hidden class _User0&lt;/span&gt;
   &lt;span class="k"&gt;this&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;name&lt;/span&gt; &lt;span class="c1"&gt;// Hidden class _User1&lt;/span&gt;
   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt; &lt;span class="c1"&gt;// Hidden class _User2&lt;/span&gt;
   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="c1"&gt;// Hidden class _User3&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After sending this &lt;code&gt;User&lt;/code&gt; object twice instantiated with any values as a parameter to a function, V8 will jump the hidden class lookup and go directly to the offset’s properties. This is much faster.&lt;/p&gt;

&lt;p&gt;However, remember that if you change the order of any attribute assignment in the function, it will result in different hidden classes, so V8 won’t be able to make use of the inline caching feature.&lt;/p&gt;

&lt;p&gt;This is a great example to show that developers shouldn’t avoid getting to know the engine more intimately. On the contrary, having such knowledge will help your code perform better.&lt;/p&gt;

&lt;h2&gt;
  
  
  Garbage Collecting
&lt;/h2&gt;

&lt;p&gt;Do you remember that we mentioned V8 collects memory garbage in a different thread? So, this helps a lot, since our program execution won’t get affected.&lt;/p&gt;

&lt;p&gt;V8 uses the well-known strategy of “&lt;a href="https://en.wikipedia.org/wiki/Tracing_garbage_collection#Copying_vs._mark-and-sweep_vs._mark-and-don't-sweep"&gt;mark-and-sweep&lt;/a&gt;” to collect dead and old objects in memory. In this strategy, the phase where the GC scans memory objects to “mark” them for collection is a bit slow, because it pauses execution in order to achieve it.&lt;/p&gt;

&lt;p&gt;However, V8 does it incrementally, i.e., for each GC stop, V8 tries to mark as many objects as possible. It makes everything faster because there’s no need to stop the entire execution until the collection finishes. In large applications, the performance improvement makes a lot of difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Continuous Ride
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed this piece. The goal was to clarify a bit on V8's structural details, which are at many times misunderstood or ignored.&lt;/p&gt;

&lt;p&gt;The whole thing is naturally complex. And it’s constantly evolving. But these are pretty much the core concepts.&lt;/p&gt;

&lt;p&gt;At the time of writing this article, the &lt;a href="https://github.com/v8/v8"&gt;GitHub repo&lt;/a&gt; counts 15.3k stars and 2.9k forks. You too can fork the open source code and change the V8 engine as you please. Add your own custom C++ instructions, change the way the hidden classes are dealt with, use your imagination.&lt;/p&gt;

&lt;p&gt;But first, don’t forget to give a good read over the &lt;a href="https://v8.dev/docs"&gt;official docs&lt;/a&gt;. Good reading!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S. If you liked this post, &lt;a href="https://blog.appsignal.com/javascript-sorcery"&gt;subscribe to our new JavaScript Sorcery list&lt;/a&gt; for a monthly deep dive into more magical JavaScript tips and tricks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.P.S. If you'd love an all-in-one APM for Node or you're already familiar with AppSignal, go and &lt;a href="https://appsignal.com/nodejs"&gt;check out AppSignal for Node.js&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Diogo Souza has been passionate about clean code, software design and development for more than ten years. If he is not programming or writing about these things, you'll usually find him watching cartoons.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building APIs With GraphQL in Your Node Application</title>
      <dc:creator>Diogo Souza</dc:creator>
      <pubDate>Wed, 24 Jun 2020 15:04:31 +0000</pubDate>
      <link>https://dev.to/appsignal/building-apis-with-graphql-in-your-node-application-118c</link>
      <guid>https://dev.to/appsignal/building-apis-with-graphql-in-your-node-application-118c</guid>
      <description>&lt;p&gt;REST has reigned for a long time in the world of web services. It's easy to implement, allows standardization through RESTful patterns and has lots of libraries that support and facilitate its development. Then came GraphQL, the famous query language for APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s GraphQL
&lt;/h2&gt;

&lt;p&gt;To better understand GraphQL, we need to look at what defines it. GraphQL was created to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;declarative&lt;/strong&gt; — meaning, you should have the power to choose the data that you want. In other words, you &lt;em&gt;query&lt;/em&gt; (request for) some data, defining exactly what you want to get (that is where the &lt;em&gt;schema&lt;/em&gt; comes in).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;compositional&lt;/strong&gt; — just like it is in many programming language objects, you can have one field inheriting from another or inside another. Or from both, if you prefer.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;strongly-typed&lt;/strong&gt; — once a field has its type defined, that’s it—a different type isn't allowed.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;self-documented&lt;/strong&gt; — the schema, by itself, offers great documentation (with data types, structure, queries and mutations, etc.).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;less verbose&lt;/strong&gt; — we only get what we asked, which greatly differs from REST, which gives you everything (which isn't very efficient, especially if this everything means a lot of unnecessary data).&lt;/li&gt;
&lt;li&gt;  among &lt;a href="https://www.howtographql.com/basics/1-graphql-is-the-better-rest/"&gt;others&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GraphQL is a whole new paradigm. It brings to light the discussion of whether your APIs should have organized and well-structured request and response data in the same way we have when programming data structures in our back-end applications.&lt;/p&gt;

&lt;p&gt;The more the number of points discussed above that your API lacks, the more of an indicator that it could benefit from GraphQL. But you don’t have to abruptly migrate to it. Some developers start slowly by creating and exposing some endpoints and asking the clients to consume them. In that way, they gather more insight from both sides that determine if that’s the right path to take.&lt;/p&gt;

&lt;p&gt;When it comes to the Node.js universe, we have a bunch of useful tools to help out. &lt;a href="https://github.com/graphql/express-graphql"&gt;express-graphql&lt;/a&gt;, for example, is one of the popular server middlewares for integrating GraphQL with Node.js. &lt;a href="https://www.apollographql.com/docs/"&gt;Apollo&lt;/a&gt; is a piece of cake in terms of GraphQL APIs development. It embraces some of the downsides of &lt;em&gt;express-graphql&lt;/em&gt;, like the easy enabling of &lt;a href="https://www.apollographql.com/docs/graphql-tools/"&gt;graphql-tools&lt;/a&gt; and its patterns. We’ll see more on this later.&lt;/p&gt;

&lt;p&gt;Let’s go to some practical stuff. Nothing better than seeing in action how GraphQL fits into a common API example. For this, we’ll be creating a complete API to access some beer data.&lt;/p&gt;

&lt;p&gt;First, our API example will enable the registration, login and authentication of users. This way, we can ensure it's secure and unauthorized users can't see our favorite beer list.&lt;/p&gt;

&lt;p&gt;Then, we’ll dive into the construction of our API operations, set up a Postgres database to store the credentials and tokens, as well as test everything out.&lt;/p&gt;

&lt;p&gt;After we finish, we can celebrate with a beer from our list. So let’s get started.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did you know that AppSignal launched the support for Node applications? 🎉 We'll be rolling out a whole array of integrations one by one in the coming weeks. &lt;a href="https://docs.appsignal.com/nodejs/"&gt;Check out the docs and learn how to add your Node app to AppSignal&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Setting Up Our Project
&lt;/h2&gt;

&lt;p&gt;The example we’re about to develop expects that you have &lt;a href="https://nodejs.org/en/"&gt;Node.js&lt;/a&gt; installed. Make sure that it's at least version 8.0.&lt;/p&gt;

&lt;p&gt;Next, select a folder of your preference and run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm i apollo-server-express bcrypt express express-jwt graphql jsonwebtoken pg pg-hstore sequelize
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; sequelize-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They initialize our Node project with default settings, install the npm dependencies required for the GraphQL + Apollo example, and install the &lt;a href="https://github.com/sequelize/cli"&gt;Sequelize CLI Tool&lt;/a&gt;, respectively.&lt;/p&gt;

&lt;p&gt;Regarding the dependencies, we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/apollographql/apollo-server/tree/master/packages/apollo-server-express"&gt;apollo-server-express&lt;/a&gt;: provides direct connection between Express and Apollo GraphQL server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.npmjs.com/package/graphql"&gt;graphql&lt;/a&gt;: the implementation &lt;em&gt;per se&lt;/em&gt; of GraphQL in JavaScript.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.npmjs.com/package/bcrypt"&gt;bcrypt&lt;/a&gt;: it’ll be used to hash our passwords.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.npmjs.com/package/express"&gt;express&lt;/a&gt; and &lt;a href="https://www.npmjs.com/package/express-jwt"&gt;express-jwt&lt;/a&gt;: the Express framework itself along with the middleware for validating &lt;a href="https://jwt.io/"&gt;JWT&lt;/a&gt; (JSON Web Tokens) via the &lt;a href="https://github.com/auth0/node-jsonwebtoken/"&gt;jsonwebtoken&lt;/a&gt; module. There are a bunch of ways of dealing with the authentication process, but in this article, we’ll make use of JWT bearer tokens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.npmjs.com/package/pg"&gt;pg&lt;/a&gt; and &lt;a href="https://www.npmjs.com/package/pg-hstore"&gt;pg-hstore&lt;/a&gt;: the client for Postgres and the serializer/deserializer of JSON to hstore format (and vice versa).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.npmjs.com/package/sequelize"&gt;sequelize&lt;/a&gt;: the Node.js ORM for Postgres (among other databases) that we’ll use to facilitate the job of communicating with the database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that the Sequelize CLI tool had to be installed globally, otherwise, it wouldn’t be available at any command line interface. As its first command, let’s run the one that will initialize our Node project as an ORM one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sequelize init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will create some folders related to the ORM framework, like &lt;code&gt;models&lt;/code&gt;, &lt;code&gt;config&lt;/code&gt; and &lt;code&gt;migrations&lt;/code&gt; (since the framework also handles the migration of our databases).&lt;/p&gt;

&lt;p&gt;Now, let’s move on to the database related configs. First of all, we need a real Postgres database. If you still don’t have Postgres installed, then &lt;a href="https://www.postgresql.org/download/"&gt;go ahead&lt;/a&gt;. As a GUI tool for managing the database, we’ll use &lt;a href="https://www.pgadmin.org/"&gt;pgAdmin&lt;/a&gt;. We'll use the web GUI that comes with it.&lt;/p&gt;

&lt;p&gt;Next, we’ll create our example’s database. For this, access the web pgAdmin window and create it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6eLZGyft--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6eLZGyft--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure01.png" alt="Creating the database"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, go back to the project and update the content of &lt;code&gt;config/config.json&lt;/code&gt; as shown:&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;"development"&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;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"database"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"appsignal_graphql_db"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dialect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"operatorsAliases"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’re only showing the &lt;code&gt;development&lt;/code&gt; section since it’s the only one we’ll be dealing with in the article. However, make sure to update the other related ones as well before deploying your app to production.&lt;/p&gt;

&lt;p&gt;Next, let’s 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;sequelize model:generate &lt;span class="nt"&gt;--name&lt;/span&gt; User &lt;span class="nt"&gt;--attributes&lt;/span&gt; login:string,password:string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is another command from Sequelize framework that creates a new model in the project—the &lt;code&gt;user&lt;/code&gt; model, to be exact. This model will be important to our authentication structure. Go ahead and take a look at what's been generated in the project.&lt;/p&gt;

&lt;p&gt;For now, we’ll only create two fields: &lt;code&gt;login&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt;. But feel free to add any other fields you judge important to your design.&lt;/p&gt;

&lt;p&gt;You may also notice a new file created under the &lt;code&gt;migrations&lt;/code&gt; folder. There, we have the code for the &lt;code&gt;user&lt;/code&gt;’s table creation. In order to migrate the changes to the physical database, let’s run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sequelize db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can check the results in pgAdmin:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--708EneBQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--708EneBQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure02.png" alt="List of created tables"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may wonder where's the table that will store our beer data. We won’t store it in the database. The reason is that I’d like to demonstrate both paths: fetching from the db and from a static list in the JavaScript code.&lt;/p&gt;

&lt;p&gt;The project’s set. Now we can move on to implementing the authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Authenticate!
&lt;/h2&gt;

&lt;p&gt;The authentication must be implemented first because no other API method should be exposed without proper safety.&lt;/p&gt;

&lt;p&gt;Let’s start with the &lt;a href="https://graphql.org/learn/schema/"&gt;schema&lt;/a&gt;. The GraphQL schema is the recipe that the API clients must follow to properly use the API. It provides the exact hierarchy of field types, queries and mutations that your GraphQL API is able to execute. It is the contract of this client-server deal. With very strong and clear clauses, by the way.&lt;/p&gt;

&lt;p&gt;Our schema should be placed in the &lt;code&gt;schema.js&lt;/code&gt; file. So, create it and add the following content:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apollo-server-express&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;typeDefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="err"&gt;
    type User {
        id: Int!
        login: String!
    }

    type Beer {
        id: Int!
        name: String!
        brand: String
        price: Float
    }

    type Query {
        current: User
        beer(id: Int!): Beer
        beers(brand: String!): [Beer]
    }

    type Mutation {
        register(login: String!, password: String!): String
        login(login: String!, password: String!): String
    }
&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;typeDefs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details on how the schema is structured, please refer to &lt;a href="https://graphql.org/learn/schema/"&gt;this&lt;/a&gt;. In short, the &lt;a href="https://graphql.org/learn/queries/"&gt;&lt;code&gt;Query&lt;/code&gt;&lt;/a&gt; type is where we place the API methods that only return data, and the &lt;a href="https://graphql.org/learn/queries/"&gt;&lt;code&gt;Mutation&lt;/code&gt;&lt;/a&gt; type is where the methods that create or change data go.&lt;/p&gt;

&lt;p&gt;The other types are our own types, like &lt;code&gt;Beer&lt;/code&gt; and &lt;code&gt;User&lt;/code&gt;—the ones we create to reflect the JavaScript model that will be defined in the resolvers.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;gql&lt;/code&gt; tag is used to infer syntax highlighting to your editor plugin (like &lt;a href="https://prettier.io/"&gt;Prettier&lt;/a&gt;). It helps to keep the code organized.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.apollographql.com/docs/graphql-tools/resolvers/"&gt;resolvers&lt;/a&gt;, in turn, are the executors of the methods defined in the schema. While the schema worries about the fields, types and results of our API, the resolver takes all this as reference and implements the execution behind.&lt;/p&gt;

&lt;p&gt;Create a new file called &lt;code&gt;resolvers.js&lt;/code&gt; and add the following:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./models&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;bcrypt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bcrypt&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;jsonwebtoken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;JWT_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./constants&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;resolvers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&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="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="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&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;findOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&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="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="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sorry, you're not an authenticated user!&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="na"&gt;Mutation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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;login&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="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="nx"&gt;login&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hash&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="mi"&gt;10&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;jsonwebtoken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sign&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="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="na"&gt;login&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;login&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;JWT_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="s2"&gt;3m&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="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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;login&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="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;findOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="p"&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&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 user doesn't exist. Please, make sure to type the right 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;valid&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;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;compare&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="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="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;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You password is incorrect!&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;jsonwebtoken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sign&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="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="na"&gt;login&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;login&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;JWT_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="s2"&gt;1d&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="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resolvers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resolvers follow a pattern that’s inherently async because it’s Promise-based. Each operation must have the exact same signature as the one defined in the schema.&lt;/p&gt;

&lt;p&gt;Note that, for all query operations, we’re receiving a third argument: &lt;code&gt;user&lt;/code&gt;.  That one is going to be injected via &lt;code&gt;context&lt;/code&gt; (still to be configured in &lt;code&gt;index.js&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;jsonwebtoken&lt;/code&gt; dependency now takes over signing in the user according to the provided credentials and then generating a proper JWT token. This action will happen in both registration and login processes.&lt;/p&gt;

&lt;p&gt;Also, notice that an expiry time must be set for the token.&lt;/p&gt;

&lt;p&gt;Finally, there’s a &lt;code&gt;JWT_SECRET&lt;/code&gt; constant that we’re using as the value for &lt;code&gt;secretOrPrivateKey&lt;/code&gt;. That is the same secret we’ll use in the Express JWT middleware to check if the token is valid.&lt;/p&gt;

&lt;p&gt;This constant will be placed in a new file, called &lt;code&gt;constants.js&lt;/code&gt;. Here’s its content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sdlkfoish23@#$dfdsknj23SD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to change the value to a safe secret of yours. The only requirement is that it be long.&lt;/p&gt;

&lt;p&gt;Now, it’s time to configure our &lt;code&gt;index.js&lt;/code&gt; file. Substitute its content with the following:&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;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApolloServer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apollo-server-express&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;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express-jwt&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;typeDefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./schema&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;resolvers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./resolvers&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;JWT_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./constants&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="nx"&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;auth&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="na"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;credentialsRequired&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="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="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;auth&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;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ApolloServer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;typeDefs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;resolvers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;playground&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/graphql&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;context&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="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;user&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;user&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&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;headers&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="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;
            &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&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="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;applyMiddleware&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&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="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The server started on port &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;PORT&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 you use Express as your web server, this code may look familiar, except for the fact that we have two servers being set here.&lt;/p&gt;

&lt;p&gt;Express &lt;code&gt;app&lt;/code&gt; is going to be used as usual. We’re creating it, adding a middleware (&lt;code&gt;jwt&lt;/code&gt;) and starting it up. However, the &lt;code&gt;ApolloServer&lt;/code&gt; may come along to add the necessary GraphQL settings.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ApolloServer&lt;/code&gt; receives the schema (&lt;code&gt;typeDefs&lt;/code&gt;), &lt;code&gt;resolvers&lt;/code&gt;, &lt;code&gt;playground&lt;/code&gt; and a &lt;code&gt;context&lt;/code&gt; as arguments. The &lt;code&gt;playground&lt;/code&gt; property states which endpoint is going to redirect to &lt;a href="https://github.com/prisma-labs/graphql-playground"&gt;Prisma’s GraphQL Playground&lt;/a&gt; view. It is a built-in IDE to help us with testing of our GraphQL APIs.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;context&lt;/code&gt;, in turn, is an optional attribute that allows us to make quick conversions or validations prior to the GraphQL query/mutation executions. In our case, we’ll use it to extract the &lt;code&gt;user&lt;/code&gt; object from the request and make it available to our resolvers functions.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;server&lt;/code&gt; object is the one that applies the middleware, passing the &lt;code&gt;app&lt;/code&gt; object as a param.&lt;/p&gt;

&lt;p&gt;This is it. Let’s test it now. Run the application with 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;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, access the address &lt;code&gt;http://localhost:3000/graphql&lt;/code&gt; and the Playground view will show up.&lt;/p&gt;

&lt;p&gt;Our first test will be to register a new valid user. So, paste the following snippet into the query area and hit the “&lt;em&gt;Execute Query&lt;/em&gt;” button:&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;mutation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;john&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&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;john&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;A valid token will return as shown in the figure below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rQzMVyqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rQzMVyqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure03.png" alt="Registering a new user"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This token can already be used to access sensitive methods, like the &lt;code&gt;current&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you don’t provide a valid token as an HTTP header, the following error message will be prompted:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K8leudXE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K8leudXE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure04.png" alt="Error of not authenticated user"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To send it properly, click the “&lt;em&gt;HTTP HEADERS&lt;/em&gt;” tab at the bottom of the page and add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&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;Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NSwibG9naW4iOiJhcHBzaWduYWwiLCJpYXQiOjE1ODk5MTYyNTAsImV4cCI6MTU4OTkxNjQzMH0.bGDmyi3fmEaGf3FNuVBGY7ReqbK-LjD2GmhYCc8Ydts&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;Make sure to change the content after &lt;em&gt;Bearer&lt;/em&gt; to your version of the returned token. You will have a result similar to the figure below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oF4cGHcQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oF4cGHcQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure05.png" alt="Querying for the current user"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Obviously, if you already have a registered user, you can get the token by logging in via &lt;code&gt;login&lt;/code&gt; mutation:&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;mutation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;appsignal&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&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;appsignal&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;Once again, if one of your credentials is wrong, you’ll get the corresponding error message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Beer API
&lt;/h2&gt;

&lt;p&gt;For the sake of simplicity, we won’t create our Beer domain in the database. A single JS file will do the job. But I’d recommend that you migrate to our ORM model as well, making use of the knowledge you’ve got so far.&lt;/p&gt;

&lt;p&gt;Let’s start with this, then. This is the code for our &lt;code&gt;beers.js&lt;/code&gt; file (make sure to create it too):&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;var&lt;/span&gt; &lt;span class="nx"&gt;beersData&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Milwaukee's Best Light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MillerCoors&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;7.54&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="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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Miller Genuine Draft&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MillerCoors&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;6.04&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="na"&gt;id&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tecate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Heineken International&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;3.19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;beersData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feel free to add more data to it. I reserve the right of not knowing their correct prices.&lt;/p&gt;

&lt;p&gt;Once the main GraphQL setup structure has been set, adding new operations is quite easy. We just need to update the schema with the new operations (which we’ve already done) and add the corresponding functions into the &lt;code&gt;resolvers.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These are the new queries:&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;async&lt;/span&gt; &lt;span class="nx"&gt;beer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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;id&lt;/span&gt; &lt;span class="p"&gt;},&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="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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;beersData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;beer&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;beer&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;id&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="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sorry, you're not an authenticated user!&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="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;beers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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;brand&lt;/span&gt; &lt;span class="p"&gt;},&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="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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;beersData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;beer&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;beer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;brand&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sorry, you're not an authenticated user!&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;They’re simply filtering the data based on the given arguments. Don’t forget to import the &lt;code&gt;beersData&lt;/code&gt; array object:&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;beersData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./beers&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;Restart the server and refresh your Playground page. Note that we made those new queries safe too, so it means you’ll need to provide a valid token as header.&lt;/p&gt;

&lt;p&gt;This is the result of a query by brand:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HdxMhqZL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HdxMhqZL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure06.png" alt="Querying with query variables"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this call, we’re making use of &lt;a href="https://graphql.org/learn/queries/#variables"&gt;Query Variables&lt;/a&gt;. It allows you to call GraphQL queries by providing arguments dynamically. It’s very useful when you have other applications calling the GraphQL API, rather than just a single web IDE.&lt;/p&gt;

&lt;p&gt;This is the magic of GraphQL. It allows even more complicated query compositions. Imagine, for example, that we need to query two specific beers in one single call, filtering by a list of ids.&lt;/p&gt;

&lt;p&gt;Currently, we only have operations that filter by one single id or one single brand name. Not with a list of params.&lt;/p&gt;

&lt;p&gt;Instead of going directly to the implementation of a new query function that would do it, GraphQL provides a feature called &lt;a href="https://graphql.org/learn/queries/#fragments"&gt;Fragments&lt;/a&gt;. Look how our query would be:&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;query&lt;/span&gt; &lt;span class="nx"&gt;getBeers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$id1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$id2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Int&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="nl"&gt;beer1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;beer&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;$id1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;beerFields&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nl"&gt;beer2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;beer&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;$id2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;beerFields&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;fragment&lt;/span&gt; &lt;span class="nx"&gt;beerFields&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;Beer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;brand&lt;/span&gt;
  &lt;span class="nx"&gt;price&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this case, you’d need to provide the exact beer name for each of the results. The &lt;code&gt;fragment&lt;/code&gt; defines from where it’s going to inherit the fields, in our case, from the &lt;code&gt;Beer&lt;/code&gt; schema.&lt;/p&gt;

&lt;p&gt;Basically, fragments allow you to build a collection of fields and then include them in your queries. Don’t forget to feed the &lt;em&gt;Query Variables&lt;/em&gt; tab with the ids:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id1&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id2&lt;/span&gt;&lt;span class="dl"&gt;"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result will look like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wlVBoHrw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wlVBoHrw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.appsignal.com/images/blog/2020-06/figure07.png" alt="Fragment's query example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the &lt;em&gt;Authorization&lt;/em&gt; header is also there, hidden in the tab.&lt;/p&gt;

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

&lt;p&gt;It took a while, but we got to the end. Now you have a fully functional GraphQL API designed to provide queries and mutations and, more importantly, in a secure manner.&lt;/p&gt;

&lt;p&gt;There is a lot you can add here. Migrate the Beer’s model to store and fetch data directly from Postgres, insert some logs to understand better what’s going on, and place some mutations over the main model.&lt;/p&gt;

&lt;p&gt;Apollo + Express + GraphQL have proven to be a great fit for robust and fast web APIs. To learn more, please be sure to visit &lt;a href="http://graphql.org/learn/"&gt;http://graphql.org/learn/&lt;/a&gt;. Great resource!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S. If you liked this post, &lt;a href="https://blog.appsignal.com/javascript-sorcery"&gt;subscribe to our new JavaScript Sorcery list&lt;/a&gt; for a monthly deep dive into more magical JavaScript tips and tricks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.P.S. If you'd love an all-in-one APM for Node or you're already familiar with AppSignal, go and &lt;a href="https://docs.appsignal.com/nodejs/"&gt;check out AppSignal for Node.js&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Diogo Souza has been passionate about clean code, software design and development for more than ten years. If he is not programming or writing about these things, you'll usually find him watching cartoons.&lt;/em&gt;&lt;/p&gt;

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