<?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: reymon359</title>
    <description>The latest articles on DEV Community by reymon359 (@reymon359).</description>
    <link>https://dev.to/reymon359</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%2F333239%2F924fa85b-a73e-4b3e-8ee1-3c54450fc26e.jpg</url>
      <title>DEV Community: reymon359</title>
      <link>https://dev.to/reymon359</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/reymon359"/>
    <language>en</language>
    <item>
      <title>Managing the infrastructure of a reusable ecommerce platform with Terraform</title>
      <dc:creator>reymon359</dc:creator>
      <pubDate>Thu, 03 Jun 2021 06:18:51 +0000</pubDate>
      <link>https://dev.to/one-beyond/managing-the-infrastructure-of-a-reusable-ecommerce-platform-with-terraform-51dg</link>
      <guid>https://dev.to/one-beyond/managing-the-infrastructure-of-a-reusable-ecommerce-platform-with-terraform-51dg</guid>
      <description>&lt;p&gt;Setting up and maintaining the infrastructure for a &lt;a href="https://ramonmorcillo.com/developing-a-reusable-ecommerce-platform/" rel="noopener noreferrer"&gt;reusable ecommerce platform&lt;/a&gt; with a microservice architecture is not an easy task. You have to provide every service with resources, keep track of them and update them when needed.&lt;/p&gt;

&lt;p&gt;Our team uses &lt;a href="https://azure.microsoft.com/en-us/" rel="noopener noreferrer"&gt;Azure&lt;/a&gt; as our cloud provider to manage all those resources. &lt;strong&gt;Every service uses different resources related to the business logic they handle.&lt;/strong&gt; We use resources like &lt;a href="https://azure.microsoft.com/en-us/services/service-bus/" rel="noopener noreferrer"&gt;Azure Service Bus&lt;/a&gt; to handle the asynchronous communication between them and &lt;a href="https://azure.microsoft.com/en-us/services/key-vault/" rel="noopener noreferrer"&gt;Azure Key Vault&lt;/a&gt; to store the secrets and environment variables.&lt;/p&gt;

&lt;p&gt;In the ones where we need a persistence layer, we rely on the resources &lt;a href="https://azure.microsoft.com/en-us/services/cosmos-db/" rel="noopener noreferrer"&gt;Azure Cosmos DB&lt;/a&gt; or &lt;a href="https://azure.microsoft.com/en-us/services/postgresql/" rel="noopener noreferrer"&gt;Azure Database for PostgreSQL&lt;/a&gt;. Other services provide an API to search among a catalog of products with &lt;a href="https://azure.microsoft.com/en-us/services/search/" rel="noopener noreferrer"&gt;Azure Cognitive Search&lt;/a&gt;. As I will explain later, we work with different &lt;em&gt;environments&lt;/em&gt;, therefore, creating and updating the resources across them becomes a harder task. &lt;/p&gt;

&lt;p&gt;If you want to understand better the context of the &lt;strong&gt;reusable ecommerce platform&lt;/strong&gt; I mention in this lecture, I recommend you to take a look at &lt;a href="https://ramonmorcillo.com/developing-a-reusable-ecommerce-platform/" rel="noopener noreferrer"&gt;this article&lt;/a&gt;. Although the architecture has changed a bit, the core concept of the reusable ecommerce platform remains the same, making this article easier to understand.&lt;/p&gt;

&lt;p&gt;So, how do you keep track of all the services resources that are being used across them?&lt;/p&gt;

&lt;p&gt;This is where &lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; comes in handy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is Terraform

&lt;ul&gt;
&lt;li&gt;Modules&lt;/li&gt;
&lt;li&gt;Resources&lt;/li&gt;
&lt;li&gt;Terraform Plan&lt;/li&gt;
&lt;li&gt;Terraform Apply&lt;/li&gt;
&lt;li&gt;State&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;How we use it

&lt;ul&gt;
&lt;li&gt;Version Control System&lt;/li&gt;
&lt;li&gt;Terraform Variables&lt;/li&gt;
&lt;li&gt;Environments and CICD&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Conclusions&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Terraform
&lt;/h2&gt;

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

&lt;p&gt;&lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; is an open-source infrastructure as code software tool developed by HashiCorp. It provides a consistent CLI workflow to manage hundreds of cloud services in configuration files. &lt;a href="https://learn.hashicorp.com/tutorials/terraform/install-cli" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is the official guide on how to install it.&lt;/p&gt;

&lt;p&gt;Terraform is a tool that helps you manage various cloud infrastructure services coding configuration files where you can configure the ones needed. It has support for the main cloud providers out there like AWS, Azure, or GCP.&lt;/p&gt;

&lt;p&gt;I will enumerate the main features it provides. There are plenty more, however, these are the minimum ones required to understand the tool and this article.&lt;/p&gt;
&lt;h3&gt;
  
  
  Modules
&lt;/h3&gt;

&lt;p&gt;Terraform provides modules that help us &lt;strong&gt;reuse our Terraform code.&lt;/strong&gt; Our complex infrastructure is broken into multiple modules making it more reusable and simpler to maintain.&lt;/p&gt;

&lt;p&gt;It is very easy to convert a given Terraform configuration into modules and Terraform has its eco-system for pre-built modules.&lt;/p&gt;
&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;p&gt;Resources are the &lt;em&gt;key&lt;/em&gt; element in Terraform. Each of them describes a cloud service such as a computed instance, persistence system, or DNS record.&lt;/p&gt;

&lt;p&gt;Here is a simple example of how we would define a resource we want to use in our infrastructure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;food&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/food"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 1.0.4"&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;resource&lt;/span&gt; &lt;span class="s2"&gt;"food_tapas"&lt;/span&gt; &lt;span class="s2"&gt;"spanish_omelet"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ingredient_1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eggs"&lt;/span&gt;
  &lt;span class="nx"&gt;ingredient_2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"onions"&lt;/span&gt;
  &lt;span class="nx"&gt;Ingredient_3&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"potatoes"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The language used in Terraform is the &lt;em&gt;HashiCorp Configuration Language (HCL)&lt;/em&gt;. In the example above we first specify the cloud provider &lt;code&gt;food&lt;/code&gt;. Then define a resource of the type &lt;code&gt;food_tapas&lt;/code&gt; with the name &lt;code&gt;spanish_omelet&lt;/code&gt;. Inside the resource block, we have the configuration arguments which are the ingredients for this delicious resource.&lt;/p&gt;

&lt;h3&gt;
  
  
  Terraform Plan
&lt;/h3&gt;

&lt;p&gt;Once all the infrastructure resources have been defined, a &lt;strong&gt;Plan&lt;/strong&gt; is run. Here Terraform checks the code for syntax errors, state verification, API authentication, and then outputs a summary of the changes.&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;terraform plan&lt;/code&gt; allows you to check if the plan to be applied for such configuration is the one you were expecting before changing the infrastructure.&lt;/p&gt;

&lt;p&gt;Here is an example of the output summary we would get when running &lt;code&gt;terraform plan&lt;/code&gt; with the example resource&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;terraform plan
An execution plan has been generated and is shown below.

Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  &lt;span class="c"&gt;# food_tapas.spanish_omelet will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"food_tapas"&lt;/span&gt; &lt;span class="s2"&gt;"spanish_omelet"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        + &lt;span class="nb"&gt;id&lt;/span&gt;                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
        + ingredient_1      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eggs"&lt;/span&gt;
        + ingredient_2      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"onions"&lt;/span&gt;
        + ingredient_3      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"potatoes"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

Plan: 1 to add, 0 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Terraform Apply
&lt;/h3&gt;

&lt;p&gt;Once confirmed, the summary of changes are the ones wanted, we execute them with &lt;code&gt;terraform apply&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After running it successfully the console shows this output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; Apply &lt;span class="nb"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; Resources: 1 added, 0 changed, 0 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that is an overall view of defining and creating your infrastructure resources in an &lt;em&gt;automated&lt;/em&gt; way. All through config files &lt;strong&gt;removing the manual process.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjr5cdtmyco787xglkjfs.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjr5cdtmyco787xglkjfs.jpeg" alt="Terraform resource Spanish omelet from Casa Paco, Madrid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terraform resource Spanish omelet from Casa Paco, Madrid&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  State
&lt;/h3&gt;

&lt;p&gt;The last thing to mention would be the &lt;strong&gt;Terraform State.&lt;/strong&gt; Its purpose is to store the relation between the objects in a remote system and the resource instances declared in your configuration.&lt;/p&gt;

&lt;p&gt;When the remote object is created its identity is recorded against a particular resource instance.&lt;/p&gt;

&lt;p&gt;Future configuration changes will update the state and make terraform update or delete that object.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we use it
&lt;/h2&gt;

&lt;p&gt;Going back to our reusable ecommerce platform. Here is how we take advantage of Terraform’s features to improve our workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Version Control System
&lt;/h3&gt;

&lt;p&gt;Having all the infrastructure defined in code files means we can use a &lt;strong&gt;VCS&lt;/strong&gt; (Version Control System). We opt for Git and host it in a GitHub repository. This way we can keep a history control of the resources we have been using.&lt;/p&gt;

&lt;p&gt;In addition, the integration with GitHub allows us to work with pull requests in order to add, change or destroy resources from the Infrastructure.  &lt;/p&gt;

&lt;p&gt;Although the Terraform State is stored locally by default in a file named &lt;code&gt;terraform.tfstate&lt;/code&gt;, we store it remotely outside the VCS. This is a good practice when working in a team environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Terraform Variables
&lt;/h3&gt;

&lt;p&gt;Being a reusable platform means its infrastructure has to be the same in every shop we create. With terraform, we accomplish this by defining a &lt;a href="https://www.terraform.io/docs/language/values/variables.html" rel="noopener noreferrer"&gt;Terraform input variable&lt;/a&gt; called &lt;code&gt;shops_to_apply&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We then pass this variable through the modules and resources where we want to use it.  This way when we apply the plan the changes will happen in each of the shops.&lt;/p&gt;

&lt;p&gt;Here is an example of how we would define the variable if we had to set up the infrastructure for three different shops.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"shops_to_apply"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;happy&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"happyReadings"&lt;/span&gt;
   &lt;span class="nx"&gt;world&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"worldOfWaves"&lt;/span&gt;   
   &lt;span class="nx"&gt;healt&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"healthyFruits"&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;Then in each resource, we use a Terraform &lt;a href="https://www.terraform.io/docs/language/meta-arguments/for_each.html" rel="noopener noreferrer"&gt;for_each meta-argument&lt;/a&gt; to iterate them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"azurerm_postgresql_database"&lt;/span&gt; &lt;span class="s2"&gt;"orders-api-service"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;for_each&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shops_to_apply&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${each.key}-orders-api-service"&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;other&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Environments and CICD
&lt;/h3&gt;

&lt;p&gt;We work with three environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Development:&lt;/strong&gt; A testing environment where all services new features, refactors, and bug fixes get released once merged to the main repository branch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staging:&lt;/strong&gt; A mirror of the Production environment. When the changes have been properly implemented in Development they are promoted to this environment. In this environment, we can see how they will work in a production-similar situation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production:&lt;/strong&gt; The environment the user has access to. The final environment where the changes get promoted from Staging.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not all the changes are visible at once in each environment. We use &lt;a href="https://configcat.com/" rel="noopener noreferrer"&gt;ConfigCat&lt;/a&gt; as our system of feature flags to make most of the changes visible or not.&lt;/p&gt;

&lt;p&gt;We use &lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; and &lt;a href="https://azure.microsoft.com/en-us/services/devops/pipelines/" rel="noopener noreferrer"&gt;Azure DevOps&lt;/a&gt; for our Continuous Integration and Continuous Delivery system. When the changes on the Terraform infrastructure repository are added to the main branch, the CICD system gets triggered and the plan is executed on our development environments. When the logs from the plan are the expected ones we manually run the &lt;code&gt;apply&lt;/code&gt;.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Having the infrastructure defined as code has brought us nothing but improvements to our platform. Here is a list of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduce human error and increase automation.&lt;/strong&gt; The fewer resources you set up manually, the fewer errors you get in the long term.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It is easier to maintain&lt;/strong&gt; since all the infrastructure is coded in config files. Plus we are &lt;strong&gt;using GitHub repositories and Pull Requests&lt;/strong&gt; to collaborate all together.&lt;/li&gt;
&lt;li&gt;The infrastructure is &lt;strong&gt;easier to change&lt;/strong&gt; compared to traditional manual ways.&lt;/li&gt;
&lt;li&gt;All the configuration files work as &lt;strong&gt;documentation of the resources&lt;/strong&gt; we are using.&lt;/li&gt;
&lt;li&gt;Thanks to the use of variables we &lt;strong&gt;speed up the process of setting up new ecommerce platforms.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Updating and deleting resources is a delicate topic. Having a proper CICD allows us to &lt;strong&gt;predict and make changes to the infrastructure in the safest way possible.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;We can effortlessly &lt;strong&gt;provision our development, staging, and production environments with the same consistent configuration.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>terraform</category>
      <category>architecture</category>
      <category>devops</category>
    </item>
    <item>
      <title>7 lessons learned from The Pragmatic Programmer and The Clean Coder</title>
      <dc:creator>reymon359</dc:creator>
      <pubDate>Wed, 13 Jan 2021 10:21:58 +0000</pubDate>
      <link>https://dev.to/one-beyond/7-lessons-learned-from-the-pragmatic-programmer-and-the-clean-coder-4pfm</link>
      <guid>https://dev.to/one-beyond/7-lessons-learned-from-the-pragmatic-programmer-and-the-clean-coder-4pfm</guid>
      <description>&lt;p&gt;I recently finished reading both books: &lt;em&gt;The Pragmatic Programmer 20th Anniversary Edition&lt;/em&gt; (2019) and &lt;em&gt;The Clean Coder&lt;/em&gt; (2011) which are found on almost every “top 10 Software Development books” lists out there. My goal was to learn, improve, and get something a teacher from mine used to say: “&lt;em&gt;knowledge that can’t be obtained from just reading articles&lt;/em&gt;.”&lt;/p&gt;

&lt;p&gt;When you are developing software you may get stuck at a point where Youtube videos and Stackoverflow answers don’t help. You end up reaching for the official docs, or the source code of that technology to find the answer. The same thing happens when you want to understand the subject properly. &lt;strong&gt;Articles fall short and reading well-known books is the best approach.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These books focus not only on how to write code but on teaching you best practices for developing software and even useful life lessons. I’ll share some lessons I learned from them. &lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Taking Responsibility&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;li&gt;Teamwork&lt;/li&gt;
&lt;li&gt;Estimating&lt;/li&gt;
&lt;li&gt;Tracer bullets&lt;/li&gt;
&lt;li&gt;Handling pressure&lt;/li&gt;
&lt;li&gt;Refactoring&lt;/li&gt;
&lt;li&gt;Main differences&lt;/li&gt;
&lt;li&gt;Conclusions&lt;/li&gt;
&lt;li&gt;Resources&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Taking Responsibility
&lt;/h2&gt;

&lt;p&gt;As a software developer, you are responsible for the code you create and must ensure that it not only works now but will do in the best possible way for a long time (nothing lasts forever). The best way to make sure the code won’t fail is by testing it, having automated tests that you run each time you write new lines to be sure everything is still working.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Take Responsibility. Responsibility is something you actively agree to.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Responsibility is not only related to coding, you have to &lt;strong&gt;take responsibility for improving yourself&lt;/strong&gt; too and get better by scheduling time for it. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Professionals spend time caring for their profession. Presumably, you became a software developer because you are passionate about software and your desire to be a professional is motivated by that passion.&lt;br&gt;
— The Clean Coder&lt;/p&gt;

&lt;p&gt;Your knowledge and experience are your most important day-to-day professional assets.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;The gravity of testing in software development is such that both books focus on this topic. &lt;/p&gt;

&lt;p&gt;You have to &lt;strong&gt;look at tests as the first users of your code&lt;/strong&gt;, so they are the best feedback that guides your coding.&lt;/p&gt;

&lt;p&gt;Practice &lt;a href="https://en.wikipedia.org/wiki/Test-driven_development" rel="noopener noreferrer"&gt;TDD Test Driven Development.&lt;/a&gt; How? Three steps explanation:&lt;/p&gt;

&lt;p&gt;1 Choose a feature to add and write a test that will pass after implementing it. Now, all tests but the new one should pass. &lt;/p&gt;

&lt;p&gt;2 Write the code required to pass it. &lt;/p&gt;

&lt;p&gt;3 Refactor the code and check all tests still pass.&lt;/p&gt;

&lt;p&gt;Thus said, it is important to look at the big picture and not to miss the main goal by writing too many tests.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is easy to become seduced by the green "tests passed" message, writing lots of code that doesn’t actually get you closer to a solution.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;There are three ways of testing: &lt;em&gt;First, During,&lt;/em&gt; and  &lt;em&gt;Never.&lt;/em&gt; First (TDD) is the best one, During is a fallback when First is not useful, and Never is often called “Test Later” but sadly &lt;strong&gt;in most cases Later means Never.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The need to test first forces you to think about "good design."&lt;br&gt;
— The Clean Coder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Having tests give you the confidence to refactor code more often because you have the tests to check if they still pass after the changes are done.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tests should be run as frequently as possible to provide maximum feedback and to ensure that the system remains continuously clean.&lt;br&gt;
— The Clean Coder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Use acceptance tests to &lt;em&gt;define when a requirement is done&lt;/em&gt; collaborating with the stakeholders.&lt;/p&gt;

&lt;p&gt;Developers take the responsibility to ensure that tests are &lt;em&gt;always automated&lt;/em&gt; for a simple reason: &lt;strong&gt;cost.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Developers have to aim “QA should find nothing” as a goal by implementing different kinds of tests, in different measures from unit to exploratory ones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4wesbcq3zqma2ikgyqho.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4wesbcq3zqma2ikgyqho.png" alt="The Test Automation Pyramid - The Clean Coder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Teamwork
&lt;/h2&gt;

&lt;p&gt;When working on a team you have to be a "team player", communicate frequently, keep an eye out for your teammates, and execute your responsibilities as well as possible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Good communication is key to avoiding these problems. And by "good" we mean instant and frictionless. Frictionless means it’s easy and low-ceremony to ask questions, share your progress, your problems, your insights and learnings, and to stay aware of what your teammates are doing.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fztxd8ipc14ep0q2pddrw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fztxd8ipc14ep0q2pddrw.jpg" alt="tobias-mrzyk-iuqmGmst5Po-unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Teams should be &lt;strong&gt;small, less than 10-12 members&lt;/strong&gt;, where everyone knows and trusts each other. This team environment is &lt;strong&gt;hard to achieve&lt;/strong&gt; therefore once you get it you have to &lt;strong&gt;care for it changing the projects they work on rather than the members.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As team size grows, communication paths grow at the rate of O(n^2), where n is the number of team members. On larger teams, communication begins to break down and becomes ineffective.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;

&lt;p&gt;To form teams around projects is a foolish approach. Individuals are only on the project for a short time and therefore never learn how to deal with each other. Teams are harder to build than projects. Therefore, it is better to form persistent teams that move together from one project to the next and can take on more than one project at a time.&lt;br&gt;
— The Clean Coder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx237ixp7v76znd8os1i9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx237ixp7v76znd8os1i9.jpg" alt="tobias-mrzyk-Px3oXvVXRxc-unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Furthermore, great teams will face and solve issues together where each individual will provide their best. They &lt;em&gt;get things done as a unit&lt;/em&gt;. In the end, they will be known for their performance and quality of work.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Quality can come only from the individual contributions of all team members. Quality is built in, not bolted on.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;

&lt;p&gt;A gelled team can work miracles, anticipate each other, cover for each other, support each other, and demand the best from each other. They make things happen.&lt;br&gt;
— The Clean Coder&lt;/p&gt;

&lt;p&gt;Great project teams have a distinct personality. People look forward to meetings with them, because they know that they’ll see a well-prepared performance that makes everyone feel good. The documentation they produce is crisp, accurate, and consistent.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwc5adohs2ir9htwptqww.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwc5adohs2ir9htwptqww.jpg" alt="natalie-pedigo-wJK9eTiEZHY-unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Estimating
&lt;/h2&gt;

&lt;p&gt;This lesson, like the majority from both books, is as important in software development as in real life. The more you practice and develop it, the more intuitive will be your ability to determine the feasibility of any task. &lt;/p&gt;

&lt;p&gt;First, I want to clarify what &lt;em&gt;estimating&lt;/em&gt; means by sharing The Clean Coder definition of an estimate which refers to it as a &lt;em&gt;probability distribution.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An estimate is not a number. An estimate is a &lt;em&gt;probability distribution,&lt;/em&gt; the likelihood of completion.&lt;br&gt;
— The Clean Coder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To help you understand it, here is a figure of the likelihood of completion of a task for the next 11 days.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdjbqb4sjne43j1licreg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdjbqb4sjne43j1licreg.png" alt="Probability distribution, the likelihood of completion. Source: The clean coder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the basics to make great estimations is to &lt;strong&gt;have proper knowledge of what you are estimating.&lt;/strong&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The first part of any estimation exercise is building an understanding of what’s being asked. You need to have a grasp of the scope of the domain.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don’t estimate alone, &lt;strong&gt;communicate with other people to be as accurate as possible.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The most important estimation resource you have are the people around you. They can see things that you don’t. They can help you estimate your tasks more accurately than you can estimate them on your own.&lt;br&gt;
— The Clean Coder&lt;/p&gt;

&lt;p&gt;A basic estimating trick that always gives good answers: ask someone who’s already done it.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When asked for an estimation choose the units that better reflect the accuracy you intend to convey. This Estimation times scale from The Pragmatic Programmer may help you.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Duration&lt;/th&gt;
&lt;th&gt;Quote estimate in&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1–15 days&lt;/td&gt;
&lt;td&gt;Days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3–6 weeks&lt;/td&gt;
&lt;td&gt;Weeks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8–20    weeks&lt;/td&gt;
&lt;td&gt;Months&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20+   weeks&lt;/td&gt;
&lt;td&gt;Think hard before giving an estimate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Although Business likes to view estimates as commitments, remember that &lt;strong&gt;an estimate is just a guess therefore no commitment is implied.&lt;/strong&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A commitment is something you must achieve. If you commit to getting something done by a certain date, then you simply have to get it done by that date. Professionals don’t make commitments unless they know they can achieve them. Missing a commitment is an act of dishonesty only slightly less onerous than an overt lie.&lt;br&gt;
— The Clean Coder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thus said, to help Business measuring requirements and making appropriate plans you have to &lt;strong&gt;remove the requirement’s ambiguity before estimating.&lt;/strong&gt; Afterwards, &lt;strong&gt;keep them updated about the progress.&lt;/strong&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The trick to managing lateness is early detection and transparency. Regularly measure your progress against your goal. Be as honest as you can about all dates. Do not incorporate hope into your estimates!&lt;br&gt;
— The Clean Coder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Do not reinvent the wheel, use well-known estimation techniques for tasks. Here I made a summary of some techniques mentioned in both books.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=pert" rel="noopener noreferrer"&gt;PERT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=wideband-delphi" rel="noopener noreferrer"&gt;Wideband Delphi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=flying-fingers" rel="noopener noreferrer"&gt;Flying Fingers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=planning-poker" rel="noopener noreferrer"&gt;Planning Poker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=affinity-estimation" rel="noopener noreferrer"&gt;Affinity Estimation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=trivariate-estimates" rel="noopener noreferrer"&gt;Trivariate Estimates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=the-law-of-large-numbers" rel="noopener noreferrer"&gt;The Law of Large Numbers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more experience you have on a certain project the better you will estimate its tasks. Therefore don’t worry if the first estimates you make are not as accurate as they could be. It is an incremental process as with every long term goal you want to achieve. &lt;/p&gt;

&lt;p&gt;Like one of my favorite quotes states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There is only &lt;strong&gt;one&lt;/strong&gt; way to &lt;strong&gt;eat an elephant&lt;/strong&gt;: a &lt;strong&gt;bite at a time&lt;/strong&gt;.&lt;br&gt;
— Desmond Tutu&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, there is no way you can eat such cuteness&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Tracer bullets
&lt;/h2&gt;

&lt;p&gt;Tracer bullets are a special kind of bullet used in movies to mark the path they’ve taken as feedback for the shooter to aim better the next time. Therefore, the main goal of Tracer Bullet Development is to "shoot" new features into the project and get quick feedback to "aim" better on the next ones.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tracer development is consistent with the idea that a project is never finished: there will always be changes required and functions to add. It is an incremental approach.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo42gcme3fpr7bd1cud08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo42gcme3fpr7bd1cud08.png" alt="Tracer Bullets. Source: The Pragmatic Programmer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This method helps developers to focus on the main features to be implemented so others can be built on. In addition, it serves as &lt;strong&gt;proof the architecture is compatible and feasible&lt;/strong&gt; by providing a functional and demonstrable skeleton to work from the beginning of the development process.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Look for the important requirements, the ones that define the system. Look for the areas where you have doubts, and where you see the biggest risks. Then prioritize your development so that these are the first areas you code.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F24p0a9k0gxl0l6x1nx6c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F24p0a9k0gxl0l6x1nx6c.jpg" alt="outer-digit-Ys78stblUyY-unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly, &lt;strong&gt;Tracer Bullet Development should not be confused with prototyping.&lt;/strong&gt; The code from prototypes isn’t supposed to be part of the project whereas the code from the tracer bullets isn’t thrown away. It works and is improved each iteration with new features.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Prototyping generates disposable code. Tracer code is lean but complete, and forms part of the skeleton of the final system. Think of prototyping as the reconnaissance and intelligence gathering that takes place before a single tracer bullet is fired.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Handling pressure
&lt;/h2&gt;

&lt;p&gt;I liked this one as well since it helps you outside software development too. Soon or later you will be under pressure, and the best tricks to handling it are to &lt;strong&gt;avoid it when you can, and weather it when you can’t.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The best way to stay calm under pressure is to avoid the situations that cause pressure.&lt;br&gt;
— The Clean Coder&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;You mainly &lt;strong&gt;avoid it by managing commitments, keeping clean, and following your disciplines.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The best way to manage commitments is by &lt;em&gt;saying no&lt;/em&gt; to those which deadlines you aren’t sure to meet. Keeping clean basically means to have no mess on your systems, code, and design.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The way to go fast, and to keep the deadlines at bay, is to stay clean. Professionals do not succumb to the temptation to create a mess in order to move quickly. “Quick and dirty” is an oxymoron. Dirty always means slow!&lt;br&gt;
— The Clean Coder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Follow disciplines you truly believe in and stick to them all the time&lt;/strong&gt; no matter the situation. Crisis times will come, and it’s when you have to pay attention to how you behave because if you follow your disciplines means you believe in them. Changing your behavior and not following them would mean you don’t truly believe in your normal behavior, and you have to shift those disciplines to improve it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you keep your code clean during normal times but make messes in a crisis, then you don’t really believe that messes slow you down. If you pair in a crisis but don’t normally pair, then you believe pairing is more efficient than non-pairing.&lt;br&gt;
— The Clean Coder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frh79xm2ny4467izz0m9u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frh79xm2ny4467izz0m9u.jpg" alt="federico-lancellotti-YBuVjp5Mtrw-unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose disciplines that you feel comfortable following in a crisis. &lt;em&gt;Then follow them all the time.&lt;/em&gt; Following these disciplines is the best way to avoid getting into a crisis. Don’t change your behavior when the crunch comes. If your disciplines are the best way to work, then they should be followed even in the depths of a crisis.&lt;/p&gt;

&lt;p&gt;However, you can’t avoid pressure always so you have to learn how to get through it. &lt;strong&gt;You weather it by staying calm, communicating, following your disciplines, and getting help.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To stay calm &lt;strong&gt;don’t panic,&lt;/strong&gt; manage your stress, and think the problem through to find the best possible outcome. Then go for it at a steady pace, &lt;em&gt;eating an elephant way-&lt;/em&gt; &lt;strong&gt;communicating&lt;/strong&gt; all the time with your team and superiors to let them know when you are in trouble to get input and guidance. This way there won’t be any unexpected surprises in the end.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Avoid creating surprises. Nothing makes people more angry and less rational than surprises. Surprises multiply the pressure by ten.&lt;br&gt;
— The Clean Coder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the same way you relied on your disciplines to avoid pressure, you should also rely on them when the moment gets tough. In fact, these times you have to pay special attention to them and neither question nor abandon them.&lt;/p&gt;

&lt;p&gt;The communication tip includes &lt;strong&gt;asking for help&lt;/strong&gt; from teammates to pair, superiors, or internet sites and forums. &lt;/p&gt;

&lt;p&gt;Don't forget to be there for others too when they are under pressure and need help.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When the heat is on, find an associate who is willing to pair program with you. You will get done faster, with fewer defects. Your pair partner will help you hold on to your disciplines and keep you from panicking.&lt;br&gt;
— The Clean Coder&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;h2&gt;
  
  
  Refactoring
&lt;/h2&gt;

&lt;p&gt;The term &lt;em&gt;Refactoring&lt;/em&gt; is defined by Martin Fowler as a:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.&lt;br&gt;
— Martin Fowler&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes you will find code that does not feel right and should be fixed or improved, and you have to keep in mind the best moment to do so is &lt;strong&gt;now&lt;/strong&gt;, when you find it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It is inevitable, a program’s code needs to grow, evolve, and improve.&lt;/strong&gt; To do so, some decisions must be rethought, and the code has to be changed therefore be sure to have it covered with &lt;strong&gt;automated tests&lt;/strong&gt; to guarantee that the external behavior does not change.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rather than construction, software is more like gardening—it is more organic than concrete. You plant many things in a garden according to an initial plan and conditions. You constantly monitor the health of the garden, and make adjustments as needed.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;When should you refactor the code? Here is a list of situations that qualify to do so:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove &lt;strong&gt;code duplication.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Making some parts of the code more &lt;strong&gt;orthogonal.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update&lt;/strong&gt; code and/or documentation outdated.&lt;/li&gt;
&lt;li&gt;To improve &lt;strong&gt;performance.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here are Martin Fowler tips on how to refactor without doing more harm than good:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Don’t try to refactor and add functionality at the same time.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Make sure you have good tests before you begin refactoring. Run the tests as often as possible.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Take short, deliberate steps: move a field from one class to another, split a method, rename a variable. Refactoring often involves making many localized changes that result in a larger-scale change.&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most important thing to keep in mind is that &lt;strong&gt;refactoring is not a certain task, it is a habit&lt;/strong&gt; that, as with most things in life, is easier to do while the issues are small, as an ongoing activity while coding. &lt;strong&gt;The less you refactor now the greater time you’ll have to invest to fix the problem down the road.&lt;/strong&gt;&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Refactoring as "a growth." Removing it requires invasive surgery. You can take it out while it is still small. Or, you could wait while it grows and spreads—but removing it then will be both more expensive and more dangerous. Wait even longer, and you may lose the patient entirely.&lt;br&gt;
— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Main differences
&lt;/h2&gt;

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

&lt;p&gt;I did not want this lecture to be a comparison but although they focus on similar subjects, the content, and the way they are narrated are not the same. Here are the main impressions I got from them not related to the content itself that can help you have an idea of what to expect while reading them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Clean Coder speaks about the developer in a more day by day at work way, with references to common situations that are given in such an environment like the relationship with sales or business people, working in a team, or saying no to clients. The developer at the Pragmatic Programmer isn’t that much pictured into job situations, rather it grants an overview of the field structuring the book on advice: &lt;em&gt;topics and tips&lt;/em&gt;, for any situation.
&lt;/li&gt;
&lt;li&gt;The Clean Coder refers to the figure of the Software Developer as a &lt;em&gt;Professional Programmer&lt;/em&gt; while The Pragmatic Programmer uses the totally unexpected term &lt;em&gt;Pragmatic Programmer&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;In general terms, The Clean Coder has a more subjective sense since it tells more personal experiences from the author whereas The Pragmatic Programmer feels more objective focusing mostly on the advice themselves.&lt;/li&gt;
&lt;li&gt;The Pragmatic Programmer contains more code examples in different programming languages than the Clean Coder which helps you understand the concepts discussed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Keep in mind that these are just the personal impressions and lessons I got from reading the two titles. The books have much more to offer, and the best thing you can do is read both yourself to form your own opinion and conclusions. &lt;/p&gt;

&lt;p&gt;If you are interested in software development, want to get better but think they are too similar and don’t have time to read both, think twice, each will bring you different knowledge and best practices for your career. &lt;/p&gt;

&lt;p&gt;Having said that, if you still want to go the lazy way, I made this &lt;a href="https://github.com/reymon359/book-sentences" rel="noopener noreferrer"&gt;open-source project with the core sentences from them&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/reymon359/book-sentences" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6y8aq62kdwq8nt0w2832.png" alt="[Book Sentences Project](https://github.com/reymon359/book-sentences)"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The main resources are both books which you can find easily on the internet and &lt;a href="https://github.com/reymon359/book-sentences/" rel="noopener noreferrer"&gt;the project&lt;/a&gt; where I noted down the sentences I found most important from them.&lt;/p&gt;

&lt;p&gt;Thank you for reading! You can read &lt;a href="https://ramonmorcillo.com/7-lessons-learned-from-the-pragmatic-programmer-and-the-clean-coder" rel="noopener noreferrer"&gt;it too on my site&lt;/a&gt; along with others!&lt;/p&gt;

</description>
      <category>books</category>
      <category>motivation</category>
      <category>career</category>
    </item>
    <item>
      <title>Using GitHub Actions and Renovate App to safely update dependencies automatically</title>
      <dc:creator>reymon359</dc:creator>
      <pubDate>Mon, 21 Dec 2020 16:27:51 +0000</pubDate>
      <link>https://dev.to/one-beyond/using-github-actions-and-renovate-app-to-safely-update-dependencies-automatically-3hc9</link>
      <guid>https://dev.to/one-beyond/using-github-actions-and-renovate-app-to-safely-update-dependencies-automatically-3hc9</guid>
      <description>&lt;p&gt;In Software Development &lt;strong&gt;keeping up to date with technology updates&lt;/strong&gt; is crucial not only for developers who have to be always learning and renewing their set of skills but also for the projects they work on and have to be maintained.&lt;/p&gt;

&lt;p&gt;When you start a project from the ground you normally set it up with the libraries' latest stable versions. Then time goes by, and the size of the project grows, new features are added, new libraries too, and &lt;strong&gt;the version of the libraries and packages usually remains the same and almost never gets updated&lt;/strong&gt;. And yes, why would you update them if the project works perfectly with the current ones?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgjd1bk1ru1cmp69ypdt9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgjd1bk1ru1cmp69ypdt9.jpg" alt="This is fine"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Here are some reasons why you should keep your dependencies updated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solving problems from old versions.&lt;/li&gt;
&lt;li&gt;Adding vulnerability fixes.&lt;/li&gt;
&lt;li&gt;Increase the overall performance.&lt;/li&gt;
&lt;li&gt;Add new features from them. &lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you keep the dependencies updated you are solving problems from older versions, improving the performance with new optimizations, and you are also able to use new features that other developers added to them. All of these contribute to increasing the &lt;em&gt;maintainability of the code&lt;/em&gt;, and the overall project.&lt;/p&gt;

&lt;p&gt;We all have worked on projects where the dependencies have never (or rarely) been updated. &lt;/p&gt;

&lt;p&gt;So how do we do it?&lt;/p&gt;

&lt;p&gt;Well, first you can run &lt;code&gt;npm outdated&lt;/code&gt; to &lt;a href="https://docs.npmjs.com/cli/outdated" rel="noopener noreferrer"&gt;see the latest releases&lt;/a&gt; of the packages you are currently using.&lt;/p&gt;

&lt;p&gt;You can then run &lt;code&gt;npm update&lt;/code&gt; to update them (it will not update them to the major versions) but how do you know which ones will make the project break and which ones won't? &lt;/p&gt;

&lt;p&gt;Then there is the &lt;em&gt;when&lt;/em&gt;, when should you update them? When should you check for updates? every day? every week? ...month?&lt;/p&gt;

&lt;p&gt;This is why I made this project, to learn about GitHub Actions and use it to have a &lt;strong&gt;safe way to automatically update the dependencies without making the project fail&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The short explanation of this tutorial is about adding the &lt;a href="https://github.com/renovatebot/renovate" rel="noopener noreferrer"&gt;Renovate app&lt;/a&gt; to check for dependencies updates and then submit Pull Requests to update them, this way we will &lt;em&gt;abstract&lt;/em&gt; ourselves on checking for updates, so we can focus on more important things.&lt;/p&gt;

&lt;p&gt;The point of using &lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; is to set up a workflow and trigger it with every Pull Request to check that the build and tests pass with the updated dependencies before adding them to the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Getting Started&lt;/li&gt;
&lt;li&gt;Set up GitHub Actions Workflow&lt;/li&gt;
&lt;li&gt;Add Renovate&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;Useful Resources&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Although &lt;strong&gt;this approach can be applied to any project&lt;/strong&gt; we will use a &lt;a href="https://reactjs.org" rel="noopener noreferrer"&gt;React&lt;/a&gt; project made with &lt;a href="https://github.com/facebook/create-react-app" rel="noopener noreferrer"&gt;Create React App&lt;/a&gt; as it will give us a basic project with everything ready to work on. By the way, if you do not have Node.js installed &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;here&lt;/a&gt; is the link to do so.&lt;/p&gt;

&lt;p&gt;Also, &lt;a href="https://github.com/reymon359/github-actions-and-renovate" rel="noopener noreferrer"&gt;in this repository is the resulting project&lt;/a&gt; you will obtain after following all the steps below in case you want to have a look before starting.&lt;/p&gt;

&lt;p&gt;So let's begin running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-react-app my-app
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use npm 5.1 or earlier, you can't use &lt;code&gt;npx&lt;/code&gt;. Instead, install &lt;code&gt;create-react-app&lt;/code&gt; globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; create-react-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;create-react-app my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Set up Github Actions Workflow
&lt;/h2&gt;

&lt;p&gt;Now we will proceed to define a GitHub Actions Workflow in our repository to automate the process.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; is a Github Feature that helps your software development workflows automating from simple tasks to custom end-to-end continuous integration (CI) and continuous deployment (CD) capabilities in your repository.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In our root folder, we will create a new folder and name it &lt;code&gt;.github&lt;/code&gt; and inside of it a &lt;code&gt;workflows&lt;/code&gt; one. This is how your project should look after these steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📁 my-app
├── 📁 .github
│   └── 📁 workflows
├── ...
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is where we will create and add our Workflows. Github Actions Workflows are the Continuous Integration automated processes we want to run in our project. &lt;/p&gt;

&lt;p&gt;Workflows are composed of jobs that contain a set of steps and to explain them in a clearer way let's create our own workflow explaining it step by step. &lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;.github/workflows&lt;/code&gt; directory, add a &lt;code&gt;.yml&lt;/code&gt; or &lt;code&gt;.yaml&lt;/code&gt; file and name it &lt;code&gt;main.yml&lt;/code&gt;. I chose that name to keep things simple, but you can give it any other name like &lt;code&gt;build-test.yml&lt;/code&gt; or &lt;code&gt;continuous-integration-workflow.yml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📁 my-app
├── 📁 .github
│   └── 📁 workflows
│       └── 📄 main.yml
├── ...
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://gist.github.com/reymon359/514cf378456457f1798293fe0ed99f3a" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is how the workflow will look in the end in case you just want to copy it and add it directly before the explanation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and Test&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;master&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;master&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build_and_test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;10&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;12&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use Node.js ${{ matrix.node-version }}&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.node-version }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install project&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build the project&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build --if-present&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first param of our workflow will be its &lt;strong&gt;name&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and Test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second param is the &lt;strong&gt;trigger&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;We can choose if the workflow is &lt;strong&gt;triggered by an event like a push or pull request to a specific branch&lt;/strong&gt;, or we can even schedule a &lt;a href="https://en.wikipedia.org/wiki/Cron" rel="noopener noreferrer"&gt;cron&lt;/a&gt; to &lt;strong&gt;automatically trigger it every defined amount of time!&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In our project we will want to trigger it when pushing to the master branch and when the Renovate app submits a Pull Request to update a dependence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;master&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;master&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we define the &lt;strong&gt;jobs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this example, there will only be one job which will be the one to &lt;strong&gt;build and test&lt;/strong&gt; the project, and chose the virtual machine where the job will be run on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build_and_test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then it comes to the matrix where we will configure the combination of versions and systems we want to run out Workflow. In our case, we will run it on Node.js 10 and 12.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;10&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;12&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the Workflow's steps. The first one is the &lt;a href="https://github.com/actions/checkout" rel="noopener noreferrer"&gt;checkout action&lt;/a&gt; which is a standard action that you must include in your workflow when you need a copy of your repository to run the workflow.&lt;/p&gt;

&lt;p&gt;Then you can run other actions and processes, in our app, we will use the &lt;strong&gt;setup-node&lt;/strong&gt; action with the matrix we defined before. Then we will add steps to install the project, build it, and run the tests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use Node.js ${{ matrix.node-version }}&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.node-version }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install project&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build the project&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build --if-present&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Create a GitHub Repository for the project, commit the local changes made, and push them to it.&lt;/p&gt;

&lt;p&gt;Quick tip, If you want to create it faster go to &lt;a href="https://repo.new" rel="noopener noreferrer"&gt;repo.new&lt;/a&gt; or &lt;a href="https://github.new" rel="noopener noreferrer"&gt;github.new&lt;/a&gt;. You can use &lt;a href="https://gist.new" rel="noopener noreferrer"&gt;gist.new&lt;/a&gt; for gists too! &lt;/p&gt;

&lt;p&gt;Once you push your changes the Workflow will run, and you will be able to see how it went in the &lt;code&gt;Actions&lt;/code&gt; &lt;a href="https://github.com/reymon359/github-actions-and-renovate/actions" rel="noopener noreferrer"&gt;tab from the GitHub Project&lt;/a&gt;.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Add Renovate
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/marketplace/renovate" rel="noopener noreferrer"&gt;Renovate&lt;/a&gt; is a free, open-source, customizable app to automate the update of our dependencies in software projects by receiving pull requests. It is used by software companies like Google, Mozilla, or Uber and you can use it on GitHub, Gitlab, Bitbucket, Azure DevOps, and Gitea.&lt;/p&gt;

&lt;p&gt;Going to the point what we will do is add a bot that will submit pull requests to our repository when there are updates in our project dependencies. &lt;/p&gt;

&lt;p&gt;The cool thing, and the whole point of our project, is that we have previously defined in our workflow to run the tests with the pull requests so when renovate submits one &lt;strong&gt;we will automatically check if the updates proposed will break the project or not before merging them to the master branch&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0hxvyo2u4cp9xfgzy8k6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0hxvyo2u4cp9xfgzy8k6.gif" alt="Thumbs Up Kid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To add Renovate to our project we have to install &lt;a href="https://github.com/apps/renovate" rel="noopener noreferrer"&gt;its app&lt;/a&gt; into the project's repository. Be careful when selecting the repository you want to add Renovate to and choose the one created before. If by mistake you want to reconfigure it you can do it in the &lt;a href="https://github.com/settings/installations" rel="noopener noreferrer"&gt;Personal Settings' Applications tab&lt;/a&gt; from your account. &lt;/p&gt;

&lt;p&gt;After some minutes we will have to accept and merge the onboarding Pull Request that we will receive.&lt;/p&gt;

&lt;p&gt;Once we have it integrated we will configure it updating the &lt;code&gt;renovate.json&lt;/code&gt; file on the project root. Remember to pull the changes after merging the Pull Request for it to appear. &lt;/p&gt;

&lt;p&gt;We can use the default configuration where renovate will submit the pull requests whenever it finds out about updates and wait for us to merge them:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"extends"&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="s2"&gt;"config:base"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or we can adapt it to the requirements of our project like &lt;a href="https://github.com/renovatebot/renovate/blob/master/renovate.json" rel="noopener noreferrer"&gt;the one used by Renovate itself&lt;/a&gt;. To avoid falling short and to learn a little more about the tool, we will use a configuration with some of its most useful features. If you want to learn more about its configuration &lt;a href="https://docs.renovatebot.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt; are the docs for it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/reymon359/4c4417522cd0922cfbc63ad75ca2c945" rel="noopener noreferrer"&gt;This&lt;/a&gt; will be our &lt;code&gt;renovate.json&lt;/code&gt; file. Have a look at it and I will explain it after.&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"extends"&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="s2"&gt;"config:base"&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;"packageRules"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"updateTypes"&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="s2"&gt;"minor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"patch"&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;"automerge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timezone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Europe/Madrid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"schedule"&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="s2"&gt;"after 10pm every weekday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"before 5am every weekday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"every weekend"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first part, we are telling renovate that our configuration will be an extension from the default one.&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"extends"&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="s2"&gt;"config:base"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we have the &lt;code&gt;packageRules&lt;/code&gt;. After some months using it I realized that going (from time to time) through the pull requests checking and accepting them if the tests passed was a major waste of time. This is why the &lt;code&gt;automerge&lt;/code&gt; is set to true, so Renovate automatically merges the pull request if the workflow passed successfully. &lt;/p&gt;

&lt;p&gt;To restrict Renovate's freedom a bit, we define that he only can perform the &lt;code&gt;automerge&lt;/code&gt; when it is a &lt;code&gt;minor&lt;/code&gt; or &lt;code&gt;patch&lt;/code&gt; update. This way, if it is a &lt;code&gt;major&lt;/code&gt; or another kind of update, we will be the ones to check whether that update should be added or not. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.renovatebot.com/configuration-options/#updatetypes" rel="noopener noreferrer"&gt;Here&lt;/a&gt; you can find more information about the update types available.&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="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"packageRules"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"updateTypes"&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="s2"&gt;"minor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"patch"&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;"automerge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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="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;Lastly, we have the time schedule. If you work alone or in a team at certain hours it is nice to have the updates done at times when you are not working to avoid unnecessary distractions.&lt;/p&gt;

&lt;p&gt;We select our timezone and add a custom &lt;a href="https://docs.renovatebot.com/presets-schedule/" rel="noopener noreferrer"&gt;schedule&lt;/a&gt; for it. You can find the valid timezone names &lt;a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&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="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"timezone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Europe/Madrid"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"schedule"&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="s2"&gt;"after 10pm every weekday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"before 5am every weekday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"every weekend"&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;Anyway, if you do not care about the time the pull requests will be submitted, or the people that contribute to the code are in different timezones then you can remove this part.&lt;/p&gt;

&lt;p&gt;Once we have updated the configuration we push the changes to GitHub to have the Renovate app adapted to the new configuration. &lt;/p&gt;

&lt;p&gt;Now you finally have the project dependencies safely up-to-date without you having to check for them. &lt;a href="https://github.com/reymon359/github-actions-and-renovate" rel="noopener noreferrer"&gt;Here is the resulting project&lt;/a&gt; after following all the steps mentioned above.&lt;/p&gt;

&lt;p&gt;Remember that if you added the time schedule part you will not get the pull request merged automatically until it complies with that configuration.&lt;/p&gt;

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

&lt;p&gt;Although there are other ways to keep the dependencies updated in an automated way if you use GitHub to host your code you should take advantage and make the most of its awesome free features. &lt;/p&gt;

&lt;p&gt;If you are wondering what else you are able to do and automate with the GitHub apps and actions just have a look at its &lt;a href="https://github.com/marketplace" rel="noopener noreferrer"&gt;Marketplace&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In addition, you can have a look at &lt;a href="https://github.com/reymon359/up-to-date-react-template" rel="noopener noreferrer"&gt;a project I made&lt;/a&gt; where I am working on from time to time and on which I based myself for this tutorial. It is a bit more complex and has more features than the one from this tutorial.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed the tutorial and learned about GitHub Actions and its Apps. If you've got any questions, suggestions, or feedback in general, don't hesitate to reach out on any of the social networks from &lt;a href="https://ramonmorcillo.com" rel="noopener noreferrer"&gt;my site&lt;/a&gt; or &lt;a ref="mailto:hey@ramonmorcillo.com"&gt;by mail&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Here is a collection of links and resources which I think can be useful to improve and learn more about GitHub Actions and Apps.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/reymon359/github-actions-and-renovate" rel="noopener noreferrer"&gt;Tutorial project&lt;/a&gt;. - The resulting project from this tutorial.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/marketplace" rel="noopener noreferrer"&gt;GitHub Marketplace&lt;/a&gt;. - The place to find all GitHub Actions and Apps.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://help.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow" rel="noopener noreferrer"&gt;GitHub Actions Workflow Configuration&lt;/a&gt; - The full documentation on how to set up a workflow on Github Actions.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/marketplace/renovate" rel="noopener noreferrer"&gt;Renovate GitHub app&lt;/a&gt; - The Renovate App main page on the GitHub Marketplace.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gist.github.com/reymon359/514cf378456457f1798293fe0ed99f3a" rel="noopener noreferrer"&gt;GitHub Actions project Workflow&lt;/a&gt;. - The Workflow used in this tutorial.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gist.github.com/reymon359/4c4417522cd0922cfbc63ad75ca2c945" rel="noopener noreferrer"&gt;Renovate App's configuration file&lt;/a&gt;. - Renovate App's custom configuration file from the tutorial.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/reymon359/up-to-date-react-template" rel="noopener noreferrer"&gt;Up to Date React Template&lt;/a&gt;. - A Personal project that uses the approach described in this tutorial.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading! You can read &lt;a href="https://ramonmorcillo.com/auto-update-dependencies-safely-github-actions/" rel="noopener noreferrer"&gt;it too on my site&lt;/a&gt; along with others!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>security</category>
      <category>tutorial</category>
      <category>github</category>
    </item>
    <item>
      <title>Getting started with GraphQL and Node.js</title>
      <dc:creator>reymon359</dc:creator>
      <pubDate>Wed, 25 Nov 2020 10:35:53 +0000</pubDate>
      <link>https://dev.to/one-beyond/getting-started-with-graphql-and-node-js-1dl6</link>
      <guid>https://dev.to/one-beyond/getting-started-with-graphql-and-node-js-1dl6</guid>
      <description>&lt;p&gt;The main purpose of this server-client &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; project is to help other people &lt;strong&gt;understand how GraphQL exposes the data from the Server and the Client fetches it&lt;/strong&gt;. I have tried to make it as simple as possible- if you want to dive into the code of the project you can find it &lt;a href="https://github.com/reymon359/graphql-hello-world-server" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, straight to the point: &lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt; is a &lt;strong&gt;query language for &lt;a href="https://en.wikipedia.org/wiki/Application_programming_interface" rel="noopener noreferrer"&gt;APIs&lt;/a&gt;&lt;/strong&gt; developed and &lt;a href="https://engineering.fb.com/core-data/graphql-a-data-query-language/" rel="noopener noreferrer"&gt;open-sourced by Facebook&lt;/a&gt; to speed up the request process.&lt;/p&gt;

&lt;p&gt;While &lt;a href="https://en.wikipedia.org/wiki/Representational_state_transfer" rel="noopener noreferrer"&gt;REST&lt;/a&gt; has been a popular way to expose data from a server, instead of having &lt;strong&gt;multiple endpoints&lt;/strong&gt; that return fixed data structures, GraphQL just has &lt;strong&gt;a single endpoint&lt;/strong&gt; and it is the client's job to specify what data it needs from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Getting started&lt;/li&gt;
&lt;li&gt;Define the Schema&lt;/li&gt;
&lt;li&gt;Add Resolver function&lt;/li&gt;
&lt;li&gt;Set up the Server&lt;/li&gt;
&lt;li&gt;Set up the Client&lt;/li&gt;
&lt;li&gt;Fetching data from the server&lt;/li&gt;
&lt;li&gt;Displaying the data&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;Useful resources

&lt;ul&gt;
&lt;li&gt;Docs 📚&lt;/li&gt;
&lt;li&gt;Learn 📝&lt;/li&gt;
&lt;li&gt;Tools 🔧&lt;/li&gt;
&lt;li&gt;IDEs 💻&lt;/li&gt;
&lt;li&gt;Extras 🍍&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;The first step is to &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;download and install Node.js&lt;/a&gt; in case you haven't already. Once you have it installed let's begin with the directory structure. The project will be composed of &lt;strong&gt;two directories&lt;/strong&gt;, one for the Client and another for the Server. I have chosen to keep both inside the project root directory but then you can split it into two separate projects or any way you want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📁 project
├── 📁 client
└── 📁 server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will initialize the project in the server directory. Change the location to the server folder in your terminal and run &lt;code&gt;npm init&lt;/code&gt; to fill in the project info and generate the &lt;strong&gt;package.json&lt;/strong&gt; file. Or &lt;code&gt;npm init -y&lt;/code&gt; which tells the generator to use the defaults (instead of asking questions and simply generate an empty npm project without going through an interactive process).&lt;/p&gt;

&lt;p&gt;The next step will be to install &lt;a href="https://github.com/graphql/graphql-js" rel="noopener noreferrer"&gt;GraphQL.js&lt;/a&gt; and &lt;a href="https://github.com/apollographql/apollo-server" rel="noopener noreferrer"&gt;Apollo Server&lt;/a&gt; to our server. GraphQL.js will provide two important capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building a type schema, which we will do in the next step.&lt;/li&gt;
&lt;li&gt;Serving queries against that type schema.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To install it just run &lt;code&gt;npm install graphql&lt;/code&gt;. I am assuming you are using a version of NPM equal or higher than &lt;strong&gt;5.0.0&lt;/strong&gt; so you &lt;a href="https://blog.npmjs.org/post/161081169345/v500" rel="noopener noreferrer"&gt;do not need&lt;/a&gt; to add &lt;code&gt;--save&lt;/code&gt; when installing a dependency to be saved in the &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Apollo Server, on the other hand, will help us to implement the GraphQL functionalities. It is part of the &lt;a href="https://www.apollographql.com/" rel="noopener noreferrer"&gt;Apollo Data Graph Platform&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Apollo is a platform for building a data graph, a communication layer that seamlessly connects your application clients (such as React and iOS apps) to your back-end services. Is an implementation of GraphQL designed for the needs of product engineering teams building modern, data-driven applications. - &lt;a href="https://www.apollographql.com/docs/" rel="noopener noreferrer"&gt;Apollo Documentation&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What you need to know about Apollo, at least for now, is it’s a community that builds on top of GraphQL and provides different &lt;strong&gt;tools to help you build your projects&lt;/strong&gt;. The tools provided by Apollo are mainly 2: Client and Server.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Apollo Client&lt;/strong&gt; helps your Frontend communicate with a GraphQL API. It has support for the most popular frameworks such as React, Vue, or Angular and native development on iOS and Android.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Apollo Server&lt;/strong&gt; is the GraphQL server layer in your backend that delivers the responses back to the client requests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you understand Apollo better and why we will use it, let's continue setting up GraphQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define the Schema
&lt;/h2&gt;

&lt;p&gt;A GraphQL Schema is at the core of any GraphQL server implementation. It &lt;strong&gt;describes the shape of your data&lt;/strong&gt;, defining it with a hierarchy of &lt;strong&gt;types&lt;/strong&gt; with fields that are populated from your data source and specifies which &lt;strong&gt;queries&lt;/strong&gt; and &lt;strong&gt;mutations&lt;/strong&gt; are available, so the client knows about the information that can be requested or sent.&lt;/p&gt;

&lt;p&gt;For example, if we wanted to build a music application, our simplest schema, usually defined in a &lt;code&gt;schema.graphql&lt;/code&gt; file, would contain two &lt;strong&gt;Object types&lt;/strong&gt;: &lt;code&gt;Song&lt;/code&gt; and &lt;code&gt;Author&lt;/code&gt; like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Song&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Author&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Author&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;songs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Song&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;Then we would have a &lt;strong&gt;Query type&lt;/strong&gt; to define the available queries: &lt;code&gt;getSongs&lt;/code&gt; and &lt;code&gt;getAuthors&lt;/code&gt;, each returning a list of the corresponding type.&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;type&lt;/span&gt; &lt;span class="nx"&gt;Query&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;getSongs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Song&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;getAuthors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Author&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;To keep it as simple as possible our schema will have just &lt;strong&gt;a single Query&lt;/strong&gt; type which will return a &lt;code&gt;String&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Query&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use &lt;strong&gt;any programming language&lt;/strong&gt; to create a GraphQL schema and &lt;strong&gt;build an interface around it&lt;/strong&gt; but as I explained before we will use Apollo server to execute GraphQL queries. So we create a new &lt;code&gt;server.js&lt;/code&gt; file in the server directory to define the Schema on it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📁 project
├── 📁 client
└── 📁 server
    └── 📄 server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we install apollo-server running &lt;code&gt;npm install apollo-server&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We have to import the &lt;strong&gt;tag function&lt;/strong&gt; &lt;code&gt;gql&lt;/code&gt; from &lt;strong&gt;apollo-server&lt;/strong&gt; to parse the schema this way: &lt;code&gt;const {gql} = require('apollo-server');&lt;/code&gt; and then declare a &lt;code&gt;typeDefs&lt;/code&gt; constant which is an &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;abstract syntax tree&lt;/a&gt; of the Graphql code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When a GraphQL server receives a query to process it generally comes in as a String. This string must be tokenized and parsed into a representation that the machine understands. This representation is called an abstract syntax tree.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want to learn more about abstract syntax trees &lt;a href="https://astexplorer.net/" rel="noopener noreferrer"&gt;AST Explorer&lt;/a&gt; is an online tool that lets you explore the syntax tree created by a chosen language as a parser.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;server.js&lt;/code&gt; file would look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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="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;apollo-server&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;`
  type Query {
    greeting: String
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add Resolver function
&lt;/h2&gt;

&lt;p&gt;Now we have defined our Schema we need a way to answer the client requests for that data; the &lt;strong&gt;resolvers&lt;/strong&gt;.&lt;br&gt;
&lt;strong&gt;A resolver is a function that handles the data for each one of the fields of your schema&lt;/strong&gt;. You can send that data to the client by &lt;strong&gt;fetching a back-end database&lt;/strong&gt; or a third-party &lt;strong&gt;API&lt;/strong&gt; among others.&lt;/p&gt;

&lt;p&gt;They have to &lt;strong&gt;match the type definitions of the Schema&lt;/strong&gt;, in our case, we just have one type definition Query which returns a greeting of type &lt;code&gt;String&lt;/code&gt;, so we will define a resolver for the &lt;code&gt;greeting&lt;/code&gt; field, 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="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="na"&gt;greeting&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello GraphQL world!👋&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;As I explained at the beginning we will keep this example as simple as possible but keep in mind that in a real case &lt;strong&gt;here is where you have to make the queries&lt;/strong&gt; to the database, external API, or from wherever which you intend to extract the query data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up the Server
&lt;/h2&gt;

&lt;p&gt;In the same &lt;code&gt;server.js&lt;/code&gt;, we define and create a new &lt;code&gt;ApolloServer&lt;/code&gt; object passing the &lt;code&gt;Schema&lt;/code&gt; (typeDefs) and &lt;code&gt;resolvers&lt;/code&gt; as parameters.&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;ApolloServer&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="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;apollo-server&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;server&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then calling the &lt;code&gt;listen&lt;/code&gt; method we start the server on the &lt;code&gt;port&lt;/code&gt; that we specify in the params.&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;server&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="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9000&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serverInfo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server running at &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;serverInfo&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also &lt;strong&gt;destructure&lt;/strong&gt; the ServerInfo &lt;code&gt;url&lt;/code&gt; when logging it.&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;server&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="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9000&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;url&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;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="s2"&gt;`Server running at &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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;server.js&lt;/code&gt; file should look like this right now.&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;ApolloServer&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="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;apollo-server&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;`
  type Query {
    greeting: String
  }
`&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="na"&gt;greeting&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello GraphQL world!👋&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="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="nc"&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="nx"&gt;server&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="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9000&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;url&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;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="s2"&gt;`Server running at &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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if we run &lt;code&gt;node server/server.js&lt;/code&gt; we will finally have our GraphQL server up and running🎉!&lt;/p&gt;

&lt;p&gt;You can go and check it on &lt;a href="http://localhost:9000/" rel="noopener noreferrer"&gt;http://localhost:9000/&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/graphql-hello-world-server
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; node server/server.js
Server running at http://localhost:9000/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the first time using GraphQL, you may be thinking &lt;strong&gt;what is this application I am seeing in front of me if we have not written a single line of client code?&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The answer to that question is the &lt;strong&gt;GraphQL Playground&lt;/strong&gt;.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/prisma-labs/graphql-playground" rel="noopener noreferrer"&gt;GraphQL Playground&lt;/a&gt; is a graphical, interactive, in-browser GraphQL IDE, created by &lt;a href="https://www.prisma.io/" rel="noopener noreferrer"&gt;Prisma&lt;/a&gt; and based on &lt;a href="https://github.com/graphql/graphiql" rel="noopener noreferrer"&gt;GraphiQL&lt;/a&gt;. - &lt;a href="https://www.apollographql.com/docs/apollo-server/testing/graphql-playground/" rel="noopener noreferrer"&gt;Apollo docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But what does that mean? It means that this is an environment where we can perform Queries, Mutations, or Subscriptions to our schema and interact with its data.&lt;/p&gt;

&lt;p&gt;If you have worked with &lt;strong&gt;RESTful&lt;/strong&gt; requests before this would be some kind of equivalent to &lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt;, just that here you &lt;strong&gt;do not have to download and configure anything&lt;/strong&gt;, it just &lt;strong&gt;comes by default&lt;/strong&gt; with Apollo!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F27ybc13b84l7xp8sikea.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F27ybc13b84l7xp8sikea.gif" alt="awesome-chris-pratt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So let's try it!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On the left panel write the &lt;code&gt;greeting&lt;/code&gt; query we defined in our schema.&lt;/li&gt;
&lt;li&gt;Then press the ▶ button that is in the middle.&lt;/li&gt;
&lt;li&gt;And &lt;em&gt;Voila!&lt;/em&gt; On the right panel appears the data we defined in our resolver to return.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1bl7knx8lwxc7k1wuf5m.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1bl7knx8lwxc7k1wuf5m.gif" alt="greeting-query-on-playground"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up the Client
&lt;/h2&gt;

&lt;p&gt;Now we have our server up and running let's focus on the client part. We will start creating a &lt;code&gt;client.html&lt;/code&gt; file inside our client folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📁 project
├── 📁 client
|   └── 📄 client.html
└── 📁 server
    └── 📄 server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;index.html&lt;/code&gt; file will have the basics of any &lt;code&gt;HTML&lt;/code&gt; file and a loading header &lt;code&gt;&amp;lt;h1&amp;gt;Loading...&amp;lt;/h1&amp;gt;&lt;/code&gt; to show the user something while we request the data from the server.&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="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Hello World GraphQL Client&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Loading...&lt;span class="nt"&gt;&amp;lt;/h1&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;"app.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fetching data from the server
&lt;/h2&gt;

&lt;p&gt;First off, in the same client folder, we create an &lt;code&gt;app.js&lt;/code&gt; file where we will write the client logic to fetch the data from the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📁 project
├── 📁 client
|   └── 📄 client.html
|   └── 📄 app.js
└── 📁 server
    └── 📄 server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside it, we set the server URL to which we will make the request.&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;GRAPHQL_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:9000/&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;Next, we define our async function &lt;code&gt;fetchGreeting()&lt;/code&gt; to, fetch the greeting from the server. We will use the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch" rel="noopener noreferrer"&gt;fetch API&lt;/a&gt; to perform the HTTP request which by default returns a promise to which we can subscribe and get the answer asynchronously.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchGreeting&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;GRAPHQL_URL&lt;/span&gt;&lt;span class="p"&gt;,&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="s1"&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;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content-type&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;application/json&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;body&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="nf"&gt;stringify&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="s2"&gt;`
        query {
          greeting
        }
      `&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;responseBody&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="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;responseBody&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 detail to take into account is that the method of the request is &lt;code&gt;POST&lt;/code&gt;, which can confuse us if we are used to working with &lt;code&gt;RESTful&lt;/code&gt; because this same request made in &lt;code&gt;RESTful&lt;/code&gt;, where we just want to read information from the server, would be usually done with the method &lt;code&gt;GET&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The thing is that with GraphQL we always make &lt;code&gt;POST&lt;/code&gt; requests where we pass &lt;strong&gt;the query in the payload&lt;/strong&gt; (body).&lt;/p&gt;

&lt;p&gt;Finally, we just call our method &lt;code&gt;fetchGreeting();&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GRAPHQL_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:9000/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchGreeting&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;GRAPHQL_URL&lt;/span&gt;&lt;span class="p"&gt;,&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="s1"&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;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content-type&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;application/json&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;body&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="nf"&gt;stringify&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="s2"&gt;`
        query {
          greeting
        }
      `&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;responseBody&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="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;responseBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchGreeting&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 open the file in your browser and see the &lt;strong&gt;console on the developer tools&lt;/strong&gt; you can see that we actually got the greeting data from the query 🙌!&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Displaying the data
&lt;/h2&gt;

&lt;p&gt;Now we have successfully got the data from the server lets &lt;strong&gt;update the loading title&lt;/strong&gt;. The first thing we will do is destructure the response and return just the &lt;code&gt;data&lt;/code&gt; from it.&lt;/p&gt;

&lt;p&gt;Just replace this part of the code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;responseBody&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="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;responseBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this one&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;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we will update the title with the &lt;code&gt;greeting&lt;/code&gt; returned &lt;strong&gt;inside the data from the response&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetchGreeting&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;greeting&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;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;greeting&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;So our &lt;code&gt;app.js&lt;/code&gt; file will end up having this look&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;GRAPHQL_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:9000/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchGreeting&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;GRAPHQL_URL&lt;/span&gt;&lt;span class="p"&gt;,&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="s1"&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;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content-type&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;application/json&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;body&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="nf"&gt;stringify&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="s2"&gt;`
        query {
          greeting
        }
      `&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchGreeting&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;greeting&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;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;greeting&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;Our &lt;code&gt;index.html&lt;/code&gt; will have the loading title updated with the data fetched from our server!🎉&lt;/p&gt;

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

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

&lt;p&gt;I hope you enjoyed the post and that this project has fulfilled the objective of showing &lt;strong&gt;how graphql works under the hood&lt;/strong&gt;, at least in a very simple way. I know there are a lot of things that I have not explained or that I could have gone deeper but like any &lt;code&gt;hello world&lt;/code&gt; project, it is intended for people who are beginners with it, so I wanted to keep it as simple as possible.&lt;/p&gt;

&lt;p&gt;I'm looking forward to learning more about GraphQL and using it in future projects. If you've got any questions, suggestions, or feedback in general, don't hesitate to reach out on any of the social networks from &lt;a href="https://ramonmorcillo.com" rel="noopener noreferrer"&gt;my site&lt;/a&gt; or &lt;a href="//mailto:hey@ramonmorcillo.com"&gt;by mail&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful resources
&lt;/h2&gt;

&lt;p&gt;Here is a collection of links and resources which have been useful for me to improve and learn more about GraphQL&lt;/p&gt;

&lt;h3&gt;
  
  
  Docs 📚
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/reymon359/graphql-hello-world-server" rel="noopener noreferrer"&gt;Project source code&lt;/a&gt; - The Github repository with all the code from the project.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;GraphQL main site&lt;/a&gt; - GraphQL main site.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;Apollo documentation&lt;/a&gt; - The Apollo platform docs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learn 📝
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.howtographql.com/" rel="noopener noreferrer"&gt;How to GraphQL&lt;/a&gt; - Free and open-source tutorials to learn all around GraphQL to go from zero to production.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/graphql-by-example/" rel="noopener noreferrer"&gt;GraphQL by Example&lt;/a&gt; - Great course where you learn GraphQL by writing full-stack JavaScript applications with Node.js, Express, Apollo Server, React, Apollo Client.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://graphql.org/learn/" rel="noopener noreferrer"&gt;Introduction to GraphQL&lt;/a&gt; - A series of articles to learn about GraphQL, how it works, and how to use it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tools 🔧
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.apollographql.com/" rel="noopener noreferrer"&gt;Apollo GraphQL&lt;/a&gt; - Main site of the Apollo GraphQL implementation.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/prisma-labs/graphql-playground" rel="noopener noreferrer"&gt;GraphQL Playground&lt;/a&gt; - Repository of the GraphQL Playground IDE we used on the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IDEs 💻
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://plugins.jetbrains.com/plugin/8097-js-graphql" rel="noopener noreferrer"&gt;JS GraphQL&lt;/a&gt; - WebStorm and other IntelliJ-based IDEs plugin to support GraphQL language including tagged template literals in JavaScript and TypeScript.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=Prisma.vscode-graphql" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt; - GraphQL extension for VSCode adds syntax highlighting, validation, and language features like go to definition, hover information, and autocompletion for GraphQL projects. This extension also works with queries annotated with gql tag.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=kumar-harsh.graphql-for-vscode" rel="noopener noreferrer"&gt;GraphQL for VSCode&lt;/a&gt; - VSCode GraphQL syntax highlighting, linting, auto-complete, and more!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extras 🍍
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/APIs-guru/graphql-apis" rel="noopener noreferrer"&gt;GraphQL APIs&lt;/a&gt; - A list of public GraphQL APIs to test your skills or to build something with them.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=783ccP__No8" rel="noopener noreferrer"&gt;GraphQL: The Documentary&lt;/a&gt; - A 30 min video that explores the story of why and how GraphQL appeared, and the impact it's having on big tech companies worldwide, including Facebook, Twitter, Airbnb, and Github.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading! You can read &lt;a href="https://ramonmorcillo.com/getting-started-with-graphql-and-nodejs/" rel="noopener noreferrer"&gt;it too on my site&lt;/a&gt; along with others!&lt;/p&gt;

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