<?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: michelada.io</title>
    <description>The latest articles on DEV Community by michelada.io (@micheladaio).</description>
    <link>https://dev.to/micheladaio</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%2F429028%2F4735cce7-e5fa-4f88-a040-6e0260f00a2e.jpg</url>
      <title>DEV Community: michelada.io</title>
      <link>https://dev.to/micheladaio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/micheladaio"/>
    <language>en</language>
    <item>
      <title>The michelada guide to delimit, solve and validate solutions.</title>
      <dc:creator>michelada.io</dc:creator>
      <pubDate>Tue, 27 Oct 2020 16:52:50 +0000</pubDate>
      <link>https://dev.to/micheladaio/the-michelada-guide-to-delimit-solve-and-validate-solutions-o9</link>
      <guid>https://dev.to/micheladaio/the-michelada-guide-to-delimit-solve-and-validate-solutions-o9</guid>
      <description>&lt;p&gt;Or how a Product Design Sprint could help streamline your business.&lt;/p&gt;

&lt;p&gt;It happens to all of us, it doesn't matter how many processes and years we've been doing something, there is always something that can be improved. It doesn't matter if you're a giant, like Amazon (with its Fire smartphone, which only lasted a year in the market) or Microsoft (remember Zune? Don't worry, neither do we).&lt;/p&gt;

&lt;p&gt;Such was the case of one of our clients, a clothing company - so important, that you probably have at least a pair of their signature items in your closet - that when they developed one of their processes for nothing more and nothing less than receiving purchase orders to stock to its brick-and-mortar third-party retailers, they started with something to barely do the work. Several years and growth later, that process stopped being a small rock in the shoe to become a kidney stone: painful, annoying and with the potential to incapacitate if not taken care of, but not necessarily fatal. (I come from a family of doctors, the medical analogy was inevitable)&lt;/p&gt;

&lt;p&gt;After they presented their problem, we used a methodology called Product Design Sprint. Why? Well, problems may have more than one solution and this methodology allows to define the problem, understand their cause, their consequences and validate the proposed solution with potential users from the hand of the stakeholders, allowing to have a basis to avoid deviating from the business goals in the creative process (which happens more frequently than we would like to admit) or avoid the omission of small logistical details that could be omitted due to assumptions during the planning of the project.&lt;/p&gt;

&lt;p&gt;But what is a Product Design Sprint?&lt;/p&gt;

&lt;p&gt;A Product Design Sprint (PDS), is a five-day process to assess ideas and solve challenges through rapid prototyping and user testing. This methodology is based on the book "Sprint: The method to solve problems and try new ideas in just 5 days" by Jake Knapp which in turn, is inspired by Knapp's work in Google Ventures.&lt;/p&gt;

&lt;p&gt;While the goal of a Design Sprint is to streamline processes we know that for various professional reasons, it is difficult to take five days from our agenda to dedicate them to a small part of our business, which although critical, remains only one. Conveniently, there is a four-day version 2.0 where you only need the entire team (i.e. stakeholders, creative minds, technical minds ...) for two days, so instead of a whole week, you only have to make space for two days .&lt;/p&gt;

&lt;p&gt;The creation of the solution&lt;/p&gt;

&lt;p&gt;During the first two days, our PDS team composed of three product designers, a software engineer, a quality control engineer, a content specialist and three stakeholders, had an interview where they presented their current situation and we determined the critical area of ​​action that helped us to identify the actors involved and their stage of interaction, we sketched a solution and carried out usability tests to the proposal that followed an interview script to avoid variations in the testing environment so that we could assign real monetary value as well as of project length should the client choose to bring the prototype solution to a real execution. &lt;/p&gt;

&lt;p&gt;Much better than trying to fix a problem and then realize that you need more resources than you had originally allocated (another of the most common negative experiences when developing software). In this particular case, users showed a positive predisposition to adapt the solution in real scenarios and ease to complete the tasks.&lt;/p&gt;

&lt;p&gt;Now, the PDS does not promise to be a definitive or long-term solution, not because it lacks the ability to, but because it's ability to will directly rely on the nature of each case for which it is being implemented. What it can promise is to give us enough information to know if it is worth investing resources to execute our solution, help us to define a problem and have better tools to execute a solution, and avoid the dread of investing in something that'll cost us more than it helps us.&lt;/p&gt;

</description>
      <category>design</category>
    </item>
    <item>
      <title>Optimistic locking of ActiveRecord models</title>
      <dc:creator>michelada.io</dc:creator>
      <pubDate>Tue, 27 Oct 2020 16:49:48 +0000</pubDate>
      <link>https://dev.to/micheladaio/optimistic-locking-of-activerecord-models-4ea2</link>
      <guid>https://dev.to/micheladaio/optimistic-locking-of-activerecord-models-4ea2</guid>
      <description>&lt;p&gt;Did you know that Rails can help avoid data overwrite when multiple users are editing the same record?&lt;/p&gt;

&lt;p&gt;Yes, you can use optimistic locking on models, and it turns out it's pretty easy to enable it too.&lt;/p&gt;

&lt;p&gt;To be honest, I've never heard about this functionality until recently while browsing the &lt;a href="http://guides.rubyonrails.org/active_record_basics.html"&gt;Active Record Basics Guide&lt;/a&gt; looking for info on a totally different problem that I had.&lt;/p&gt;

&lt;p&gt;When I read about the &lt;code&gt;lock_version&lt;/code&gt; field, I was curious and surprised by what I found.&lt;/p&gt;

&lt;p&gt;It basically works like this:&lt;/p&gt;

&lt;p&gt;If you add the &lt;code&gt;lock_version&lt;/code&gt; field to any ActiveRecord model, every time that record is saved it will be checked for modifications after the record was loaded. &lt;/p&gt;

&lt;p&gt;So, if for some reason the record changed in the database while you were editing it, when you try to save it an &lt;code&gt;ActiveRecord::StaleObjectError&lt;/code&gt; exception will be raised.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'active_record'&lt;/span&gt;

&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;establish_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;adapter: &lt;/span&gt;&lt;span class="s1"&gt;'sqlite3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;database: &lt;/span&gt;&lt;span class="s1"&gt;':memory:'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="ss"&gt;:orders&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt; &lt;span class="ss"&gt;:total&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="ss"&gt;:lock_version&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;

&lt;span class="n"&gt;object_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;object_2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;object_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="n"&gt;object_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt; &lt;span class="c1"&gt;# Succeeds!&lt;/span&gt;

&lt;span class="n"&gt;object_2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;span class="n"&gt;object_2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt; &lt;span class="c1"&gt;# Raises ActiveRecord::StaleObjectError&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see from the example that both &lt;code&gt;object_1&lt;/code&gt; and &lt;code&gt;object_2&lt;/code&gt; were loaded at the same time.&lt;/p&gt;

&lt;p&gt;When you modify and change the first object, it will be saved without any problem and the &lt;code&gt;save&lt;/code&gt; method will return true as expected, but when you try and save the second one (&lt;code&gt;object_2&lt;/code&gt;), the &lt;code&gt;ActiveRecord::StaleObjectError&lt;/code&gt; will be raised because the object has been modified already.&lt;/p&gt;

&lt;p&gt;You can read more about this feature directly on its API documentation.&lt;br&gt;
It is worth mentioning that there is a more aggressive way to lock records by using &lt;code&gt;Pessimistic Locking&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>rails</category>
    </item>
    <item>
      <title>ARM-Based Macs from the developer's perspective</title>
      <dc:creator>michelada.io</dc:creator>
      <pubDate>Tue, 27 Oct 2020 16:34:35 +0000</pubDate>
      <link>https://dev.to/micheladaio/arm-based-macs-from-the-developer-s-perspective-42ap</link>
      <guid>https://dev.to/micheladaio/arm-based-macs-from-the-developer-s-perspective-42ap</guid>
      <description>&lt;p&gt;A few days ago, Apple revealed its plans to integrate processors with ARM architecture in its desktops, leaving aside Intel processors with x86. But what does this mean for us developers? Currently, the vast majority of projects do not consider the architecture to which our software will be destined, since the heavy load is carried by compilers that allow us to distribute our software for different platforms. &lt;/p&gt;

&lt;p&gt;This does not mean that we leave the problem unattended in the medium and long term.&lt;/p&gt;

&lt;p&gt;ARM is everywhere&lt;/p&gt;

&lt;p&gt;First of all, let's talk about the elephant in the room. ARM architecture is everywhere: from our mobile devices to our vehicles, and even on our consoles and graphics cards. This is because ARM's business model is not manufacturing but the design and licensing of its processors. That is why companies such as AMD, Qualcomm, Nvidia, Nintendo, Apple among others, can have their own custom chips at a low cost. Also, with the internet of things gadget makers have enough processing power with low power consumption. That is why in the last decade this market has exploded, and surely there is an ARM processor near you.&lt;/p&gt;

&lt;p&gt;High-level languages&lt;/p&gt;

&lt;p&gt;Most of us work with very high-level languages ​​and in our work we do not focus on low-level issues, such as compatibility for different processors. As I mentioned before, this workload is left to the compilers, which allow us to have binaries for any architecture. In the case of Java with the introduction of android, its virtual machine had to be able to run on ARM processors and the only thing the development community did was adapt the ecosystem to limited resources and improve performance. In the case of languages ​​that depend on an interpreter, such as ruby ​​or python, they work perfectly well on embedded systems or on the raspberry pi. Even in Japan, the use of ruby ​​focuses more on this type of system. So this change should not concern the vast majority.&lt;/p&gt;

&lt;p&gt;Third party dependencies&lt;/p&gt;

&lt;p&gt;However, not all the code we produce comes from our hands. Many times we depend on the work of others, who in turn depend on others and so on. This practice of free software has made life easier for us and thanks to it we have avoided reinventing the wheel in each project. However, we may have dependencies that are tied to a certain architecture, and this may be happening without us noticing.&lt;br&gt;
To avoid this we have to test our code on different platforms. The most accessible option would be to test our production project on a RaspberryPI or BeagleBone. Maybe our software requires much more processing power, but at least we will know if in the near future our dependencies work, or if we need to make adjustments.&lt;/p&gt;

&lt;p&gt;But it works in my local&lt;/p&gt;

&lt;p&gt;For those who are familiar with this phrase, "Brace yourself" because if you are a backend developer, we may say it more often than we are used to. Since the difference in the instruction set of our development environments, with our production environments, will be considerable. Although if we make the transition well, the problems in development environments could be annoying but manageable.&lt;br&gt;
Fortunately, mobile development would benefit, since the applications would be developed in environments very close to mobile devices. Both the Android emulator and the iOS simulator will have a significant advantage.&lt;/p&gt;

&lt;p&gt;ARM on the server?&lt;/p&gt;

&lt;p&gt;Currently in the backend, our projects work in the cloud. Whether from Amazon, Google, or another. And while the data center market is entirely dominated by Intel, this does not mean that these cloud service companies are not looking for alternatives with a better cost benefit. In economic terms, reducing energy and cooling costs can have a great impact on the profits of these companies; since feeding and maintaining these facilities at an optimal operating temperature is really expensive, so in the near future it will be more common to see "eco-friendly" options in the backend, without the need to sacrifice performance.&lt;/p&gt;

&lt;p&gt;In conclusion, ARM is a technology with more than 30 years in the market, which in the last decade has been embedded in various industries. And thanks to its thermal efficiency and energy consumption, it is very attractive for a future where efficiency is above raw performance. And this technological change should not take us by surprise, because whether we like it or not, Apple leads the trends in the market.&lt;/p&gt;

</description>
      <category>serverless</category>
    </item>
    <item>
      <title>Women and technological development.</title>
      <dc:creator>michelada.io</dc:creator>
      <pubDate>Tue, 27 Oct 2020 15:54:45 +0000</pubDate>
      <link>https://dev.to/micheladaio/women-and-technological-development-5ao7</link>
      <guid>https://dev.to/micheladaio/women-and-technological-development-5ao7</guid>
      <description>&lt;p&gt;Maitetxu Larraechea is a Chilean journalist, historian and currently director of Girls in Tech; an organization with a presence in 40 countries that promotes the participation of women in the development of technology. In November 2015, during his TED Talk in Chile, she shared some information to bear in mind. One of them, which she refers to as a dramatic figure, is that of the total startup founders in the world, only 5% are women.&lt;/p&gt;

&lt;p&gt;It is curious that in an era where information technologies have become increasingly important in aspects such as entrepreneurship, inclusion, and problem solving, education and others, the participation of women has been reduced in recent years.International data affirm that in the 80s, the percentage of women graduated from careers related to programming was 37%, while currently the figure has been reduced to 12%.What are the reasons why the presence of women in technological development is markedly inferior to that of men?&lt;/p&gt;

&lt;p&gt;In an interview with CNN, Maitetxu believes that it has to do with cultural aspects of parenting; It is very common for girls to be encouraged to opt for careers that make motherhood compatible, so they will grow up perceiving that programming and other sciences are work camps for men.&lt;/p&gt;

&lt;p&gt;Another important factor is the lack of visibility of successful women in the development of technology. We know and have enjoyed great media coverage names such as Steve Jobs, Bill Gates and Elon Musk, while most unfamiliar people with information technologies are unaware of the contributions of women like Ada Lovelace, creator of the first algorithm that could be processed by a machine or Hedy Lamarr, a fundamental contributor to the development of WiFi. &lt;/p&gt;

&lt;p&gt;Fortunately, not everything is a setback, Larraechea also states that investors are increasingly aware of the profitability of having women in management positions in technology companies. A study by the Kauffman Foundation states that the return on investment of a female CEO can be up to 35% more than a man. Features such as greater meticulousness, organization, and great ease for communication, make them excellent leaders and developers.&lt;/p&gt;

&lt;p&gt;The evolution of technology comes hand in hand with creative diversity. A set of unique minds looking for solutions in common for the problems of humanity.If the creative space is reduced to a percentage of individuals, the development of technology and society will be affected.&lt;/p&gt;

&lt;p&gt;For Mariana Costa, Peruvian developer, programming is the language of the future. A skill that transforms. After realizing the lack of diversity in this area, the task of creating a program for women called Laboratoria was created, where she started with 16 girls who, she says, went from ignoring what a web browser is to graduate as developers web front end. Today his initiative has managed to train hundreds of women and obtained various awards and alliances with companies such as Google and Microsoft.&lt;/p&gt;

&lt;p&gt;Like her, there are thousands of women who, with their talent and skills, are making a great effort to generate awareness and knowledge. There is a long way to go. It is the task of all of us to support the momentum of this growth, eliminating prejudices and recognizing much more its work in an area in which its participation is indispensable for technological development and therefore of humanity.&lt;/p&gt;

</description>
      <category>womenintech</category>
    </item>
    <item>
      <title>Ruby on Rails</title>
      <dc:creator>michelada.io</dc:creator>
      <pubDate>Tue, 27 Oct 2020 15:46:14 +0000</pubDate>
      <link>https://dev.to/micheladaio/ruby-on-rails-2401</link>
      <guid>https://dev.to/micheladaio/ruby-on-rails-2401</guid>
      <description>&lt;p&gt;Ruby is a programming language. It was created 20 years ago by Yukihiro "Matz" Matsumoto. According to most measures of popularity of the programming language, Ruby is in the top ten, although it is generally the tenth (more or less) in popularity, and largely due to Rails' popularity. Like Java or the C language, Ruby is a general purpose programming language, although it is best known for its use in web programming.&lt;/p&gt;

&lt;p&gt;Rails is a software library that extends the Ruby programming language. David Heinemeier Hansson is its creator. He named it "Ruby on Rails", even though it is often simply called "Rails". It is a software code added to the Ruby programming language. Technically, it is a package library (specifically, a Ruby Gem), which is installed using the command line interface of the operating system.Rails is a framework for building websites. As such, Rails establishes conventions to facilitate collaboration and maintenance. &lt;/p&gt;

&lt;p&gt;These conventions are coded as the Rails API (the application programming interface or directives that control the code). The Rails API is documented online and described in books, articles and blog posts. "Learning Rails" means learning to use the Rails conventions and their API.Rails combines the Ruby programming language with HTML, CSS &amp;amp; JavaScript to create a web application that runs on a web server. Because it runs on a web server, Rails is considered a server-side web application development platform or "back-end" (the web browser is the "front-end").&lt;/p&gt;

&lt;p&gt;Rails, in a deep sense, is more than a software library &amp;amp; an API. Rails is the central project of a wide "community" that produces software libraries that simplify the task of building complex websites. The members of this Rails community share many fundamental values, they often use the same tools and support each other with an informal network. That means they do it just for love to the development. The community is something informal, but that does not detract it from professionalism. It forms an economic network that includes: jobs, recruiters, consulting firms, conferences and companies that create websites with Rails and investors that finance new companies. &lt;/p&gt;

&lt;p&gt;Rails is popular among web startups, significantly by the set of "libraries" or open source software libraries (RubyGems or "gems") that make possible to build complex sites quickly (although without much style ... please don't kill me ) that work perfectly.Do you need to study Ruby to learn Rails?Your most difficult challenge will be to learn (or understand) the names of the structures where you see code examples. This is why it is useful to follow a brief introduction to Ruby. You should be able to recognize when you are seeing a matrix or a hash. You must recognize when you are looking at an iterator or the syntax of a block with Ruby. Eventually, you will recognize more exotic Ruby formulations such as lambda. It's fine if you can't write a lambda function or even know when to use it; Many Rails developers start working before learning Ruby in depth.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
    </item>
    <item>
      <title>Render dangerous content with React</title>
      <dc:creator>michelada.io</dc:creator>
      <pubDate>Tue, 27 Oct 2020 15:27:41 +0000</pubDate>
      <link>https://dev.to/micheladaio/render-dangerous-content-with-react-38pa</link>
      <guid>https://dev.to/micheladaio/render-dangerous-content-with-react-38pa</guid>
      <description>&lt;p&gt;FYI All the content of this post suits best for some edge cases, and the solution proposed here is probably not the more safe way to do it.&lt;br&gt;
Cross-site Scripting (XSS Attacks)&lt;/p&gt;

&lt;p&gt;Among all the web vulnerabilities, one of the most common is cross-site scripting, this type of vulnerability allows the attackers to inject scripts on the page to get access to any sensitive information the browser and the site are sharing (cookies, tokens, etc...).&lt;/p&gt;

&lt;p&gt;This attack occurs when the data entered is coming from an untrusted source or the data that is sent to the user include dynamic content without been validated first.Although there are limitless varieties of XSS attacks, Javascript XSS attacks seems to be popular among hackers.&lt;/p&gt;

&lt;p&gt;Types of XSS Attacks&lt;/p&gt;

&lt;p&gt;There are 3 types of XSS attacks:&lt;/p&gt;

&lt;p&gt;Stored XSS Attacks occurs when the injected script is store on the server (i.e. store on a database) so each time the user request a something from the server the malicious script is sent to the client.&lt;/p&gt;

&lt;p&gt;Reflected XSS Attacks happens when the malicious script is reflect on the web that's vulnerable, this could be due to a click on an email link that's malformed or any other external source.&lt;/p&gt;

&lt;p&gt;DOM Based XSS Attacks is a vulnerability that occurs on the DOM (Document Object Model) instead of the HTML.&lt;br&gt;
Let's say you have this code on your app:&lt;/p&gt;

&lt;p&gt;Now, imagine someone visits your site using the URL &lt;a href="https://www.nicesite.com/index.html#"&gt;https://www.nicesite.com/index.html#&lt;/a&gt;alert(&amp;amp;#39;test&amp;amp;#39;), the script will be executed because the code above writes whatever comes on url to the document using document.write.&lt;/p&gt;

&lt;p&gt;We can point one of the main differences between this type of XSS attack and the Stored and Reflected: The servers can't stop this attack, since the hash (#) part of the url is not being sent to the server on the request.&lt;/p&gt;

&lt;p&gt;Prevent XSS Attacks&lt;br&gt;
For most of the XSS attacks the solution is simple, just sanitize your input data, even if comes from a trusted source.Doing this will ensure that no matter what's the input or output, is always secure.&lt;/p&gt;

&lt;p&gt;Javascript offers us plenty ways to interact with the DOM, so we can works with dynamic content in an easy way, but we need to be careful on how to use it, since it can make vulnerable our websites.&lt;/p&gt;

&lt;p&gt;Inputs &amp;amp; Outputs&lt;/p&gt;

&lt;p&gt;Here's a tiny list of the most common input and outputs that can be dangerous to use with javascript.&lt;/p&gt;

&lt;p&gt;INPUTS: &lt;/p&gt;

&lt;p&gt;document.URL&lt;br&gt;
document.documentURI&lt;br&gt;
location.href&lt;br&gt;
OUTPUTS:&lt;br&gt;
document.write&lt;br&gt;
element.innerHTML&lt;br&gt;
element.src (in some elements like img)&lt;/p&gt;

&lt;p&gt;React and cross-site scripting&lt;/p&gt;

&lt;p&gt;Nowadays all the web apps required some dynamism, from having a multiple step form that shows different question depending on your answers to a simple tables that filter out information, this is where Javascript enters to the equation.&lt;br&gt;
Back in time, when Javascript vainilla was enough to get everything done (which still is, we just 'syntax-sugar' it), one of the way you could handle insertion of dynamic content, was using innerHTML property.&lt;/p&gt;

&lt;p&gt;Element.innerHTML:The Element property innerHTML gets or sets the HTML or XML markup contained within the element&lt;br&gt;
So, you can set the HTML content from an element using this property, but what happen when the content has an script inside?&lt;/p&gt;

&lt;p&gt;The first 2 lines create a variable that holds a plain string, then using innerHTML set the content of an element to be this value, so far so good, nothing harmless here.&lt;br&gt;
On the next 2 lines of code we do the same, but this time, the string value is html-like with a  tag within it, so what would you think will be the output?&amp;lt;br&amp;gt;
Well, if you though that this will result on an alert prompting to the user that he has been hacked, well you are wrong.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;HTML5 specifications says that scripts inserted using innerHTML shouldn&amp;amp;#39;t execute.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Easy to be safe&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;React follows the philosophy &amp;amp;quot;easy to be safe&amp;amp;quot;, that&amp;amp;#39;s why we as developers should be explicit if we want to go for the unsafe path, and this is the case for the dangerouslySetInnerHTML prop.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;This prop allows you to inject dynamic html to an element, all you need to do is pass and object with a single property: __html, with a string html-like of what you want to render:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;As you can see, seems a little odd that you have to pass an object when it could be a simple string, but this is done intentionally, to remind you that it&amp;amp;#39;s dangerous and you should avoid using it as much as possible.&amp;lt;br&amp;gt;
innerHTML vs dangerouslySetInnerHTML&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Writing React doesn&amp;amp;#39;t mean that you can&amp;amp;#39;t use the features that Javascript offer us, you can use innerHTML to add the dynamic html to a react component and it will work the same (both will update the node with the html), but it can lead to undesired performance issues.&amp;lt;br&amp;gt;
React uses a virtual DOM and a diffing algorithm to compare what&amp;amp;#39;s been updated and re-render the content, this process is called reconciliation.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Using dangerouslySetInnerHTML you can tell React to ignore all the dynamic html during reconciliation&amp;lt;br&amp;gt;
When you use innerHTML to set the content, all the dynamic html that was generated is included in the reconciliation process, aside performance issues, React could wrongly update the dynamic html.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Since both properties works the same (in fact dangerouslySetInnerHTML implements innerHTML to set the content) they both share kinda the same vulnerabilities, hence the importance of sanitizing your input sources.&amp;lt;br&amp;gt;
Render the danger&amp;lt;br&amp;gt;
Now what happens when you want to use dangerouslySetInnerHTML but also need to execute any script tag that comes inside the html? That&amp;amp;#39;s against HTML5 specifications, but if we dig a little bit more on what innerHTML do to inject the html we can found something interesting:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The specified value is parsed as HTML or XML (based on the document type), resulting in a DocumentFragment object representing the new set of DOM nodes for the new elements.&amp;lt;br&amp;gt;
This DocumentFragment is a lightweight version of the document, it can have child nodes, the main difference is that since is a fragment, is not actually a part of the active/main document.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;We can create a DocumentFragment using the document.Range API.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;This code snippet will create a DocumentFragment object, parse the value of the html variable and store the result on a variable called node. All we have to do is render this variable:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;If we translate all of this to a React component we end up with something like this:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;This way we could pass a string with html content that includes &amp;lt;script&amp;gt; tags, and those will be executed  (works with &amp;lt;script&amp;gt; .. content ..  and )&lt;/p&gt;

&lt;p&gt;dangerously-set-html-content is a tiny (297B Gzipped), no-dependencies, library that allows you to render dynamic html and execute any scripts tag within it.&lt;br&gt;
1) Add it to your project:&lt;/p&gt;

&lt;p&gt;2) Start using it:&lt;/p&gt;

&lt;p&gt;Of course this doesn't prevent any attack (in fact, does the opposite of that), but sometimes this functionally could be what you are looking for.&lt;br&gt;
I built this because I actually needed this functionality.&lt;/p&gt;

&lt;p&gt;Conclusions&lt;/p&gt;

&lt;p&gt;All the web is full of vulnerabilities that can cause you headaches if you are not aware of how to prevent them. Mostly of the common frontend libraries already handle a few of these in a way, so you don't have to worry about it‌ but still is good to know what we are dealing with as front-end developers.&lt;/p&gt;

&lt;p&gt;Additionally of what React offers us, there are several techniques that can help you to prevent an attack, so if you are having a problem of this type just head to the docs and you'll probably find the solution.&lt;/p&gt;

&lt;p&gt;While 99% of the time all this magic behind React works perfectly for us, sometimes we can found ourselves struggling with it, but in the end is just Javascript so embracing both will help us to find the solution to our problem.&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

</description>
      <category>reactnative</category>
    </item>
    <item>
      <title>Full-stack web app with NextJS and GraphQL</title>
      <dc:creator>michelada.io</dc:creator>
      <pubDate>Tue, 27 Oct 2020 15:22:25 +0000</pubDate>
      <link>https://dev.to/micheladaio/full-stack-web-app-with-nextjs-and-graphql-9le</link>
      <guid>https://dev.to/micheladaio/full-stack-web-app-with-nextjs-and-graphql-9le</guid>
      <description>&lt;p&gt;When we talk about developing a front end application with ReactJS, we can find three main options: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;CRA&lt;/code&gt;: focuses on building single-page web applications but has difficulties with SEO positioning. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Gatsby&lt;/code&gt;: focuses on static site generation with great performance and cool SEO and data-fetching.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NextJS&lt;/code&gt;: in my opinion, the best way to write ReactJS web applications nowadays since it offers server-side rendering with the option of making it client-side, cool built-in routing, zero-configuration philosophy and, since NextJS 9, this framework provides API routes which is a really easy way to provide back-end code to our react app and, this is what we are using for this post. &lt;/p&gt;

&lt;p&gt;In this post, we are going to learn how we can implement a GraphQL API running over an API route.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basic NextJS app
&lt;/h2&gt;

&lt;p&gt;As I mentioned before, NextJS focuses on a zero-configuration philosophy we can easily configure but, to make it even easier, let's just type &lt;code&gt;npx create-next-app todo-app&lt;/code&gt; in our terminal to have it ready to use. Once the project is setup, let's run &lt;code&gt;cd todo-app&lt;/code&gt; and type &lt;code&gt;yarn dev&lt;/code&gt; to run the server and see that everything is running.&lt;/p&gt;

&lt;h2&gt;
  
  
  The API Route
&lt;/h2&gt;

&lt;p&gt;Cool!, We now have our NextJS web app up and running. Let's create a new file inside &lt;code&gt;pages/api/&lt;/code&gt; called &lt;code&gt;graphql.js&lt;/code&gt; and let's add the following 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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GRAPHQL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, if we go to &lt;code&gt;localhost:3000/api/graphql&lt;/code&gt;,  we'll be able to see the text GRAPHQL written. Easy!. Let's now configure GraphQL!.&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install it
&lt;/h3&gt;

&lt;p&gt;First, let's add a dependency called &lt;code&gt;apollo-server-micro&lt;/code&gt; by writing &lt;code&gt;yarn add apollo-server-micro&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Our Schema
&lt;/h3&gt;

&lt;p&gt;The next thing we need to work with GraphQL is writing our schema, which will define the Queries and Mutations we have and how the data is structured. For now, we want to have a query called &lt;code&gt;hello&lt;/code&gt; which will return a string. So, let's add the following to the top of our route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apollo-server-micro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="err"&gt;
  type Query {
    hello: String!
  }
&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;h3&gt;
  
  
  Resolvers
&lt;/h3&gt;

&lt;p&gt;We have just written our schema, but now GraphQL needs the resolvers of our schema, which tell GraphQL where to fetch our data from. Below the schema, let's add our resolvers:&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;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_context&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="s2"&gt;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The server
&lt;/h3&gt;

&lt;p&gt;Now, let's create our server with our schema and resolvers.&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;apolloServer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ApolloServer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;typeDefs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;resolvers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&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;Cool! With this instance, we can access a handler, which is in charge of handling all the requests and responses and, as we are actually working with NextJS, we need to specify that we don't need &lt;code&gt;bodyParser&lt;/code&gt; in our requests.&lt;/p&gt;

&lt;p&gt;Let's remove the last &lt;code&gt;export default&lt;/code&gt; and change it for the following 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;handler&lt;/span&gt; &lt;span class="o"&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;createHandler&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/graphql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;bodyParser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We have now a basic configuration of a GraphQL server; why don't we go to &lt;code&gt;localhost:3000/api/graphql&lt;/code&gt; and see what we have now?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hu71VH5L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Lmo7F5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hu71VH5L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Lmo7F5j.png" alt="graphql running image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And, if we run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;hello&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;We will have our response from the resolver.  &lt;/p&gt;

&lt;h3&gt;
  
  
  CORS
&lt;/h3&gt;

&lt;p&gt;We need another thing to use this API from the front-end so, let's add a new package by typing &lt;code&gt;yarn add micro-cors&lt;/code&gt; and let's add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt;  &lt;span class="nx"&gt;Cors&lt;/span&gt;  &lt;span class="k"&gt;from&lt;/span&gt;  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;micro-cors&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;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nx"&gt;Cors&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
    &lt;span class="na"&gt;allowMethods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OPTIONS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;  

&lt;span class="c1"&gt;// Here is how we connect our handler with CORS.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data from Postgres with Knex.
&lt;/h3&gt;

&lt;p&gt;At some point, our app would need some sort of access to a database to persist some data. For this, we will need to set up some stuff so let's do it! First, let's add Knex and Postgres with &lt;code&gt;yarn add knex pg&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Create a file called &lt;code&gt;knexfile.js&lt;/code&gt; with our database configuration:&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgresql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgres://postgres@localhost:5432/todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;migrations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;knex_migrations&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;Next, let's create our first migration, which will tell Postgres how to create our tables. Let's start by typing &lt;code&gt;yarn run knex migrate:make create_todo&lt;/code&gt; and inside the folder &lt;code&gt;migrations&lt;/code&gt; we will have a new file generated, let's open it and add how we want our table to be created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;up&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;knex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;knex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;increments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;notNullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;done&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;defaultTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;notNullable&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;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;down&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;knex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;knex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dropTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And let's build our table by running &lt;code&gt;yarn run knex migrate:up&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Now, we need to create a constant which will help us manage the database inside our code. Let's open &lt;code&gt;/pages/api/graphql.js&lt;/code&gt; and add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;knex&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;knex&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;knex&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgres://postgres@localhost:5432/todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Updating our schema
&lt;/h3&gt;

&lt;p&gt;Why don't we change our schema and resolvers?&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;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="err"&gt;
  type Query {
    todos: [Todo]!
    todo(id: ID!): Todo
  }

  type Todo {
    id: ID!
    description: String!
    done: Boolean!
  }
&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolvers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;where&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we now go to &lt;code&gt;localhost:3000/api/graphql&lt;/code&gt;, we'll finally be able to fetch and play with our data!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FudLlbcK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/FBiig6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FudLlbcK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/FBiig6g.png" alt="empty query image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But, wait a minute! How are we going to create data? Well...&lt;/p&gt;

&lt;p&gt;Let's go and see how we can add a &lt;code&gt;Mutation&lt;/code&gt; which will help us create data inside our database!&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating data
&lt;/h3&gt;

&lt;p&gt;First, we have to add a new type inside our schema. We first need to specify the name of the mutation, in this case &lt;code&gt;createTodo&lt;/code&gt;, and then inside the parenthesis the names and types of values that we will receive. At the end, we need to specify what our mutation will return, in this case, a &lt;code&gt;Todo&lt;/code&gt; 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="err"&gt;
  ...

  type Mutation {
    createTodo(description: String!, done: Boolean): Todo
    completeTodo(id: ID!): Todo
  }
&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, inside our &lt;code&gt;resolvers&lt;/code&gt; object, let's add the new &lt;code&gt;Mutation&lt;/code&gt; key and the &lt;code&gt;createTodo&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;resolvers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="na"&gt;Mutation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;createTodo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;_c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;returning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;completeTodo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;_c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;where&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;returning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="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;And with this, now we can create and complete ToDos in our database&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TkR5QhI8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/YCvJP8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TkR5QhI8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/YCvJP8n.png" alt="create ToDo image"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kiA-QZ2J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/31SOBFY.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kiA-QZ2J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/31SOBFY.png" alt="complete ToDo image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool, but what about the Front-end?&lt;/p&gt;
&lt;h2&gt;
  
  
  The client
&lt;/h2&gt;

&lt;p&gt;Until now, we have been building the server-side of our application by integrating GraphQL in an API route: why don't we integrate the client side of our app?&lt;/p&gt;
&lt;h3&gt;
  
  
  Dependencies
&lt;/h3&gt;

&lt;p&gt;Let's start by adding two dependencies we need to connect to GraphQL:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add @apollo/react-hooks apollo-boost&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Provider
&lt;/h3&gt;

&lt;p&gt;First, let's setup the Apollo Client of our app. For this, let's open &lt;code&gt;pages/_app.js&lt;/code&gt; and add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../styles/globals.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApolloProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@apollo/react-hooks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ApolloClient&lt;/span&gt;&lt;span class="p"&gt;,&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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apollo-boost&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ApolloClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:3000/api/graphql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ApolloProvider&lt;/span&gt; &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ApolloProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyApp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Query
&lt;/h3&gt;

&lt;p&gt;Now, let's open our &lt;code&gt;pages/index.js&lt;/code&gt; and import what we are going to need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMutation&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@apollo/react-hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apollo-boost&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;We first need to declare our GraphQL query exactly as we would do in the GraphQL Playground:&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;GET_TODOS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="err"&gt;
  query {
    todos {
      id
      description
      done
    }
  }
&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, inside our component, we are going to use the query and map through them to render them in the app&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Home&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;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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="nx"&gt;refetch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GET_TODOS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;ERROR :(&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My TODO list&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
              &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Done&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Complete&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we should see our ToDos on the browser. Let's add a way to create ToDos.&lt;/p&gt;

&lt;p&gt;Let's start by adding the &lt;code&gt;createTodo&lt;/code&gt; mutation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CREATE_TODO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="err"&gt;
  mutation CreateTodo(&lt;/span&gt;&lt;span class="s2"&gt;$&lt;/span&gt;&lt;span class="err"&gt;description: String!) {
    createTodo(description: &lt;/span&gt;&lt;span class="s2"&gt;$&lt;/span&gt;&lt;span class="err"&gt;description) {
      id
      description
      done
    }
  }
&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, inside our component, we add some state management, our mutation, and our form to perform the mutation. The file will end up looking like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Home&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;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;createTodo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CREATE_TODO&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;saveTodo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;createTodo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;todo&lt;/span&gt; &lt;span class="p"&gt;}});&lt;/span&gt;
    &lt;span class="nx"&gt;refetch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;setTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My TODO list&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;saveTodo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          New todo
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Save&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      ...

    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Completing todos
&lt;/h3&gt;

&lt;p&gt;Pretty straightforward! Why don't we add our &lt;code&gt;completeTodo&lt;/code&gt; mutation and add functionality to our buttons?&lt;/p&gt;

&lt;p&gt;Here we have our mutation declaration:&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;COMPLETE_TODO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="err"&gt;
  mutation CompleteTodo(&lt;/span&gt;&lt;span class="s2"&gt;$&lt;/span&gt;&lt;span class="err"&gt;id: ID!) {
    completeTodo(id: &lt;/span&gt;&lt;span class="s2"&gt;$&lt;/span&gt;&lt;span class="err"&gt;id) {
      id
    }
  }
&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, inside our component, we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Home&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;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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="nx"&gt;refetch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GET_TODOS&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;createTodo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CREATE_TODO&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;completeTodo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;COMPLETE_TODO&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;saveTodo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;createTodo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;todo&lt;/span&gt; &lt;span class="p"&gt;}});&lt;/span&gt;
    &lt;span class="nx"&gt;refetch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;setTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onComplete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;completeTodo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}});&lt;/span&gt;
    &lt;span class="nx"&gt;refetch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;ERROR :(&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My TODO list&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;saveTodo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          New todo
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Save&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
              &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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="nx"&gt;onComplete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Done&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Complete&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, if now we go to our browser, we can see our app working!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7jbOy7n9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media0.giphy.com/media/TdG9m7QLteD7bFC7Sx/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7jbOy7n9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media0.giphy.com/media/TdG9m7QLteD7bFC7Sx/giphy.gif" alt="app running"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;GraphQL is a technology that has been growing a lot in the last couple of years and so has NextJS. Now that we can have API routes in our NextJS app, we can integrate them to build a delightful stack able to behave as a monolith and, who knows, maybe even run in a serverless architecture 🤔.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Trying regular expressions in Ruby</title>
      <dc:creator>michelada.io</dc:creator>
      <pubDate>Tue, 27 Oct 2020 15:15:38 +0000</pubDate>
      <link>https://dev.to/micheladaio/trying-regular-expressions-in-ruby-44mn</link>
      <guid>https://dev.to/micheladaio/trying-regular-expressions-in-ruby-44mn</guid>
      <description>&lt;p&gt;Is understanding regular expressions difficult to you? It usually happens to me and, for such reason, I decided to read and reread information about this topic. I wrote down some notes which I think will be enough to work with them when I need it and I would like to share them with you:&lt;br&gt;
We can create a Ruby RegEx with // or %r{}  which are the literal constructors of it.&lt;/p&gt;

&lt;p&gt;And both are instances of the RegEx class&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;The String class has also the match? method:&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;The number 11 was returned because the expression matched the word are and the position of its first character is 11. It can be proved:&lt;/p&gt;

&lt;p&gt;String class has also the =~ method:&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;To use a special character in a ReGex, it needs to be escaped. For example:&lt;/p&gt;

&lt;p&gt;It is also possible to get a match if the dot sign is not escaped, but it is not the match we are looking for, let's prove it:&lt;/p&gt;

&lt;p&gt;To escape a character, the backslash character \ needs to be positioned just before the desired character, like with the previous example with the dot .&lt;/p&gt;

&lt;p&gt;This character used on a ReGex matches everything with all characters on a string, except if there is a newline \n&lt;/p&gt;

&lt;p&gt;If we inspect what the expression matched, we get:&lt;/p&gt;

&lt;p&gt;This expression expects that any character exists just before the pattern ated&lt;br&gt;
The dot . doesn't match a newline \n&lt;br&gt;
Example:&lt;/p&gt;

&lt;p&gt;Inside of the brackets, many characters can be listed, and any of them can be matched&lt;br&gt;
Example test a string to know if it has a vowel:&lt;/p&gt;

&lt;p&gt;And more characters can be added to the expression just after the brackets:&lt;/p&gt;

&lt;p&gt;In this example, the character r inside the brackets, plus the characters out of them uby matches with the word ruby&lt;/p&gt;

&lt;p&gt;Ranges can be created inside the brackets, example:&lt;/p&gt;

&lt;p&gt;All of these abbreviations have a negative version that matches the opposite from the positive versions&lt;/p&gt;

&lt;p&gt;For example, let's capture the strings "Lenin Godinez" and "40" from the next string:&lt;/p&gt;

&lt;p&gt;With the pattern ([A-Za-z]+\s[A-Za-z]+) the words "Lenin Godinez" are captured  and, with the pattern (\d+), the number "40" is captured&lt;br&gt;
All the captures automatically are assigned to global variables. On the previous example, the two captures were stored on the global variables $1 and $2 and we can test it using puts:&lt;/p&gt;

&lt;p&gt;The captures can be accessed the same way we get an element from an array: sending an index:&lt;/p&gt;

&lt;p&gt;If zero is indicated as the index on the m variable, the complete match is returned:&lt;/p&gt;

&lt;p&gt;A useful method from the MatchData object is the method captures which returns an array with the captures:&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;The captures can be accessed in the same way we get the value from a hash: sending a key, being the key the name of the capture&lt;br&gt;
Example:&lt;/p&gt;

&lt;p&gt;Also, there is a useful method to get the named captures: the method named_captures that returns a hash with the captures:&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;If we remove the modifier ? from the pattern and the letter s from "Mrs." on the string, we can see that the test fails, because it is looking for the pattern Mrs&lt;/p&gt;

&lt;p&gt;Now, if we return the modifier ? to the pattern, this time we will get a match with "Mr." because the character s on the pattern is optional&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;If the modifier is removed from this expression, only the first number from 31 is matched&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;If we modify the string to be only "Name: Lenin", the expression continues matching since more characters after the word "Lenin" are just optional, thanks to the modifier *&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
If I want to match the format phone number 111-111-1111&lt;/p&gt;

&lt;p&gt;Also, we can indicate a minimum and maximum of repetitions with a range as {1,n} The first number indicates the minimum and the second number indicates the maximum of repetitions.&lt;br&gt;
Example:&lt;/p&gt;

&lt;p&gt;On thin example, four numbers are matched, because we asked for at least one number and four as maximum&lt;br&gt;
If the string to be evaluated has less characters than the maximum indicated on the pattern, then all characters are matched&lt;/p&gt;

&lt;p&gt;If the minimum amount is not reached, then the expression returns nil&lt;/p&gt;

&lt;p&gt;If the second number on the range is not indicated, it only will take the minimum amount and the maximum amount will be open:&lt;/p&gt;

&lt;p&gt;Also, if the minimum amount is not reached, then the expression returns nil&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;The match can also be found at the beginning of a newline&lt;/p&gt;

&lt;p&gt;If we try to look the comment up between the string, we won't get a match and a nil will be returned&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
If we want to match the dot that appears at the end of the line of the next string:&lt;/p&gt;

&lt;p&gt;If we try to match the word "currently" that starts on a new line, it is not matched because this anchor does not work for that purpose.&lt;/p&gt;

&lt;p&gt;If we try to match the end of a line, it will return nil&lt;/p&gt;

&lt;p&gt;If the same string is evaluated with the anchor \z, then we won't get a match due to the new line indicated at the end of the string&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
There is a list of numbers and I want to match the numbers that ends with a dot, but I don't want to include the dot sign on the result of the match. The lookahead assertion needed is (?=.) with the dot escaped inside it:&lt;/p&gt;

&lt;p&gt;On the other hand, there is a negative version of this lookahead assertion&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;The result is "123" because it was the first match that the pattern found with the indications "A series of numbers without a dot placed at the end of it"&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
I want to match the word "regex" only if the word "ruby" is placed just before of it in the next string:&lt;/p&gt;

&lt;p&gt;And its negative version is:&lt;/p&gt;

&lt;p&gt;In this example, nil is returned because the "regex" word is preceded by the word "ruby", so the match is not successful. To get a match, the string needs to be modified.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;This method helps to escape characters from a string.&lt;br&gt;
Example:&lt;/p&gt;

&lt;p&gt;This method evaluates a string from left to right and returns an array with all the matches found&lt;br&gt;
Example:&lt;/p&gt;

&lt;p&gt;It is possible to make captures with the scan method: if something is matched, an array of arrays is returned with the results&lt;br&gt;
Example:&lt;/p&gt;

&lt;p&gt;If a RegEx is sent as a parameter on this method, this evaluates each element from the array and, if it matches the pattern, then it is returned on an array. All elements that pass the test are returned in the array&lt;br&gt;
Example:&lt;/p&gt;

&lt;p&gt;Only 2 elements from the array matched the expression, and it can be proved as follows:&lt;/p&gt;

&lt;p&gt;And that is it! All you need to do is practice and practice with them to get more familiar. Feel free to reference this blog post if you have doubts.&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>You may not need websockets
</title>
      <dc:creator>michelada.io</dc:creator>
      <pubDate>Tue, 27 Oct 2020 15:10:42 +0000</pubDate>
      <link>https://dev.to/micheladaio/you-may-not-need-websockets-3knc</link>
      <guid>https://dev.to/micheladaio/you-may-not-need-websockets-3knc</guid>
      <description>&lt;p&gt;When you work on a feature that requires some sort of real time functionality, it's common to think about using websockets as a swiss knife capable of doing whatever you're being asked to do, but most of the times websockets can be overkill, to the point that it might add complexity to your tech stack making your life or someone else's (your beloved devops) even more complicated than it already is.&lt;/p&gt;

&lt;p&gt;You'll be wondering why, well, I don't want to bore you with the technical details and I want to keep this post very concise so everyone without decent network knowledge can understand my point. In case you're still curious about the reasons I'd recommend you to read this &lt;a href="https://samsaffron.com/archive/2015/12/29/websockets-caution-required"&gt;excellent post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, back to my point, first let's review the most common cases for real time features we can find in a web application. Based on my experience, I can give you a short list, I know there are others, but these are the ones that I recall at this moment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chat&lt;/li&gt;
&lt;li&gt;Page updates&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Financial tickers&lt;/li&gt;
&lt;li&gt;Real time data visualization&lt;/li&gt;
&lt;li&gt;Real time collaboration tools&lt;/li&gt;
&lt;li&gt;Multiplayer games&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let's break the list apart in two categories based on the type of communication they require: &lt;strong&gt;Unidirectional&lt;/strong&gt; vs &lt;strong&gt;Bi-directional&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Unidirectional
&lt;/h2&gt;

&lt;p&gt;This type of communication is for when you need communication to go one way only in this case, from the server to the client. In this category we can find the following use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Page updates&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Financial tickers&lt;/li&gt;
&lt;li&gt;Real time data visualization&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bi-directional
&lt;/h2&gt;

&lt;p&gt;Communication happens both ways, server and client can send messages back and forth to each other, ideal use cases of this type of communication are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chat&lt;/li&gt;
&lt;li&gt;Real time collaboration tools&lt;/li&gt;
&lt;li&gt;Multiplayer games&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, In which of these cases should I use websockets, well, I'd recommend you to use them only for Bi-directional communication and when your communication needs are very close to real time. Websockets are designed for this, multiplexed communication with very low latency, everything else can survive with a little bit of delay.&lt;/p&gt;

&lt;h2&gt;
  
  
  OK, but what do I use for everything else?
&lt;/h2&gt;

&lt;p&gt;Long polling can be considered in this case, but it's proven to be very inefficient in terms of CPU, memory and bandwidth usage, so, what do I use then?, enter &lt;a href="https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events"&gt;Server Sent Events (SSE)&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server Sent Events
&lt;/h2&gt;

&lt;p&gt;SSE are a mechanism where the client can get server pushes without having to ask for them as in a traditional client/server communication, you can think of SSE as one way pub-sub pattern where the clients subscribe to a stream, then the server can use this stream to push data to the client.&lt;/p&gt;

&lt;p&gt;At its core SSE are just a regular HTTP request/response, the only differences are in the &lt;code&gt;text/event-stream&lt;/code&gt; value we pass to the &lt;code&gt;Accept&lt;/code&gt;/&lt;code&gt;Content-Type&lt;/code&gt; headers of the request/response, the browser reads this as an instruction to create a persistent HTTP connection, once this persistent connection is established,  the client just needs to listen for messages coming in the stream, the server can push these messages whenever it wants and the connection is closed as soon of one of the sides decides that it needs to be closed.&lt;/p&gt;

&lt;p&gt;SSE is designed to be efficient, since it's a long lived connection, it reduces latency by eliminating costly handshakes, its protocol is simple and text based, offers gzip compression and it has a built in retry mechanism to handle broken connections.&lt;/p&gt;

&lt;p&gt;The client side implementation of SSE is handled by the &lt;a href="https://html.spec.whatwg.org/multipage/server-sent-events.html#eventsource"&gt;EventSource API&lt;/a&gt; described as part of the HTML5 standard, most modern browsers support it, except IE and Edge (of course), but don't worry, you can still use a polyfill.&lt;/p&gt;

&lt;p&gt;The EventSource API is quite simple, you just need to create a new &lt;code&gt;EventSource&lt;/code&gt; object, ie:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;evtSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;EventSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/updates&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;with this object, you can start listening for messages:&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;evtSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also listen for a specific event:&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;evtSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="p"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In case there’s any connection error, you can handle them 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;evtSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EventSource failed.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, when you want to close the stream:&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;evtSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server side implementation is simple as well, most web frameworks already have this implemented, I'll give you an example using the Ruby on Rails built it implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UpdatesController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Live&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Content-Type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'text/event-stream'&lt;/span&gt;
    &lt;span class="n"&gt;sse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SSE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;retry: &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;sse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hello world'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Live&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ClientDisconnected&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SSE client disconnected'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;ensure&lt;/span&gt;
    &lt;span class="n"&gt;sse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;you see?, it's just a normal Rails controller, nothing complicated (I'm watching you websockets).&lt;/p&gt;

&lt;h2&gt;
  
  
  With great power comes great responsibility
&lt;/h2&gt;

&lt;p&gt;Browsers have a limit for simultaneous open connections to the same server, the number is around 6 in most modern browsers, this mean you'll have one less connection available for when for example the user opens your app in a different browser window/tab, now let's say the user opens 6 tabs, then you will run out of available connections. There are a few techniques to deal with this, one of them is domain sharding, but be aware, this technique can be considered &lt;a href="https://http2.github.io/faq/#why-just-one-tcp-connection"&gt;harmful as well&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One application opening so many connections simultaneously breaks a lot of the assumptions that TCP was built upon; since each connection will start a flood of data in the response, there’s a real risk that buffers in the intervening network will overflow, causing a congestion event and retransmits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The only feasible solution to this problem could be &lt;strong&gt;HTTP/2&lt;/strong&gt; and its &lt;a href="https://http2.github.io/faq/#why-is-http2-multiplexed"&gt;multiplexing feature&lt;/a&gt;, and guess what, you can start &lt;a href="https://caniuse.com/#search=http2"&gt;using HTTP/2 today&lt;/a&gt;, topic that I'll tackle in a future post explaining how to implement SSE over HTTP/2 with NGINX and Ruby on Rails.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Next time you see a real time feature coming in your backlog, think twice about the solution you're need to offer, there's a big chance you’ll end up over engineering by using websockets, SSE is an excellent solution for most of the cases, so why don't you give it a try? &lt;/p&gt;

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