<?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: Michael Wolf Hoffman</title>
    <description>The latest articles on DEV Community by Michael Wolf Hoffman (@mwolfhoffman).</description>
    <link>https://dev.to/mwolfhoffman</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%2F376502%2Fba71bcac-fe86-4bef-ba92-3409f66bd7f0.jpeg</url>
      <title>DEV Community: Michael Wolf Hoffman</title>
      <link>https://dev.to/mwolfhoffman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mwolfhoffman"/>
    <language>en</language>
    <item>
      <title>Quitting Coffee as a Software Engineer</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Tue, 25 Jan 2022 21:36:34 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/quitting-coffee-as-a-software-engineer-2bip</link>
      <guid>https://dev.to/mwolfhoffman/quitting-coffee-as-a-software-engineer-2bip</guid>
      <description>&lt;h1&gt;
  
  
  Quitting Coffee as a Software Engineer
&lt;/h1&gt;

&lt;p&gt;I was a big coffee drinker for a long time. Before learning to code and becoming a software engineer, I was a laboratory scientist and technician. In most surveys, this is the profession that consumes the most coffee. &lt;br&gt;
However, software engineers are right up there near the top too in terms of caffeine consumption. &lt;/p&gt;

&lt;p&gt;I knew I was addicted and thought it would be good to decrease my caffeine consumption over time. In this post, I will talk about why and how I did that and what the results were.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Quit Caffeine
&lt;/h2&gt;

&lt;p&gt;There are many reasons it's good to decrease your caffeine consumption. &lt;a href="https://amzn.to/3rRKhpz"&gt;Caffeine Blues&lt;/a&gt; is a great book that I read that offers many reasons.&lt;/p&gt;

&lt;p&gt;A few of the reasons mentioned in this book are that caffeine is very addictive. In terms of addiction it isn't very different from many illegal drugs. It just happens to be socially acceptable. Our society even lets children consume this drug!&lt;/p&gt;

&lt;p&gt;The author, Stephen Cherninske, is a biochemist and he goes into detail for how ccientifically caffiene doesn't actually give you energy or help you focus. &lt;/p&gt;

&lt;p&gt;Instead, caffeine takes advantage of the fight or flight response and forces the adrenal glands to pump out stress hormones, which makes us feel like we have energy and focus, but in reality this just taxes our adrenal glands which we need for other important physiological purposes. &lt;/p&gt;

&lt;p&gt;Another reason to quit caffeine that he mentions is that coffee is acidic and also full of pesticides. It uses more pesticides than any other crop. While you might think that tea is safer, tea also uses a ton of pesticides and it really is not much safer. It's best to just drink water (or some other alternatives he mentions in the book). &lt;/p&gt;

&lt;p&gt;On a more personal level, while drinking coffee I was having trouble falling and staying asleep at night. I also had trouble focusing in the afternoon if I was not actively sipping some coffee. I also lost my father to esophageal cancer and want to be more careful about what acidic things I let slide down my gullet.&lt;/p&gt;

&lt;p&gt;Ultimately, I didn't like the feeling of being dependent on a drink to get my work done. I didn't like taxing my adrenal glands all day, or filling my body with acid and pesticides. &lt;/p&gt;

&lt;h2&gt;
  
  
  How I Quit Caffeine
&lt;/h2&gt;

&lt;p&gt;I was addicted to coffee and quitting any addiction is no joke. Withdrawls from coffee can be very serious. In the past I had tried cold turkey and it was miserable. It is best to ween yourself off of slowly. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://amzn.to/3rRKhpz"&gt;Caffeine Blues&lt;/a&gt; has a method to quit coffee, but I did not use this method. Instead, I drank a smaller amount each day for about 2 weeks. On the last day, I had basically a sip and that was it. &lt;/p&gt;

&lt;p&gt;By doing this, I felt no withdrawl affects. I did not have the common headaches that can be absolutely brutal for some people and had destroyed my attempts to quit caffeine in the past. &lt;/p&gt;

&lt;p&gt;One of the hardest parts of quitting an addiction, beside the physical aspect of the addiction, is the actual mental habit. &lt;/p&gt;

&lt;p&gt;For a while I was drinking &lt;a href="https://amzn.to/3o04pot"&gt;rooibos&lt;/a&gt; or &lt;a href="https://amzn.to/3rTgzR6"&gt;ginseng&lt;/a&gt; teas instead of coffee. Neither of these contain caffeine and they have some great health benefits.&lt;/p&gt;

&lt;p&gt;These are both great teas and they were recommend in  &lt;a href="https://amzn.to/3rRKhpz"&gt;Caffeine Blues&lt;/a&gt;, but they didn't provide the same deep nutty robust flavor that coffee had. Eventually, I bought some &lt;a href="https://amzn.to/3rT9T5F"&gt;chickory root granules&lt;/a&gt; for this reason. They have a ton of health benefits as well, no caffeine, and a similar taste and feel to coffee. Each morning, I began drinking chickory root instead of coffee. &lt;/p&gt;

&lt;p&gt;I also made sure to get plenty of exercise. I run most mornings, lift weights 3 days a week, and walk or hike with my dogs every day. It's important to exercise and eat well to keep your energy and focus. &lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;So what are the results? Is it worth it to quit coffee as a software engineer, entrepreneur or other creative? &lt;/p&gt;

&lt;p&gt;If coffee provides you with the energy and focus you need to get through the day and you feel like you can't get your tasks completed without coffee, then you are probably the exact person who should consider quitting coffee. &lt;/p&gt;

&lt;p&gt;I am going to talk about my results now, and then you can decide for yourself. &lt;/p&gt;

&lt;p&gt;I track my sleep using the app &lt;a href="https://www.sleepcycle.com/"&gt;Sleep Cycle&lt;/a&gt;. I was often getting scores of about 70/100, not very good. I noticed that I felt more energize when I woke up after quitting coffee and I have more energy naturally thoughout the day. My sleep cycle scores are usually in the high 80s or low 90s. I have even had a few 100/100 sleep nights! I consistenly experience more deep sleep than during my caffeine consuming days. &lt;/p&gt;

&lt;p&gt;I also feel much more focused at work. There are days where I might be tired, and I may drink a ginseng tea to help keep me focused, but for the most part I am more focused on my work and I feel more productive after quitting coffee. If nothing else, I'm not constantly leaving my computer to pour more coffee or to piss it out. &lt;/p&gt;

&lt;p&gt;Very importantly, I still drink coffee once or twice a week. I try not to have more than a small mug during each time. &lt;/p&gt;

&lt;p&gt;This is a nice treat for me, since I love the smell and taste of coffee, and this method allows me not to become addicted. &lt;/p&gt;

&lt;p&gt;I do want to warn you though. The first time I drank coffee after quitting, I had quit for about 3 months with absolutly no coffee. I drank a mug and a few minutes later I was shaking, sweaty, and very nervous. I felt like I was having a psychadelic experience. This type of account is also experienced by Michael Pollan and he writes about it in his book &lt;a href="https://amzn.to/3IDlcp8"&gt;This is Your Mind on Plants&lt;/a&gt;, which is another fascinating read if you want to learn more about caffeine (and other plants).&lt;/p&gt;

&lt;p&gt;This trip-like experience was eye-opening for me because so many people get so used to caffeine and don't understand how powerful it truly is and it's affects on their bodies and minds. &lt;/p&gt;

&lt;p&gt;In conclusion, I am glad that I "quit" coffee (other than the once or twice per week). I recommend it and would love to hear your thoughts and experiences. &lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>discuss</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Supabase Vs Firebase Pricing and When To Use Which</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Sat, 22 Jan 2022 23:59:30 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/supabase-vs-firebase-pricing-and-when-to-use-which-5hhp</link>
      <guid>https://dev.to/mwolfhoffman/supabase-vs-firebase-pricing-and-when-to-use-which-5hhp</guid>
      <description>&lt;h1&gt;
  
  
  Supabase Vs Firebase Pricing and When To Use Which
&lt;/h1&gt;

&lt;p&gt;Supabase recently appeared on the scene as an attempt to be an open source alternative to Firebase. It's a great product and I've used it in many projects already. I've written about it &lt;a href="https://codewithwolf.com/how-to-use-react-with-supabase-pt-1"&gt;here&lt;/a&gt; and &lt;a href="https://codewithwolf.com/how-to-use-react-with-supabase-pt-2"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The main difference between Supabase vs Firebase is that Supabase is a SQL database that utilized postgres and Firebase uses a NoSQL document data store. &lt;/p&gt;

&lt;p&gt;On my current side project I recently replaced Supabase for Firebase. I'll get into why and some of the pricing differences to consider.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Consideration for Supabase vs Firebase
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Firebase has more features, for now
&lt;/h3&gt;

&lt;p&gt;For one, Firebase has been around much longer than Supabase and thus has more features. You can host your app on Firebase, you can also write cloud functions. (Currently I believe Supabase has cloud functions in beta).&lt;/p&gt;

&lt;p&gt;Both have great options for objects storage, authentication, and most things you will need as a backend as a service product. &lt;/p&gt;

&lt;p&gt;Also, while Supabase is not yet a perfect 1:1 mapping of Firebase, they do seem to be very quickly puting out new features to more closely match Firebase's offerings. &lt;/p&gt;

&lt;h3&gt;
  
  
  SQL vs NoSQL
&lt;/h3&gt;

&lt;p&gt;This is a big one that I've been considering more. I enjoy relational data and my brain allows me to think about the relationships that SQL allows better than NoSQL document or key/value stores. &lt;/p&gt;

&lt;p&gt;I've been doing more of a deep dive into NoSQL and learning about how to structure data with it lately. &lt;/p&gt;

&lt;p&gt;With my research, I have decided that for small side projects and MVPs, I will be going with Firebase over Supabase if I truly don't need my data to be relational. &lt;/p&gt;

&lt;p&gt;NoSQL (firebase) can &lt;em&gt;often&lt;/em&gt; be structured in a way that is more efficient than SQL. &lt;/p&gt;

&lt;p&gt;There are drawbacks however. Because you can't write complex queries and joins, you do have to consider how you might want to query your data in the future. &lt;/p&gt;

&lt;p&gt;This can be a difficult task. Once you have correctly anticipated the queries your application will need in the future, you actually duplicate that data into another document or collection in the NoSQL data store. &lt;/p&gt;

&lt;p&gt;Of course, now you have multiple places to update data too! This sounds like a headache, but with some practice it's actually pretty easy to catch on fast. &lt;/p&gt;

&lt;p&gt;After learning some more about how to structure documents in a NoSQL datastore, this performance and scalability is why I have decided that I will typically use Firebase over Supabase. &lt;/p&gt;

&lt;p&gt;The other reason is price. &lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing
&lt;/h3&gt;

&lt;p&gt;Another consideration for the Supabase vs Firebase debate is pricing. Both services offer a generous free tier. But what makes pricing considerations difficult is that scalability always has to be kept in mind. &lt;/p&gt;

&lt;p&gt;First, let's go over what each service offers for free in terms of a database and authentication (the two most used services by each) per month.&lt;/p&gt;

&lt;h4&gt;
  
  
  Supabase:
&lt;/h4&gt;

&lt;p&gt;You get 3 free projects. You get 500 MB of storage. You get 10,000 users through their authentication service. &lt;/p&gt;

&lt;h3&gt;
  
  
  Firebase:
&lt;/h3&gt;

&lt;p&gt;You get unlimited free projects. You get 1 GB of storage. You get 10,000 users through their authentication service. &lt;/p&gt;

&lt;p&gt;Firebase does charge for ingress and egress too. So you get 20,000 free writes per day and 50,000 free reads per day. &lt;/p&gt;

&lt;h3&gt;
  
  
  Which to choose
&lt;/h3&gt;

&lt;p&gt;Ultimately, when I think about how my projects are going to scale (if they ever needed to) and what I am going to use them for, often NoSQL is just fine for my use cases and I get a better deal with Firebase. &lt;/p&gt;

&lt;p&gt;This is because my projects don't often scale to over 20,000 writes per day or 50,000 reads per day. And even if they do, the price is comparable with Supabase's next tier.&lt;/p&gt;

&lt;p&gt;This decision allows me to save my limited supabase free projects for when I really need a relational database. &lt;/p&gt;

</description>
      <category>sql</category>
      <category>firebase</category>
      <category>database</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Where to Publish Plugins, Add-ons, and Extensions for Software Engineers and Entrepreneurs</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Fri, 21 Jan 2022 02:38:31 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/where-to-publish-plugins-add-ons-and-extensions-for-software-engineers-and-entrepreneurs-2m6g</link>
      <guid>https://dev.to/mwolfhoffman/where-to-publish-plugins-add-ons-and-extensions-for-software-engineers-and-entrepreneurs-2m6g</guid>
      <description>&lt;h1&gt;
  
  
  Where to Publish Plugins, Add-ons, and Extensions for Software Engineers and Entrepreneurs
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Which Platforms Can a Software Engineer Or Entrepreneur Publish a Plugin, Add-on, or Extension?
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Why Publish a Plugin?
&lt;/h2&gt;

&lt;p&gt;One of the reasons that I originally was interested in becoming a software engineer was to try my hand at becoming an entrepreneur. &lt;/p&gt;

&lt;p&gt;I had hopes of starting with a day-job and spending my evenings and weekends creating a software product or service that would yield me passive income and buy me my own freedom from the 9-5 grind. It's not that I don't want to work. I actually love working and really enjoy my job. Even with millions in the bank I would keep working as a software engineer. &lt;/p&gt;

&lt;p&gt;I just wanted to have that freedom if I ever didn't want to work and the security if I ever lost my job or ability to work.&lt;/p&gt;

&lt;p&gt;If that sounds like you, keep reading. &lt;/p&gt;

&lt;h2&gt;
  
  
  Failure Disclaimer
&lt;/h2&gt;

&lt;p&gt;Given that &lt;a href="https://www.entrepreneur.com/article/361350"&gt; 20% of small businesses fail in their first year&lt;/a&gt;, and 70% fail in the first decade, I am right on schedule. I honestly still don't have a thriving profitable small business. &lt;/p&gt;

&lt;p&gt;Failing has been an incredible journey and I encourage everyone to try it. I have learned a ton about software engineering, various languages, frameworks,  tools, DevOps, product design, and more. While I haven't turned a profit with any of my projects yet, it's hard to really say I have failed after gaining so much experience.&lt;/p&gt;

&lt;p&gt;So while I am admitting to not be a successful business person yet, I still think it's worth taking the advice I have in this article. Mostly because the advice comes from some great entrepreneurs that I admire. &lt;/p&gt;

&lt;h2&gt;
  
  
  What Business To Start
&lt;/h2&gt;

&lt;p&gt;I recently listened to an episode of &lt;a href="https://www.mfmpod.com/saas-companies-that-anyone-can-start-with-rob-walling/"&gt;My First Million&lt;/a&gt; where Sam Parr talks with Rob Walling.&lt;/p&gt;

&lt;p&gt;Rob Walling is an entrepreneur mostly known for &lt;a href="https://drip.com"&gt;Drip&lt;/a&gt; and &lt;a href="https://microconf.com/"&gt;Microconf &lt;/a&gt;. He was chatting with Sam about businesses that anyone can start. &lt;/p&gt;

&lt;p&gt;He mentioned his &lt;a href="https://robwalling.com/2015/03/26/the-stairstep-approach-to-bootstrapping/"&gt;Stair Step Approach&lt;/a&gt; to starting a business. This changed how I think about new side projects and possible businesses that I try starting. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why Publish A Plugin?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Smaller Initial Investment
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;tldr;&lt;/code&gt; of &lt;a href="https://robwalling.com/2015/03/26/the-stairstep-approach-to-bootstrapping/"&gt; Rob's Stair Step Approach article &lt;/a&gt;  is that you should start small. It's best to start with something like a video course, e-book, or just publishing a plugin onto another platform.&lt;/p&gt;

&lt;p&gt;Starting small in this manner has no or little monetary investment upfront. These projects can be small and might not be lucrative at first, but they tend to be easier to build, faster to start, and thus the lower overhead will allow you to create more of these products/services. Overtime these can add up and eventually buy you back your time. &lt;/p&gt;

&lt;p&gt;I think this is a compelling approach because the opposite would be to try to start a large full-blown SaaS product from scratch... which can be very expensive and time-consuming to ever get to the point where the market can even validate it. When it does come time for validation, it's possible the market won't like it after all that hard work, time and money invested!&lt;/p&gt;

&lt;h3&gt;
  
  
  Marketing Is Done For You
&lt;/h3&gt;

&lt;p&gt;As a software engineer, marketing is terrifying to me. For other engineers, solo-founders, and technical entrepreneurs without a marketing background, publishing a plugin is a great business because the marketing is already done for you. Users are already using the platform (Chrome, Wordpress, Shopify, etc.) and when they search the platform's marketplace your product will be in the search results. There is no need to go out to do paid advertising or what ever else marketers do. (I have no idea). &lt;/p&gt;

&lt;p&gt;&lt;b&gt;Therefore, publishing plugins onto an existing platform is a great option for starting your first online business&lt;/b&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where To Publish Plugins/Add-ons/Extensions
&lt;/h2&gt;

&lt;p&gt;I had trouble finding a good list of where a software engineer, solo-founder, or entrepreneur can publish these plugins. &lt;/p&gt;

&lt;p&gt;Here are some platforms to give you an idea of where you can publish a plugin, add-on, or extension and start your first business. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Chrome (or other browsers that have extensions)&lt;/li&gt;
&lt;li&gt;Wordpress (A huge majority of the web uses Wordpress)&lt;/li&gt;
&lt;li&gt;Shopify&lt;/li&gt;
&lt;li&gt;Heroku&lt;/li&gt;
&lt;li&gt;Jira&lt;/li&gt;
&lt;li&gt;Slack&lt;/li&gt;
&lt;li&gt;Figma&lt;/li&gt;
&lt;li&gt;Jenkins&lt;/li&gt;
&lt;li&gt;Amazon&lt;/li&gt;
&lt;li&gt;Amazon Web Services&lt;/li&gt;
&lt;li&gt;Netlify&lt;/li&gt;
&lt;li&gt;Grafana&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is by no means an exhaustive list. There are tons of others. I put the first few that I like at the top and will add more later. Contact me if you have a few that you want to add to this list too. I would be glad to add them. &lt;/p&gt;

&lt;p&gt;Go build and publish those plugins and start your business! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>startup</category>
      <category>saas</category>
      <category>career</category>
    </item>
    <item>
      <title>How to Use React + Supabase Pt 2: Working with the Database
</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Tue, 30 Nov 2021 01:39:14 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/how-to-use-react-supabase-pt-2-working-with-the-database-1mgc</link>
      <guid>https://dev.to/mwolfhoffman/how-to-use-react-supabase-pt-2-working-with-the-database-1mgc</guid>
      <description>&lt;p&gt;This demo will teach you how to connect a React application with Supabase. &lt;/p&gt;

&lt;p&gt;If you want to learn more about Supabase in general or how to set up authentication easily using supabase in a react application, read &lt;a href="https://codewithwolf.com/how-to-use-react-with-supabase-pt-1"&gt; this post&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install an ORM
&lt;/h2&gt;

&lt;p&gt;We will use an Object Relational Mapper (ORM) to interact with our database. We will go with Prisma for this demo since it's highly popular, well maintained, and easy to set up. If you want you can use another ORM since Knex, TypeORM, Sequelize, and others are great too so feel free to follow along with those if you are more familiar with them. &lt;/p&gt;

&lt;p&gt;If you are familiar with graphql you will find Prisma a breeze to pick up. &lt;/p&gt;

&lt;p&gt;Install Prisma&lt;br&gt;
&lt;code&gt;yarn add prisma&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Are We Using an ORM?
&lt;/h2&gt;

&lt;p&gt;It's possible to do everything we are going to with an ORM also without one. You can write raw SQL scripts or use the Supabase UI to do all of these tasks. &lt;/p&gt;

&lt;p&gt;The reason that I am using an ORM for this is so that we can have our SQL interactions coded and saved in source control to make it easier to troubleshoot, scale, and collaborate. &lt;/p&gt;

&lt;p&gt;Feel free to write raw SQL, use the SupabaseUI, or a different ORM if you would like, but an ORM makes this much easier. &lt;/p&gt;
&lt;h2&gt;
  
  
  Connect Prisma to our Supabase DB
&lt;/h2&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;code&gt;npx prisma init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will create a new file called &lt;code&gt;schema.prisma&lt;/code&gt; in a new &lt;code&gt;prisma&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = "&amp;lt;YOUR_DB_CONNECTION_STRING&amp;gt;"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace this with your connection string for the supabase DB you created in the &lt;a href="https://codewithwolf.com/how-to-use-react-with-supabase-pt-1"&gt; previous post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Be careful with these sensitive values. You will want to make sure that they remain secrets, so don't push these to github in a public repo. For this demo we will be hard coding them to just keep things simple. &lt;/p&gt;

&lt;p&gt;Your connection string should look like this: &lt;code&gt;postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Models
&lt;/h2&gt;

&lt;p&gt;Creating models with Prisma has a bit of a learning curve. Check out &lt;a href="https://www.prisma.io/"&gt;the docs&lt;/a&gt; as you build out these models. &lt;/p&gt;

&lt;p&gt;For now, copy and paste this into the &lt;code&gt;prisma/schema.prisma&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

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

model User {
 id Int @id @default(autoincrement())
 firstName String 
 lastName String
 email String
}

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

&lt;/div&gt;



&lt;p&gt;We will create a small Customer Relationship Manager. Here we just have a simple &lt;code&gt;User&lt;/code&gt; model to get us started. &lt;/p&gt;

&lt;h2&gt;
  
  
  Create Migrations
&lt;/h2&gt;

&lt;p&gt;Next we need to create our migrations. This is extremly simple and can be done automatically with Prisma. &lt;/p&gt;

&lt;p&gt;Run the command: &lt;br&gt;
&lt;code&gt;npx prisma migrate dev --name init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You will see a &lt;code&gt;migrations&lt;/code&gt; folder created in the &lt;code&gt;prisma&lt;/code&gt; directory. If you navigate to your project in the Supabase UI, you will see the are now tables created! One is named &lt;code&gt;User&lt;/code&gt; and was created from our migration. (Another table is &lt;code&gt;_prisma_migrations&lt;/code&gt; and is used by Prisma to internally keep track of which migrations have been created or rolledback). &lt;/p&gt;
&lt;h2&gt;
  
  
  Install Prisma Client
&lt;/h2&gt;

&lt;p&gt;Because we are using Prisma, the next step before we can seed and query our DB is to install the Prisma client. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add @prisma/client&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we will create a new file in the &lt;code&gt;prisma&lt;/code&gt; directory called &lt;code&gt;prismaClient.js&lt;/code&gt; with the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { PrismaClient } = require('@prisma/client')

const prisma = new PrismaClient()

module.exports =  prisma


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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Seed DB
&lt;/h2&gt;

&lt;p&gt;Now it's time to seed the database. Let's create a file called &lt;code&gt;seedDb.js&lt;/code&gt; in the &lt;code&gt;prisma&lt;/code&gt; directory that imports the &lt;code&gt;prismaClient&lt;/code&gt; we just created and seeds the DB with some dummy data. &lt;/p&gt;

&lt;p&gt;We will use &lt;code&gt;faker&lt;/code&gt; to create some fake names for the dummy data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const prisma = require('./prismaClient.js')
const faker = require('faker')


const users = []

function createUsers(){
    const num = 100;
    let x = 0;

    while(x &amp;lt; 100){
        const user = {
            firstName: faker.name.firstName(),
            lastName: faker.name.lastName(),
            email: faker.internet.email(),
            }
    users.push(user)
    x++
    }
}


async function seedDb(){
 await prisma.user.createMany({data: users})
} 


async function main() {
    createUsers()
    await seedDb()
}


main().catch((e) =&amp;gt; {
    throw e
  }).finally(async () =&amp;gt; {
    await prisma.$disconnect()
  })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Read From DB with the Supabase JS Client
&lt;/h2&gt;

&lt;p&gt;Now that we can create tables with migrations and write to tables using our ORM, we are ready to get back into our React app and perform CRUD applications on this data. &lt;/p&gt;

&lt;p&gt;The migrations and seeding in the previous step give us some data tables and mock data to work with here. &lt;/p&gt;

&lt;p&gt;From now on, in our react app, we will be using the supabase client to interact with our database. &lt;/p&gt;

&lt;p&gt;First let's create a new folder called &lt;code&gt;components&lt;/code&gt; in the &lt;code&gt;src&lt;/code&gt; directory. &lt;/p&gt;

&lt;p&gt;Then in the &lt;code&gt;src/components&lt;/code&gt; directory, we will create a new component called  &lt;code&gt;Users.jsx&lt;/code&gt;, which will looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useState } from "react";
import supabase from "../supabase";

export default function () {
  const [loading, setLoading] = useState(true);
  const [users, setUsers] = useState([]);

  async function getUsers() {
    const { data, error } = await supabase.from("User").select();
    setUsers(u =&amp;gt; u= data);
  }

  useEffect(() =&amp;gt; {
    setLoading(true);
    getUsers();
    setLoading(false);
  }, []);

  return (
    &amp;lt;&amp;gt;
      &amp;lt;h2&amp;gt;Users&amp;lt;/h2&amp;gt;
      {loading ? (
        &amp;lt;p&amp;gt;loading...&amp;lt;/p&amp;gt;
      ) : (
        &amp;lt;&amp;gt;
          {users?.length ? (
            &amp;lt;ul&amp;gt;
              {users.map((user) =&amp;gt; (
                &amp;lt;li&amp;gt;
                  {user.email} : {user.firstName} {user.lastName}
                &amp;lt;/li&amp;gt;
              ))}
            &amp;lt;/ul&amp;gt;
          ) : (
            &amp;lt;p&amp;gt;No users currently&amp;lt;/p&amp;gt;
          )}
        &amp;lt;/&amp;gt;
      )}
    &amp;lt;/&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;In theory, this will print every user's email and name. &lt;/p&gt;

&lt;p&gt;We don't want to do that unless the user is logged in, so let's update our &lt;code&gt;App.js&lt;/code&gt; file to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "./App.css";
import supabase from "./supabase";
import { useState, useEffect } from "react";
import Users from "./components/Users";

function App() {
  const [user, setUser] = useState(null);

  supabase.auth.onAuthStateChange((event, session) =&amp;gt; {
    if (session?.user) {
      setUser((u) =&amp;gt; (u = session.user));
    }
  });

  async function signInWithGithub() {
    const { user, session, error } = await supabase.auth.signIn({
      provider: "github",
    });
  }

  async function signOut() {
    const { error } = await supabase.auth.signOut();
    setUser((u) =&amp;gt; (u = null));
  }

  return (
    &amp;lt;div className="App"&amp;gt;
      {!user ? (
        &amp;lt;button onClick={signInWithGithub}&amp;gt;Sign In With Github&amp;lt;/button&amp;gt;
      ) : (
        &amp;lt;&amp;gt;
          &amp;lt;button onClick={signOut}&amp;gt;Log Out, {user?.email}&amp;lt;/button&amp;gt;
          &amp;lt;Users /&amp;gt;
        &amp;lt;/&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the user will be presented with a Log In button if not authenticated, and if they are authenticated we should see a list of all of our user's email and names. &lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;To write, update, get real-time updates, create stored-procedures, use storage and the many more features of Supabase, check out the Supabase JS client &lt;a href="https://supabase.com/docs/reference/javascript/select"&gt;docs&lt;/a&gt;. They are easy to follow and very helpful. &lt;/p&gt;

&lt;p&gt;Hopefully this got you started with Supabase and you can be well on your way to building real-time authenticated web apps quickly without the overhead of managing a DB and API.&lt;/p&gt;

&lt;p&gt;If you like this post and it helped you, share it with friends. &lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Show Your Work: A Software Engineering Book Review</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Tue, 30 Nov 2021 01:36:22 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/show-your-work-a-software-engineering-book-review-56f4</link>
      <guid>https://dev.to/mwolfhoffman/show-your-work-a-software-engineering-book-review-56f4</guid>
      <description>&lt;h2&gt;
  
  
  Show Your Work Summary
&lt;/h2&gt;

&lt;p&gt;This weekend I read a short book that is well worth the time. It’s Austin Kleon’s &lt;a href="https://amzn.to/32zgQ2C"&gt;Show Your Work&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;What I love about this book is that it backs up a theory that I have long held to be true and I attempt to practice as often as possible. I don’t think that is my own confirmation bias this time, I think the ideas in this book truly are important. &lt;/p&gt;

&lt;p&gt;Show Your Work talks about a lot of things, but one of them is that you should teach to learn. &lt;/p&gt;

&lt;p&gt;I will go over some of the key concepts of this book in a moment, but the main idea is that you have something to teach anyone. You don’t have to be an expert to put your work onto the internet for others to find and gain help from. As you learn new skills, you can show what and how you are learning. You can teach to learn, and you can do it by showing your work. &lt;/p&gt;

&lt;h1&gt;
  
  
  Key Ideas:
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Lone Wolf Myth
&lt;/h2&gt;

&lt;p&gt;Artists, engineers, and other creatives don’t typical work solo. They work in groups and communicate with others to come up with ideas. They also follow others’ works and gain inspiration from them. Don’t just work alone and keep your work to yourself. People will find your work and have plenty to learn from you. &lt;/p&gt;

&lt;h2&gt;
  
  
  Teach Others, Show Them What You Know
&lt;/h2&gt;

&lt;p&gt;Instead of only consuming media, produce something as well. Often times we consume more than we even realize without ever being contributors. If you are learning something new, post about it and someone will find it useful. Instead of being a taker, become a giver. &lt;/p&gt;

&lt;h1&gt;
  
  
  Be an Amateur
&lt;/h1&gt;

&lt;p&gt;It is very rare for a talented person to be naturally gifted. Athletes, artists, and everyone works incredibly hard for their achievements that impress us. Embrace being an amature. Become a lifelong learner. If you are a lifelong learner, you will have to be an amatuer at many times as your life progresses. This is a good quality, not a hindrance. &lt;br&gt;
Always be learning, always be an amatuer in regard to something. As Kleon clearly writes, “overnight success is a myth”.&lt;/p&gt;

&lt;h1&gt;
  
  
  How To Start Showing Your Work
&lt;/h1&gt;

&lt;p&gt;Find what you want to learn, commit to learning it, and then learn it in front of others. Create a blog or youtube video, write an ebook, etc. &lt;/p&gt;

&lt;h1&gt;
  
  
  Read the Obituaries Every Morning
&lt;/h1&gt;

&lt;p&gt;Here is a chapter I wasn’t expecting. Every morning, the author reads the obituaries. He says that instead of reading and thinking about death, obituaries are really about life. They are lists of achievements a person has accomplished in their life. All of these people started out as amateurs and had plenty to learn. This inspires the reader to learn more and share his learnings. &lt;/p&gt;

&lt;h1&gt;
  
  
  Read A Lot
&lt;/h1&gt;

&lt;p&gt;If you are a lifelong learner and a passionate amateur, it’s likely you already like to read. If you are going to be writing, you should also be reading. If you are going to be speaking, you should be listening. Consume the media that you produce. Kleon talks about “human spam” and uses that term for the type of people who write but never read. &lt;/p&gt;

&lt;h1&gt;
  
  
  Vampire Test
&lt;/h1&gt;

&lt;p&gt;Austin Kleon shares a rumor that Pablo Picasso would spend time with people and suck the energy out of them. When he was done hanging out, he would go home and use that energy to paint. Do you have people that when you spend time with them they exhaust you instead of energize you? Stop spending time with them. &lt;/p&gt;

&lt;h1&gt;
  
  
  Trolls
&lt;/h1&gt;

&lt;p&gt;If you are putting your learnings on the internet and showing your work, it’s likely that people will find you. If they do, it’s likely you will encounter trolls. Even my own coding blog has gotten trolls. There just isn’t a way around it. Don’t let them get to you, and keep learning and sharing. Consider turning off comments or just not responding to the trolls. &lt;/p&gt;

&lt;h1&gt;
  
  
  Monetize, eventually
&lt;/h1&gt;

&lt;p&gt;People will want to read and hear what you are saying as you are learning the same things that they are learning. However, amateurs don’t typically want to pay amateurs. It’s usually the experts that get the money. College students wouldn’t be paying the exorbitant amount it costs to attend college if they were learning from other students instead of professors with PhDs. &lt;/p&gt;

&lt;p&gt;Eventually, you might be able to monetize your learnings. Maybe you can get good and write an ebook, or your youtube channel will get enough views to make money off of ads. At the very least, the author tells you to collect email addresses in case you have products to sell later, to promote new material, etc. &lt;/p&gt;

&lt;h1&gt;
  
  
  Support Others
&lt;/h1&gt;

&lt;p&gt;Here is an important point from the book not to overlook, support others. Credit other people’s ideas, promote other peoples’ learnings that they are sharing, and support those in your community. Learning to code and improving? Try attending a local meetup and help others learning to code. Be helpful. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>How To Use React + Supabase Pt 1: Setting Up a Project and Supabase Authentication</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Tue, 23 Nov 2021 16:52:46 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/how-to-use-react-supabase-pt-1-setting-up-a-project-and-supabase-authentication-44kk</link>
      <guid>https://dev.to/mwolfhoffman/how-to-use-react-supabase-pt-1-setting-up-a-project-and-supabase-authentication-44kk</guid>
      <description>&lt;h1&gt;
  
  
  How To Use React + Supabase Pt 1: Setting Up a Project and Supabase Authentication
&lt;/h1&gt;

&lt;p&gt;Stay tune for more posts in this series to learn how to build apps quickly with React and Supabase at &lt;a&gt;&lt;/a&gt;&lt;a href="http://www.codewithwolf.com"&gt;www.codewithwolf.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Supabase and Why Use it?
&lt;/h2&gt;

&lt;p&gt;Have you ever wanted to build an application very quickly? Maybe it's for a client or maybe it's to get it in front of potential customers or investors. &lt;/p&gt;

&lt;p&gt;The issue is that building applications quickly, (or rapid protoyping) can be incredibly difficult because of the amount of architecture usually needed. You need a UI, DB, API, and maybe more components. &lt;/p&gt;

&lt;p&gt;Supabase is a backend as a service (BaaS), but has a generous free tier and predictable pricing. (Areas where competitors like Firebase or Back4App fall short).&lt;/p&gt;

&lt;p&gt;If you want to rapid prototype an minimum viable product (MVP) to get in front of potential consumers or investors, I have found no better tool than using the UI framework of your choice(React, Angular, Vue, etc) and Firebase. (Click  &lt;a href="https://codewithwolf.com/best-js-framework"&gt;here&lt;/a&gt; for an overview of how to choose a front end framework) and &lt;a href="https://supabase.io/"&gt;Supabase&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Supabase is built on PostgreSQL and essentially acts as your SQL DB and real-time API. Real-time features like chat apps are a breeze with Supabase. &lt;/p&gt;

&lt;p&gt;For this demo, we will create a react project that uses Supabase. This will be the first part of a series that goes through some of Supabase's most important features. &lt;/p&gt;

&lt;p&gt;The next part of the series is &lt;a href="https://codewithwolf.com/how-to-use-react-with-supabase-pt-2"&gt;here&lt;/a&gt;.&lt;/p&gt;



&lt;h2&gt;
  
  
  Create The React Project
&lt;/h2&gt;



&lt;p&gt;This tutorial assumes you have an understanding of JavaScript and at least a minimal understanding of react. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd&lt;/code&gt; into a directory of your choice and run: &lt;br&gt;
&lt;code&gt;npx create-react-app supabase-react&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;(&lt;code&gt;supabase-react&lt;/code&gt; is the name of the project. You can name your project anything you want).&lt;/p&gt;

&lt;p&gt;Once the project is created you will see the typical default files for an app created with &lt;code&gt;create-react-app&lt;/code&gt;. You can start the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd supabase-react
yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should open a browser tab at &lt;code&gt;localhost:3000&lt;/code&gt; with a default react app running.&lt;/p&gt;



&lt;h2&gt;
  
  
  Install Supabase
&lt;/h2&gt;



&lt;p&gt;Next, we will install the supabase js client. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add @supabase/supabase-js&lt;/code&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Create a Supabase Project
&lt;/h2&gt;



&lt;p&gt;Next we need to create a Supabase project. &lt;/p&gt;

&lt;p&gt;If you don't have an account, you can sign up for free &lt;a href="https://supabase.io/"&gt;here&lt;/a&gt;. Everything we do in this demo (at the time of publishing this post) will be within the confines of the free tier. &lt;/p&gt;

&lt;p&gt;Once you have an account created, log in and create a Supabase project. You will need to give it a name (I called mine &lt;code&gt;supabase-poc&lt;/code&gt;) and make sure to give it a strong password. I use &lt;a href="lastpass.com"&gt;LastPass&lt;/a&gt; to create strong passwords. &lt;/p&gt;

&lt;p&gt;Now, when you select your Supabase project you will have access to an &lt;code&gt;annon public key&lt;/code&gt;. &lt;/p&gt;



&lt;h2&gt;
  
  
  Connecting React With Supabase
&lt;/h2&gt;



&lt;p&gt;Create a new directory in the &lt;code&gt;src&lt;/code&gt; directory of the react project and name it &lt;code&gt;supabase&lt;/code&gt;. In that directory, create a file &lt;code&gt;index.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;src/supabase/index.js&lt;/code&gt;, you will need to create the supabase client. &lt;/p&gt;

&lt;p&gt;Use the below code, except replace the first parameter with the URL in your supabase project's settings. And the second parameter should be the project's public annon key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createClient } from '@supabase/supabase-js'

export default createClient('https://project.supabase.co', 
'&amp;lt;YOUR PUBLIC ANNON KEY&amp;gt;')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h1&gt;
  
  
  Setup Supabase Authentication with GitHub
&lt;/h1&gt;

&lt;p&gt;One of my favorite features of Supabase is how simple it is to set up authentication. &lt;/p&gt;

&lt;p&gt;Head over to your supabase project and navigate to the Auth page. &lt;/p&gt;

&lt;p&gt;So far, there are no auth providers set up. On the left side nav bar, select Settings. &lt;/p&gt;

&lt;p&gt;When you scroll down to the External Auth Providers section, you will see a long list of 3rd party auth providers you may use. &lt;/p&gt;

&lt;p&gt;For this demo, we will only use Github. (Although each provider will be very similar to set up). &lt;/p&gt;

&lt;p&gt;Toggle on Github. &lt;/p&gt;

&lt;h2&gt;
  
  
  Create An OAuth App In Github
&lt;/h2&gt;

&lt;p&gt;The next step is to create an OAuth app in github. To do this, navigate to &lt;a href="https://github.com"&gt;GitHub&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Go to your settings and select Developer Settings, and then OAuth Apps. &lt;/p&gt;

&lt;p&gt;Next, click the button to add a new OAuth app. &lt;/p&gt;

&lt;p&gt;Fill out the form. You'll need a homepage URL. I used &lt;code&gt;http://localhost:3000&lt;/code&gt; for now. And for your Auth Callback add &lt;code&gt;https://&amp;lt;YOUR_PROJECT_REFERENCE&amp;gt;.supabase.co/auth/v1/callback&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After that, a Client ID and Client Secret are created for you in Github. Copy and paste them into the Supabase Authentication Console where you previously enabled Github auth. (They recently started adding default values in there so just replace those with the values generated in Github).&lt;/p&gt;

&lt;p&gt;Click the 'Save' button in the auth settings. &lt;/p&gt;

&lt;h2&gt;
  
  
  Sign In User Interface
&lt;/h2&gt;

&lt;p&gt;Now we are ready for a UI to log in with Github. &lt;/p&gt;

&lt;p&gt;In &lt;code&gt;/src/App.js&lt;/code&gt;, replace the current code with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; user, session, error } = await supabase.auth.signIn({
      provider: 'github'
    });
  }

  async function signout() {
    const { error } = await supabase.auth.signOut();
  }

  return (
    &amp;lt;div className="App"&amp;gt;
    &amp;lt;button onClick={signInWithGithub} &amp;gt;Sign In With Github&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll now see a button and if you click on it, it will allow you to login with Github and then redirect you back to localhost. &lt;/p&gt;

&lt;p&gt;Next, we will complete the login process. &lt;/p&gt;

&lt;h1&gt;
  
  
  How to Use Supabase Authentication with React
&lt;/h1&gt;

&lt;p&gt;One of the more confusing parts about using OAuth with Supabase and React is what to do after you are redirected back to localhost. &lt;/p&gt;

&lt;p&gt;That is what this blog post is about, and where other posts and the Supabase docs seem to fall short. &lt;/p&gt;

&lt;p&gt;Currently,  our &lt;code&gt;App.js&lt;/code&gt; is just a button that does part of the login work for us. Now, we will make a few simple change to complete the entire login process.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;src/App.js&lt;/code&gt; now should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "./App.css";
import supabase from "./supabase";
import { useState } from "react";

function App() {
  const [user, setUser] = useState(null);

  supabase.auth.onAuthStateChange((event, session) =&amp;gt; {
    if (session?.user) {
      setUser((u) =&amp;gt; (u = session.user));
    }
  });

  async function signInWithGithub() {
    const {
      user,
      session,
      error,
    } = await supabase.auth.signIn({
      provider: "github",
    });
  }

  async function signOut() {
    const { error } = await supabase.auth.signOut();
    setUser((u) =&amp;gt; (u = null));
  }

  return (
    &amp;lt;div className="App"&amp;gt;
      {!user ? (
        &amp;lt;button onClick={signInWithGithub}&amp;gt;Sign In With Github&amp;lt;/button&amp;gt;
      ) : (
        &amp;lt;button onClick={signOut}&amp;gt;Log Out, {user?.email}&amp;lt;/button&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  );
}

export default App;


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

&lt;/div&gt;



&lt;p&gt;Looking at this code, this will handle just about all of the auth workflow that we need. &lt;/p&gt;

&lt;p&gt;We are able to sign in with the &lt;code&gt;signInWithGithub()&lt;/code&gt; function and sign out with &lt;code&gt;signOut()&lt;/code&gt;. One import piece is the listener for AuthStateChanges, which is what the code in the &lt;code&gt;supabase.auth.onAuthStateChanges()&lt;/code&gt; block handles. This will constantly listen for any changes (including if a user already has an active session when first entering our web app so they don't need to log in unnecessarily). &lt;/p&gt;

&lt;p&gt;You might be wondering what happens to a user that hasn't visited our web app before and doesn't yet have an account. Since we are not managing our own authentication, they can create an account in our application by creating an account in Github and we will have them handle our auth. &lt;/p&gt;





</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Use JWT with Node.js, Express, and SQLite</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Tue, 19 Jan 2021 20:36:33 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/how-to-use-jwt-with-node-js-express-and-sqlite-3jcc</link>
      <guid>https://dev.to/mwolfhoffman/how-to-use-jwt-with-node-js-express-and-sqlite-3jcc</guid>
      <description>&lt;h1&gt;
  
  
  How to Use JWT with Node.js, Express, and SQLite
&lt;/h1&gt;

&lt;p&gt;I start a lot of side projects (and occasionally even finish them). They tend to have a few things in common, like data persistence, authentication, and session storage. &lt;/p&gt;

&lt;p&gt;These items can be a bit of a pain to write from scratch every single time. I haven't found a lightweight and simple template for this that I enjoy yet. To be honest, the developer portion of me hasn't really looked because I was planning on building this out myself one day. &lt;/p&gt;



&lt;h1&gt;
  
  
  The Template
&lt;/h1&gt;

&lt;p&gt;I started a template that will serve the following purposes. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local Authentication using JWT and Session Storage.&lt;/li&gt;
&lt;li&gt;Data Persistence with SQLite (by default running in memory).&lt;/li&gt;
&lt;li&gt;Simple/Lightweight template to quickly create REST APIs for MVPs.&lt;/li&gt;
&lt;/ul&gt;



&lt;h1&gt;
  
  
  Disclaimer
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;This project is not intended for production use.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is for dev purposes only and should not be used in a production environment. &lt;/p&gt;



&lt;h1&gt;
  
  
  Source Code
&lt;/h1&gt;

&lt;p&gt;The entire project can be found &lt;a href="https://github.com/mwolfhoffman/node-jwt-sqlite-starter"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is an open liscence so fork it, modify it, make it yours. Feel free to file any issues or make PRs as well.&lt;/p&gt;



&lt;h1&gt;
  
  
  Dependencies
&lt;/h1&gt;

&lt;p&gt;Here are the dependencies used for this project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -s bcrypt body-parser cookie-parser 
cors express express-session express-session-sqlite
njwt nnode sqlite3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h1&gt;
  
  
  Package.json
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "node-jwt-sqlite-starter",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1",
    "start": "node index.js",
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "bcrypt": "^5.0.0",
    "body-parser": "^1.19.0",
    "cookie-parser": "^1.4.5",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "express-session": "^1.17.1",
    "express-session-sqlite": "^2.0.8",
    "njwt": "^1.0.0",
    "nnode": "^0.3.3",
    "sqlite3": "^5.0.1"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h1&gt;
  
  
  index.js
&lt;/h1&gt;

&lt;p&gt;This is all that is needed in the &lt;code&gt;index.js&lt;/code&gt;. The reason for this file is more to import &lt;code&gt;nnode&lt;/code&gt; which allows us to use the latest ECMAScript features in JS. &lt;/p&gt;

&lt;p&gt;If you don't want to use &lt;code&gt;nnode&lt;/code&gt; and are cool writing ES5, then you really can just add all of the &lt;code&gt;app.js&lt;/code&gt; contents here. &lt;/p&gt;

&lt;p&gt;My tech debt is showing, but I kept getting errors trying to include all of my server code in the same file I require &lt;code&gt;nnode&lt;/code&gt; in so I split them out like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require('nnode');
require('./app');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h1&gt;
  
  
  app.js
&lt;/h1&gt;

&lt;p&gt;Here is where our &lt;code&gt;express&lt;/code&gt; server will live.&lt;/p&gt;

&lt;p&gt;I included quite a bit of middleware in here, which we will create in just a moment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import bodyParser from 'body-parser';
import dao from './repositories/dao';
import { authenticated, authMiddleware } from './controllers/auth.controller';
import authRoutes from './routes/auth.routes';
import itemsRoutes from './routes/items.routes';
const session = require('express-session');
const cookieParser = require('cookie-parser');
import * as sqlite3 from 'sqlite3'
import sqliteStoreFactory from 'express-session-sqlite'

const port = 3000;
export const app = express();

app.listen(port, () =&amp;gt; console.log(`Node-JWT-SQLite-Starer is listening on port ${port}!`));
app.use(bodyParser.json());
app.use(authMiddleware);
app.use(cookieParser());

app.use(session({ secret: "super secret string" }));
const SqliteStore = sqliteStoreFactory(session)
app.use(session({
    store: new SqliteStore({
        driver: sqlite3.Database,
        path: ':memory:',
        ttl: 604800000, // 1 week in miliseconds
    }),
}));

//  Script to setup sqlite DB in memory //
dao.setupDbForDev();
////////////////////////////////////

app.use('/api/auth', authRoutes);
app.use('/api/items', authenticated, itemsRoutes);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will want to create a config file to hold sensitive values such as the session secret. &lt;/p&gt;

&lt;p&gt;You will see that &lt;code&gt;body-parser&lt;/code&gt;, &lt;code&gt;cookie-parser&lt;/code&gt;, &lt;code&gt;expresss-session&lt;/code&gt; and a lot of middleware is setup here. &lt;/p&gt;

&lt;p&gt;Go through this and refactor for your needs. &lt;/p&gt;

&lt;p&gt;By default, I have a session with a ttl for 1 week. And you can see it is using a SQLite data store. &lt;/p&gt;

&lt;p&gt;I also have abstracted out some routes, controllers, and a repository. &lt;/p&gt;

&lt;p&gt;Let's get into some of that now. &lt;/p&gt;



&lt;h1&gt;
  
  
  repositorys/dao.js
&lt;/h1&gt;

&lt;p&gt;The purpose of this DAO file is to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Setup the DB with the &lt;code&gt;setupDbForDev()&lt;/code&gt; function. This will create tables and insert values. &lt;/p&gt;

&lt;p&gt;Because the DB is running in memory in this template, it will need to create the table and insert values each time the server is restarted. &lt;/p&gt;

&lt;p&gt;You can update the tables and values to fit your needs. &lt;/p&gt;

&lt;p&gt;You can also host the SQLite db one your local machine or elsewhere instead of using memory&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Abstracting out common SQLite functionality&lt;/p&gt;

&lt;p&gt;This projects uses the &lt;code&gt;sqlite3&lt;/code&gt; node module to connect and query the SQLite DB. I find myself constantly copying code that runs the library's three main commands so I abstracted those commands here and return a promise.&lt;br&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database(':memory:');
const bcrypt = require('bcrypt');
const saltRounds = 10;



export default class {

    static setupDbForDev() {
        //  This sets up a DB in memory to be used by creating tables, inserting values, etc.
        db.serialize(function () {
            const createUsersTable = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT,username TEXT, password text)";
            db.run(createUsersTable);
            const createItemsTable = "CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price NUMERIC)";
            db.run(createItemsTable);
            let password = '123'

            bcrypt.hash(password, saltRounds, function (err, hash) {
                const insertUsers = `INSERT INTO users (username, password) VALUES ('foo', '${hash}'), ('bar', '${hash}');`
                db.run(insertUsers);
            });
            const insertItems = `INSERT INTO items (name, price) VALUES ('book', 12.99), ('t-shirt', 15.99), ('milk', 3.99);`
            db.run(insertItems);
        });
    }

    static all(stmt, params) {
        return new Promise((res, rej) =&amp;gt; {
            db.all(stmt, params, (error, result) =&amp;gt; {
                if (error) {
                    return rej(error.message);
                }
                return res(result);
            });
        })
    }
    static get(stmt, params) {
        return new Promise((res, rej) =&amp;gt; {
            db.get(stmt, params, (error, result) =&amp;gt; {
                if (error) {
                    return rej(error.message);
                }
                return res(result);
            });
        })
    }

    static run(stmt, params) {
        return new Promise((res, rej) =&amp;gt; {
            db.run(stmt, params, (error, result) =&amp;gt; {
                if (error) {
                    return rej(error.message);
                }
                return res(result);
            });
        })
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h1&gt;
  
  
  repository/repository.js
&lt;/h1&gt;

&lt;p&gt;This file is where some of the data access code can live. You will see shortly that the controllers are calling these functions. &lt;/p&gt;

&lt;p&gt;This starter project is very simple in terms of data needs and there may need to be more processing and data mapping performed here (or in another service).&lt;/p&gt;

&lt;p&gt;For this starter template, the repository is more or less just a pass-through.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import dao from './dao';
const bcrypt = require('bcrypt');
const saltRounds = 10;

export default class {

    static async getAllItems() {
        return await dao.all("SELECT * FROM items", [])
    }

    static async getItemById(id) {
        return await dao.get("SELECT * FROM items WHERE id = ?", [id])
    }

    static async getUserByUsername(username) {
        return dao.get("SELECT * FROM users WHERE username =?", [username]);
    }

    static async getUserById(id) {
        return dao.get('SELECT * FROM users WHERE id = ?', [id]);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h1&gt;
  
  
  controllers/auth.controller.js
&lt;/h1&gt;

&lt;p&gt;This is where the auth code is. &lt;/p&gt;

&lt;p&gt;The project uses &lt;code&gt;bcrypt&lt;/code&gt; to hash password and save it to our in-memory SQLite data store. &lt;/p&gt;

&lt;p&gt;JWT tokens are encoded/decoded by &lt;code&gt;njwt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This file calls the repository we just created to find the matching user on login and check for a password match.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import njwt from 'njwt';
import repository from '../repositories/repository';
const bcrypt = require('bcrypt');

const {
  APP_SECRET = 'secret' } = process.env;

const encodeToken = (tokenData) =&amp;gt; {
  return njwt.create(tokenData, APP_SECRET).compact();
}

const decodeToken = (token) =&amp;gt; {
  return njwt.verify(token, APP_SECRET).setExpiration(new Date().getTime() + 604800000).body; //1 week
}

export const authMiddleware = async (req, res, next) =&amp;gt; {
  const token = req.header('Access-Token');
  if (!token) {
    return next();
  }

  try {
    const decoded = decodeToken(token);
    const { userId } = decoded;
    const user = await repository.getUserById(userId)
    if (user) {
      req.userId = userId;
    }
  } catch (e) {
    return next();
  }
  next();
};

export const authenticated = (req, res, next) =&amp;gt; {
  if (req.userId) {
    return next();
  }

  res.status(401);
  res.json({ error: 'User not authenticated' });
}

const returnInvalidCredentials = (res) =&amp;gt; {
  res.status(401);
  return res.json({ error: 'Invalid username or password' });

}

export const login = async (req, res) =&amp;gt; {
  const { username, password } = req.body;


  const user = await repository.getUserByUsername(username)

  if (!user) {
    returnInvalidCredentials(res)
  }

  bcrypt.compare(password, user.password, (err, result) =&amp;gt; {
    if (result) {
      const accessToken = encodeToken({ userId: user.id });
      return res.json({ accessToken });
    } else {
      return returnInvalidCredentials(res);
    }
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h1&gt;
  
  
  controllers/items.controller.js
&lt;/h1&gt;

&lt;p&gt;This is just a sample controller that calls the repository to get DB data. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;./repository/dao.js&lt;/code&gt;'s &lt;code&gt;setupDbForDev()&lt;/code&gt; function creates a table of items and inserts a few items so these controller methods are used to get those items.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import repository from '../repositories/repository';
import dao from '../repositories/dao'

export default class {
    static async getAllItems(req, res) {
        let items = await repository.getAllItems();
        return res.send({ items });
    };

    static async getItemById(req, res) {
        let item = await repository.getItemById(req.params.id)
        return res.send({ item });
    }

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

&lt;/div&gt;





&lt;h1&gt;
  
  
  routes/auth.js
&lt;/h1&gt;

&lt;p&gt;Here is a route file that handles our one auth route, &lt;code&gt;/login&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You will likely modify this and add a logout and what not. A lot of the other auth related code you already saw lives in the auth contorller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { login } from '../controllers/auth.controller';
import * as express from 'express';
const router = express.Router()

router.post('/login', login)

module.exports = router
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h1&gt;
  
  
  routes/items.js
&lt;/h1&gt;

&lt;p&gt;Last, here are our item routes to get items from the in-memory SQLite data store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import itemsController from '../controllers/items.controller';
import * as express from 'express';
const router = express.Router()

router.get("/", itemsController.getAllItems);
router.get("/:id", itemsController.getItemById)

module.exports = router
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h1&gt;
  
  
  Tying It All Together
&lt;/h1&gt;

&lt;p&gt;Those are all of the files to start the project. If you haven't installed the node modules be sure to run &lt;code&gt;npm i&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After that, run the project with &lt;code&gt;npm run start&lt;/code&gt;.&lt;/p&gt;



&lt;h1&gt;
  
  
  Authenticating
&lt;/h1&gt;

&lt;p&gt;If you make a request to any of the &lt;code&gt;item&lt;/code&gt; endpoints, you should get a 401/unauthorized error. &lt;/p&gt;

&lt;p&gt;Let's authenticate. &lt;/p&gt;

&lt;p&gt;We can do that by sending a &lt;code&gt;POST&lt;/code&gt; request to &lt;code&gt;localhost:3000/api/auth/login&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We need our request body to include one of the username/password combos in &lt;code&gt;repositories/dao.js&lt;/code&gt; like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "username":"foo",
    "password":"123"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that we will get back a 200 status with a response that includes an access-token. &lt;/p&gt;

&lt;p&gt;The response should look like this ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "access_token":"&amp;lt;YOUR ACCESS TOKEN&amp;gt;"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, take our access token and add it to your headers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Content-Type": "application/json",
    "Accept":"*/*",
    "Access-Token: "YOUR ACCESS TOKEN FROM ABOVE"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now be authenticated. &lt;/p&gt;

&lt;p&gt;Try out a &lt;code&gt;GET&lt;/code&gt; request to &lt;code&gt;localhost:3000/api/items&lt;/code&gt; and you should get the list of 3 items as a response. &lt;/p&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That's about it. It's a lightweight starter for any node.js API. It has authentication, session storage, data storage, and would work great to use as a template for dev side projects, MVPs, etc. &lt;/p&gt;

&lt;p&gt;Again, this is not intended for production use. &lt;/p&gt;

&lt;p&gt;If you found this useful, consider &lt;a href="https://www.buymeacoffee.com/codewithwolf"&gt;buying me a coffee&lt;/a&gt;. I hope you will enjoy using this project to start your own node.js APIs.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Best JS Framework and How To Choose One</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Sat, 16 Jan 2021 14:08:43 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/the-best-js-framework-and-how-to-choose-one-ein</link>
      <guid>https://dev.to/mwolfhoffman/the-best-js-framework-and-how-to-choose-one-ein</guid>
      <description>&lt;h1&gt;
  
  
  The Best JS Framework and How to Choose One
&lt;/h1&gt;

&lt;p&gt;A popular topic among web developers is what the best modern javascript framework is. &lt;/p&gt;

&lt;p&gt;Usually the big three (Angular, Vue, and React) get compared for things like bundle size, performance, adoption, etc. By the end of the post, the writer will give their conclusion. &lt;/p&gt;

&lt;p&gt;I’ve used the big three extensively for the last four or so years and wanted to give an updated opinion that I don’t see too often. &lt;/p&gt;



&lt;h1&gt;
  
  
  State of JS
&lt;/h1&gt;

&lt;p&gt;First off, the &lt;a href="https://2020.stateofjs.com/en-US/"&gt;State of JS &lt;/a&gt; was released this week. And it shows tons of stats for dev opinions on JS, libraries, features, etc. &lt;/p&gt;

&lt;p&gt;As far as frameworks go, React looked like the big winner there with Vue not too far behind it. It looked like Angular devs looked like they were the least happy in that survey.&lt;/p&gt;



&lt;h2&gt;
  
  
  It Doesn’t Matter
&lt;/h2&gt;

&lt;p&gt;Honestly, It doesn’t matter. For the most part, they are all the same.&lt;/p&gt;

&lt;p&gt;Yes, there are minimal differences that still exist today. &lt;/p&gt;

&lt;p&gt;For example, if you want a job, maybe React is better in the US. There are more React jobs in the US so it would make sense to learn React if you are looking for a position. &lt;/p&gt;

&lt;p&gt;But are you not going to get a job with only Angular or Vue skills? I mean there are still plenty of Backbone and Ember jobs too, so I don’t really see the issue here.&lt;/p&gt;



&lt;h3&gt;
  
  
  Framework Shouldn't Determine Hirability
&lt;/h3&gt;



&lt;p&gt;And one of the more ridiculous things a job posting could have is something like: “Must have 3 years of React experience”.  &lt;/p&gt;

&lt;p&gt;If someone has used Angular and/or Vue for 5 years, do you really think they won’t be able to be productive in React within a few days or weeks? They could probably look at a company's existing react app and immediately write code. &lt;/p&gt;

&lt;p&gt;If your team is hiring someone because they have experience in the one particular framework and not for their ability to solve complex problems and learn the best tool for the job, you might want to re-think your hiring policy.&lt;/p&gt;



&lt;h2&gt;
  
  
  It Used To Matter
&lt;/h2&gt;

&lt;p&gt;It for sure used to matter. &lt;/p&gt;

&lt;p&gt;AngularJS’s original scoping where it used dirty checking to update state was inefficient. React’s state management which eventually led to redux was significantly more efficient. I wrote a Vue/TypeScript app even just a year ago and the TS support was pretty awful. Angular 2 had great TS support, and now all three of them do.  &lt;/p&gt;

&lt;p&gt;Vue.js apps tended to have the smallest bundle sizes and was seen as an up and comer, but now neither of the big three really differ enough to have that be the straw that breaks your application’s back. &lt;/p&gt;

&lt;p&gt;Here is another example. React came out with hooks for their functional components. Aficionados everywhere were pleased. Vue didn’t have that! Oh, but now they do. The Vue Composition API are just react hooks for vue. &lt;/p&gt;

&lt;p&gt;It seems that these framworks have been in a state of convergent evolution. They have adapted in their environments and independently begun to portray the same traits over time. &lt;/p&gt;

&lt;p&gt;Bundle size might be the last real difference to talk about, so let's do that. &lt;/p&gt;



&lt;h2&gt;
  
  
  Bundle Size... Does Size Matter?
&lt;/h2&gt;

&lt;p&gt;The bundle size of your application is going to matter some, yes. This &lt;a href="https://gist.github.com/Restuta/cda69e50a853aa64912d"&gt;README&lt;/a&gt; shows the minified bundle size of each core library and some of their combinations. &lt;/p&gt;

&lt;p&gt;Angular is the clear loser here, vue is the smallest of the big three. Preact (a lightweight React alternative) minfies down to 16kb according to that link. 3kb on their website! Eitherway it is very lightweight.&lt;/p&gt;

&lt;p&gt;While the README does show the bundle size for React, React DOM, and Redux combined... this brings up one issue on bundle size. &lt;/p&gt;

&lt;p&gt;It's not so much the framework's bundle size that matters but your dependence on other libraries. A Vue app with Vuex, Moment, Axios, Lodash, and more will start to add up. You might find yourself as heavy as a small React/Redux app as you add more dependencies. And if your coding practices are bad in that bloated vue app, you will see performance drawbacks.&lt;/p&gt;

&lt;p&gt;So if bundle size is your determining factor, you'll want to work too keep that small no matter what framework you are choosing. &lt;/p&gt;



&lt;h2&gt;
  
  
  It Just Doesn’t Really Matter Now
&lt;/h2&gt;

&lt;p&gt;It really doesn’t matter now. These frameworks have become so similar that trying to even determine the best one for a specific tasks becomes a challenge. Any of the frameworks can now build any application your team would need. &lt;/p&gt;

&lt;p&gt;Any modern JS project is going to be bloated compared to vanilla JS. &lt;/p&gt;

&lt;p&gt;But any modern JS project is also going to be tree shaken and minified. &lt;/p&gt;

&lt;p&gt;Want a small bundle size? Watch your dependencies and use clean code practices like lazy loading and selective imports. &lt;/p&gt;

&lt;p&gt;React by itself is tiny. Throw in redux, react-router, thunk, Moment, Lodash, TypeScript, and before you know it, your bundle size can’t fit in the state of Texas.&lt;/p&gt;



&lt;h2&gt;
  
  
  What Does Matter
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;User happiness&lt;/strong&gt; is a big one. Do you like Angular and Vue directives more than JSX as far as templating goes? React might not be for you out of the box. &lt;/p&gt;

&lt;p&gt;But if you are working with a framework you’ll have more positive experiences and you’ll use that framework more. &lt;/p&gt;

&lt;p&gt;You'll spend more time with it, learn it's intricacies, and best practices. This is what will make your app efficient and you a productive developer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What matters is your ability to choose a framework, stick with it through it’s drawbacks and then master that framework.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you can do that, you can learn another framework for another project or position. &lt;/p&gt;

&lt;p&gt;I don’t think the question really should be which framework is better. They are all perfectly fine and can do anything web application related. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The question should be how can I learn to use this framework to master any requirements thrown at me.&lt;/strong&gt; &lt;/p&gt;



&lt;h2&gt;
  
  
  An Example
&lt;/h2&gt;

&lt;p&gt;Let's say there is a small Vue app and it doesn't even have that many dependencies, but we have a view with nested components. In the mounted lifecycle hook of a few of those components it makes an expensive API call and blocks the page with a spinner to show that data is being fetch. Let's say some of these components in this view are nested... and a few of them have that same API call. It gets made twice or three times whe the user navigates to this specific page. Then when a user navigates away and comes back during the same session, the components don't check state for that data and make the duplicate/triplicate expensive API calls again.&lt;/p&gt;

&lt;p&gt;Is bundle size killing you here? Too many dependencies? &lt;/p&gt;

&lt;p&gt;No. The framework is being used incorrectly here and is your downfall. &lt;/p&gt;

&lt;p&gt;This is an extreme example. But one or two of these mistakes in this example can occur throughout an application and affect usability and load times. &lt;/p&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;The three main frameworks have been in a state of convergent evolution. They now are pretty similar. A year ago, I wouldn't have said that. But at this point, they are about the same. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Their bundle sizes are the main difference these days, but clean coding practices will affect performance more than pure bundlesize.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, if you don't lazy load components and you have nested components making the same expensive API call in a mounted hook that will fire twice, things like this will kill your app. A memory leak could hurt you more in a Preact (lightweight react alternative with a 3kb bundle size) app than than Angular's bundle size. You should check state on page load instead of fetching data from a server each time, etc.&lt;/p&gt;

&lt;p&gt;Choose a framework that you like. Stick with it and learn it's best practices, and you will have great efficient applications.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What is CI/CD: Continuous Integration and Continuous Delivery For Beginners</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Thu, 07 Jan 2021 16:41:54 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/what-is-ci-cd-continuous-integration-and-continuous-delivery-for-beginners-1104</link>
      <guid>https://dev.to/mwolfhoffman/what-is-ci-cd-continuous-integration-and-continuous-delivery-for-beginners-1104</guid>
      <description>&lt;p&gt;CI and CD are two software development processes that allow teams to integrate code and deploy products to users faster, safer, cheaper and easier. &lt;/p&gt;

&lt;p&gt;I will discuss both of these methods and their benefits. &lt;/p&gt;

&lt;p&gt;Both of these methods have been around in some form since the 1990s but have gained popularity more recently as they solve common integration and deployment issues teams often face. &lt;/p&gt;



&lt;h1&gt;
  
  
  What is CI?
&lt;/h1&gt;

&lt;p&gt;CI is Continuous Integration. &lt;/p&gt;

&lt;p&gt;This is a process where the development team frequently checks their code into the same source control repository and branch so that it is frequently integrated. &lt;/p&gt;



&lt;h2&gt;
  
  
  Commit Frequently
&lt;/h2&gt;

&lt;p&gt;Each developer should check their code into this branch at least once per day, but ideally it would be even more than that. &lt;/p&gt;

&lt;p&gt;As the code is checked in from all developers on the project into a single branch, a build is created. &lt;/p&gt;

&lt;p&gt;The build can consist of scripts and tasks that need to run, such as variable swapping, unit tests, etc. &lt;/p&gt;



&lt;h2&gt;
  
  
  Code is Integrated With Each Commit
&lt;/h2&gt;

&lt;p&gt;The developer checking in the code at the time can watch the build and if it fails, he or she will know that their commit broke the build. &lt;/p&gt;

&lt;p&gt;They are then able to fix this immediately. &lt;/p&gt;



&lt;h2&gt;
  
  
  Without CI
&lt;/h2&gt;

&lt;p&gt;The ability to integrate code daily and immediately fix broken builds is important because the common practice without CI is that each developer would work on a separate branch and at the end of a cycle, right before a release, the developers would all create merge requests into the deployment branch.&lt;/p&gt;

&lt;p&gt;That would mean that there is no way to know if all of the code will integrate together until right before the release. &lt;/p&gt;

&lt;p&gt;If there were bugs during this integration process, they would be caught at the end of the cycle and there would be a huge scramble to fix them. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It could mean a delay of a promised feature or the release entirely.&lt;/strong&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Costly Integrations Without CI
&lt;/h2&gt;

&lt;p&gt;You can imagine that the scenario where all developers integrate their code immediately before a deployment can be costly. &lt;/p&gt;

&lt;p&gt;With CI, a developer knows if their code was integrated immediately after checking it in because they can check if the build failed. &lt;/p&gt;

&lt;p&gt;If the build fails, they can immediately fix their code.&lt;/p&gt;

&lt;p&gt;Imagine finishing some bug fixes or features quickly in the cycle and continuing to move on to new tasks, then right at the end of the cycle, your code doesn’t integrate! You (the developer) need to switch gears and go back to this old task you worked on and work as fast as possible to get it fixed. Then it needs to be integrated and tested over again. &lt;/p&gt;

&lt;p&gt;CI fixes this common problem. &lt;/p&gt;



&lt;h2&gt;
  
  
  Benefits
&lt;/h2&gt;

&lt;p&gt;The big benefit is the ease of integrating code. This saves time and money, bugs are found earlier and can be fixed faster. &lt;/p&gt;

&lt;p&gt;Your build pipeline can check unit tests and fail the build if one fails. After a successful build, automated tests and end to end tests can run. &lt;/p&gt;

&lt;p&gt;All in all, CI is a huge win for companies that migrate to this process. &lt;/p&gt;






&lt;h4&gt;
  
  
  Pro Tip:
&lt;/h4&gt;

&lt;p&gt;Developers can run the pipeline locally and make sure there are no merge conflicts, failed tests, and other issues before the code is allowed to be pushed to the repository.&lt;/p&gt;






&lt;h1&gt;
  
  
  What is CD?
&lt;/h1&gt;

&lt;p&gt;CD is often associated with CI. CD could be Continuous Delivery or Continuous Deployments.&lt;/p&gt;

&lt;p&gt;These are two slightly different processes from each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continuous Deployments&lt;/strong&gt; would mean that each time code is checked in, it is automatically deployed. &lt;/p&gt;

&lt;p&gt;While there are pros and cons to this approach, I would usually prefer Continuous Delivery as it gives a team more control. &lt;/p&gt;

&lt;p&gt;The rest of this post will refer to CD as Continuous Delivery (not Continuous Deployment. See? Confusing!)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continuous Delivery&lt;/strong&gt; (often confused with Continuous Deployments) means that a development team has the ability to deploy their codebase at any time, though they can chose when as it is not automatically deployed with each integration. &lt;/p&gt;



&lt;h2&gt;
  
  
  Freedom to Deploy Any time
&lt;/h2&gt;

&lt;p&gt;If a feature is ready to go and is accepted, it can be deployed. &lt;/p&gt;

&lt;p&gt;The master branch (or deployment branch) is always ready for production. &lt;/p&gt;

&lt;p&gt;A team can deploy to production multiple times a day if it works for them. &lt;/p&gt;

&lt;p&gt;They could do a daily deployment, or still deploy at the end of a sprint knowing that the codebase is always ready for production.&lt;/p&gt;



&lt;h2&gt;
  
  
  Build to a Lower Environment for Testing Immediately
&lt;/h2&gt;

&lt;p&gt;As code is checked in multiple times a day because of a team’s CI process, maybe a team doesn’t want code to go directly to production. &lt;/p&gt;

&lt;p&gt;But, code can be automatically deployed to a test environment for the QA team to get a look at. &lt;/p&gt;

&lt;p&gt;It can also be deployed to an environment for viewing by the business team as code is integrated. That way, design and user experience can be accepted as it is worked on. &lt;/p&gt;

&lt;p&gt;This can prevent a situation where a developer works for a full cycle (or more) on a new feature and as it is integrated and built to a test environment right before a release, the business team finds flaws in the UX and wants the design changed. &lt;/p&gt;



&lt;h2&gt;
  
  
  Simpler Deployments
&lt;/h2&gt;

&lt;p&gt;Again, code can deploy to a test, staging and/or prod environment immediately. &lt;/p&gt;

&lt;p&gt;This can occur because the process is automated. It can be set up so as a developer commits code, a hook is caught and the codebase is built and immediately deployed by running scripts and tasks that the team set up. &lt;/p&gt;

&lt;p&gt;It can also be manually deployed at the push of a button. This might be a better way to deploy to QA or Production for your team. &lt;/p&gt;

&lt;p&gt;No matter how your team decides to deploy, CD gives that flexibility. &lt;/p&gt;



&lt;h2&gt;
  
  
  Flexible Deployments
&lt;/h2&gt;

&lt;p&gt;Speaking of flexibility, all deployments can be set up the same. If something needs to change, it can be tested in Test, Acceptance, Staging, or a lower environment to ensure that it will work when deploying to production. &lt;/p&gt;



&lt;h2&gt;
  
  
  Flexible Tooling
&lt;/h2&gt;

&lt;p&gt;While there are many tools like: GoCD, Jenkins, Azure Devops, etc. that allow you to create your deployment pipeline, they have one thing in common. &lt;/p&gt;

&lt;p&gt;They are flexible. &lt;/p&gt;

&lt;p&gt;CI and CD are not rigid processes. They are language, framework, and culture agnostic. &lt;/p&gt;

&lt;p&gt;Need a bash script to run? Maybe a little powershell now? Need to install npm or nuget packages? a ruby gem (I think that's a thing, right?). &lt;/p&gt;

&lt;p&gt;These tools will allow you to do that in a manner that works with your team's workflow and culture without having to make a large institutional change in the tooling. &lt;/p&gt;



&lt;h2&gt;
  
  
  If Everyone is Committng to the Same Branch, Won't There Be Code Conflicts?
&lt;/h2&gt;

&lt;p&gt;Yes, if you are not communicating with your team. &lt;/p&gt;

&lt;p&gt;Members on the team should not be working on the same portions of a code base that would conflict regardless of committing to the same branch with CI/CD or if they are using a feature branch and integrating code once before each release. &lt;/p&gt;

&lt;p&gt;Even without CI and CD, this is the kind of practice that would lead to conflicts and integration issues.&lt;/p&gt;

&lt;p&gt;It is important to communicate this with your team and distribute work appropriately. &lt;/p&gt;

&lt;p&gt;That doesn't change with Continuous Integration and Continuous Deployments. &lt;/p&gt;

&lt;p&gt;What changes is that the code is integrated frequently.&lt;/p&gt;



&lt;h1&gt;
  
  
  If Everyone is Committing to the Master Branch, Won’t it Get Polluted with Code That is Not Production Ready?
&lt;/h1&gt;

&lt;p&gt;Yes and no. &lt;/p&gt;

&lt;p&gt;CI/CD works best with agile teams that deploy small features every 2 or 3 weeks. &lt;/p&gt;

&lt;p&gt;Now, let’s say you are working on a large feature that takes 10 weeks. That means your code would be polluting the deployment branch for the devs working on smaller items in the cycle. &lt;/p&gt;

&lt;p&gt;Should you just commit to a separate branch? &lt;/p&gt;

&lt;p&gt;No. &lt;/p&gt;

&lt;p&gt;That would break CI because your code needs to be integrated at least daily to know that it doesn’t break a build. And 10 weeks without an integration?! That’s a huge risk. &lt;/p&gt;

&lt;p&gt;There are options for this, one common and excellent solution that is often utilized is by using a feature flag.&lt;/p&gt;



&lt;h2&gt;
  
  
  Feature Flags
&lt;/h2&gt;

&lt;p&gt;A feature flag allows you to hide code behind a toggle. You can decide which users can view your code and in which environments. &lt;/p&gt;

&lt;p&gt;This can be useful for progressively deploying a new feature out to users, or collecting feedback on some new integration. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A feature flag is also an excellent tool for Continuous Integration.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Getting into how you can use a feature flag is out of scope for this article, but check out  &lt;a href="%E2%80%9Dhttps://launchdarkly.com/%E2%80%9D"&gt;  Launch Darkly’s &lt;/a&gt; website. They have excellent docs and I have used their product and highly recommend them. &lt;/p&gt;



&lt;h1&gt;
  
  
  Downside
&lt;/h1&gt;

&lt;p&gt;Is there a downside to CI/CD? &lt;/p&gt;

&lt;p&gt;I can think of a few&lt;/p&gt;



&lt;h2&gt;
  
  
  Human Error
&lt;/h2&gt;

&lt;p&gt;CI/CD automates the build process. That eliminates the possibilities for human error. Except that computers really only do what humans tell them to. &lt;/p&gt;

&lt;p&gt;So who sets up the build processes? Humans. &lt;/p&gt;

&lt;p&gt;And when a process needs to change for a specific deployment or a new pipeline needs to be created, who does that? &lt;/p&gt;

&lt;p&gt;Humans. &lt;/p&gt;

&lt;p&gt;While CI/CD makes integration and deployment faster, safer, cheaper, easier, and removes a lot of possibility for human error… there is still room for some human error. And man do you feel dumb when you mess something up! &lt;/p&gt;

&lt;p&gt;Computers and automation won't fix everything. Developers need to learn the tooling and processes and apply them appropriately.&lt;/p&gt;



&lt;h2&gt;
  
  
  Cultural Change
&lt;/h2&gt;

&lt;p&gt;The biggest downside to CI/CD is the cultural change it takes to implement it. &lt;/p&gt;

&lt;p&gt;I’m sure I lost tons of people when I said that devs should be committing code multiple times a day to the master branch. &lt;/p&gt;

&lt;p&gt;It sounded crazy to me at first… until I did it, and a few cycles later it started to make sense. &lt;/p&gt;

&lt;p&gt;Who is going to run the deployments? Well, see… your pipeline will just run… no one is responsible for manually deploying anymore. That is another one that doesn’t always make sense. &lt;/p&gt;

&lt;p&gt;Finding these issues and working them out will be unique to your team's culture and needs.&lt;/p&gt;

&lt;p&gt;It will take time, but the benefits of CI/CD tend to be worth it. &lt;/p&gt;



&lt;h2&gt;
  
  
  Slow For Teams to Implement
&lt;/h2&gt;

&lt;p&gt;Part of the reason it is slow for teams to implement is the cultural change. &lt;/p&gt;

&lt;p&gt;But when I began using CI/CD, it was unclear when we would need a feature flag or what environment we wanted to deploy to and when. &lt;/p&gt;

&lt;p&gt;These are things that will certainly take time and collaboration. &lt;/p&gt;

&lt;p&gt;It’s energy well spent though to get to a point where integration is regular and deployments are a breeze. &lt;/p&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;CI is continuous integration. It is a practice where development teams commit their code into a shared repository and the code is immediately integrated together with the rest of the development team's code. &lt;/p&gt;

&lt;p&gt;This can help a team find integration issues immediately and fix them. &lt;/p&gt;

&lt;p&gt;This can also be done in a manner where the repository is always ready for a deployment at any time. &lt;/p&gt;

&lt;p&gt;The concept of being able to deploy at any time is Continous Delivery. (Often confused with Continuous Deployment which is when code is deployed immediately and automatically after it is integrated).&lt;/p&gt;

&lt;p&gt;These two practices, CI and CD, can help teams deliver code faster, with few bugs, and spending less time on the deployments and integrations and more time on development, thus saving a company money. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>What To Do With Shared And Complex Logic in React Applications
</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Thu, 07 Jan 2021 16:37:02 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/what-to-do-with-shared-and-complex-logic-in-react-applications-b4a</link>
      <guid>https://dev.to/mwolfhoffman/what-to-do-with-shared-and-complex-logic-in-react-applications-b4a</guid>
      <description>&lt;p&gt;At my full time job, I write a lot of vue. For my hobby projects outside of work I like to switch back and forth between UI frameworks (or using none at all). &lt;/p&gt;

&lt;p&gt;Lately, I have been playing with React and mostly enjoying my time with it.&lt;/p&gt;

&lt;p&gt;But I did come across a common problem recently that took me a while to come up with a viable solution. &lt;/p&gt;



&lt;h1&gt;
  
  
  The Problem: Shared Complex Logic
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What should I do with my more complex UI logic in react?
&lt;/h2&gt;

&lt;p&gt;I had asked a few talented developers that use react I know. Some of them said that they will write that shared logic in custom hooks. &lt;/p&gt;

&lt;p&gt;I thought that was a great idea, but hooks are only for functional components. That doesn't help with anyone using class based component. &lt;/p&gt;

&lt;p&gt;So I think I came up with a pretty slick way to handle this for ALL react apps and ALL react components (functional AND class components). It would work with or without redux, mobx and requires no library. &lt;/p&gt;



&lt;h2&gt;
  
  
  What is Shared Complex Logic?
&lt;/h2&gt;

&lt;p&gt;By this, I mean API calls, async tasks, presentational logic shared across multiple components, etc.&lt;/p&gt;

&lt;p&gt;Business logic is typically going to live in the API's business layer. &lt;/p&gt;

&lt;p&gt;And while some front-end applications will never face this issue, UI presentational logic can at times get quite complex.&lt;/p&gt;

&lt;p&gt;As your app grows, your business requirements evolve and become more complicated you need a place to hold that logic. &lt;/p&gt;



&lt;h3&gt;
  
  
  Can I Put The Logic in Action Creators?
&lt;/h3&gt;

&lt;p&gt;The first thing I tried was putting this logic in action creators. &lt;/p&gt;

&lt;p&gt;I have found that redux action creators do NOT handle logic well. &lt;/p&gt;

&lt;p&gt;I would add small amounts of logic to a redux action creator. If I was using &lt;code&gt;redux-thunk&lt;/code&gt; and making an API call. This worked great if I had one action to return for a successful request and another one for a failed request.&lt;/p&gt;

&lt;p&gt;But if my action creator had to make an API call and then based on the response, complete more logic before it could return an action, then things got bad fast. &lt;/p&gt;

&lt;p&gt;So no, action creators really are not good for processing more than simple logic.&lt;/p&gt;



&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;p&gt;A solution to my problem that I discovered is to place complex logic, api calls, shared code, and whatnot into a service (or services). &lt;/p&gt;

&lt;p&gt;You can then create a new instance of the service or services and use React's &lt;strong&gt;Context API&lt;/strong&gt; to give access to these services to the component. &lt;/p&gt;



&lt;h1&gt;
  
  
  Example
&lt;/h1&gt;

&lt;p&gt;Let's go through a simple example. &lt;/p&gt;



&lt;h2&gt;
  
  
  Create a Service
&lt;/h2&gt;

&lt;p&gt;We will need a service so let's create something simple. We can have a &lt;code&gt;services&lt;/code&gt; folder in the &lt;code&gt;src&lt;/code&gt; directory and we can call our service &lt;code&gt;data.service.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/services/data.service.js

export default class DataService {
     getSomeData() {
         return new Promise((req,res)=&amp;gt;{
               return setTimeout(()=&amp;gt;{
                   return ["Foo", "Bar", "Baz"]
             }, 1000);
         })
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Above we just have a very simple service that we are going to sort of fake an async request and return an array of strings.&lt;/p&gt;



&lt;h2&gt;
  
  
  Create the Context
&lt;/h2&gt;

&lt;p&gt;We can now create a &lt;code&gt;context&lt;/code&gt; folder in the &lt;code&gt;src&lt;/code&gt; directory to hold our contexts. &lt;/p&gt;

&lt;p&gt;Then I created a &lt;code&gt;context/services.context.js&lt;/code&gt; file. &lt;/p&gt;

&lt;p&gt;I like to keep this in it's own file to prevent any possible circular dependency issues. &lt;/p&gt;

&lt;p&gt;All you really need in there is to create the context and export it.&lt;br&gt;
&lt;/p&gt;

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

import React from "react";

export default React.createContext({});

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

&lt;/div&gt;





&lt;h2&gt;
  
  
  Provide the Context
&lt;/h2&gt;

&lt;p&gt;Now we need to provide our &lt;code&gt;ServiceContext&lt;/code&gt; so it can be consumed by the children components. &lt;br&gt;
In this example I am doing this in the &lt;code&gt;App.js&lt;/code&gt;, but this approach could be modularized and placed in a parent component elsewhere and only accessible to that component's children too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import DataService from './services/data.service';
import ServiceContext from './context/services.context';

class App extends React.Component {

  render() {
    return (
        &amp;lt;ServiceContext.Provider
          value={{
            dataService: new DataService()
          }}
        &amp;gt;
          &amp;lt;App /&amp;gt;
        &amp;lt;/ServiceContext.Provider&amp;gt;
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;In our &lt;code&gt;App.js&lt;/code&gt; we are importing our &lt;code&gt;ServiceContext&lt;/code&gt; and &lt;code&gt;DataService&lt;/code&gt;. We then pass the &lt;code&gt;ServiceContext.Provider&lt;/code&gt; a value with the new &lt;code&gt;DataService&lt;/code&gt; instance so it can be used in the context. &lt;/p&gt;



&lt;h2&gt;
  
  
  Consume the Context
&lt;/h2&gt;

&lt;p&gt;Let's create an example component so we can consume the context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//  src/components/example.component.js

import React from 'react'
import ServiceContext from '../context/services.context';

export default class ExampleComponent extends React.Component {

  static contextType = ServiceContext;

  async componentDidMount() {
    console.log(this.context);
    let data = await this.context.dataService.getSomeData();
  }

  render() {
    return (
      &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;
            Welcome To My Example Component!
        &amp;lt;/h1&amp;gt;
      &amp;lt;/div&amp;gt;
    )
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;You would consume this &lt;code&gt;context&lt;/code&gt; just like you would any other. &lt;/p&gt;

&lt;p&gt;In this component we set the static &lt;code&gt;contextType&lt;/code&gt; property to the &lt;code&gt;ServiceContext&lt;/code&gt; that we imported.&lt;/p&gt;

&lt;p&gt;Then, we can call our &lt;code&gt;DataService&lt;/code&gt;'s &lt;code&gt;getSomeData&lt;/code&gt; method that we created earlier. &lt;/p&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Where is a good place to keep the more complex logic that is shared across multiple components in a react application? &lt;/p&gt;

&lt;p&gt;My first thought was in Action Creators while using Redux. &lt;/p&gt;

&lt;p&gt;But I quickly discovered that redux action creators are not great at completing complex tasks. As your business and presentational logic evolves, you will need to store this logic somewhere. &lt;/p&gt;

&lt;h3&gt;
  
  
  I found that creating a service and using the Context API is a great solution.
&lt;/h3&gt;

&lt;p&gt;This works regardless of using redux, mobx, or any other libraries. No library prevents your ability to do this, and it requires no libraries other than React to implement. &lt;/p&gt;

&lt;p&gt;This approach is flexible. You services contexts can be scoped to any module or it can be global in the &lt;code&gt;App.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This approach is also loosely coupled. If you need to overhaul a service or remove it completely, that can be done easily.&lt;/p&gt;

&lt;p&gt;While the Context API can have performance drawbacks when holding significant amounts of state because of how it re-renders the DOM on updates, this approach does not have these issues because the services are initialized once when the app is loaded and are not updated again.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Common Ailments of Software Developers: Burnout and Imposter Syndrome:
</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Tue, 05 Jan 2021 14:32:42 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/the-common-ailments-of-software-developers-burnout-and-imposter-syndrome-3g78</link>
      <guid>https://dev.to/mwolfhoffman/the-common-ailments-of-software-developers-burnout-and-imposter-syndrome-3g78</guid>
      <description>&lt;p&gt;Software engineering is a rewarding and challenging career. I thoroughly enjoy the teams I get to work with and products that I get to build. I wanted a career where I can learn new things and that every time I open up my laptop to work I am required to be innovative and creative. &lt;/p&gt;

&lt;p&gt;With that said, I have had days, weeks, and months go by where my heart isn’t in it anymore. &lt;/p&gt;

&lt;p&gt;Maybe I consider switching careers to something far from technology. Maybe I could open a bakery or write novels. Being a farmer could be cool, being out in the tall swaying grains with the wind and sun on my face and a subtle cackle of ringneck pheasants from a far carrying through the praries.&lt;/p&gt;

&lt;p&gt;There are times where the unbearable load of always needing to learn to stay current and complete my tasks becomes too much. In fact, that is what got me into software development to begin with. I wanted to be learning on the job all the time. I changed careers from a position where I wasn't ever able to learn. Why is it all of a sudden wearing me down?&lt;/p&gt;

&lt;p&gt;Sometimes I toss and turn all night struggling with a problem I am facing on a project only to come back to work the next day tired, exhausted, and frustrated. How am I going to solve anything like that? Maybe I had a nightmare where I was stuck in a &lt;code&gt;do while&lt;/code&gt; loop. Why? I've only used those once! So scary.&lt;/p&gt;

&lt;p&gt;Maybe I am looking at a list of conference talks some day and the pure genius of the speakers and the elegance of their code is something I know deep in my gut that I can never achieve no matter how hard I try. I am not a good developer, I tell myself. &lt;/p&gt;

&lt;p&gt;Like I said, I like my job and being a software developer is something I enjoy immensely… probably 98% of the time. That’s a pretty good satisfaction stat for anyone at any job. &lt;/p&gt;

&lt;p&gt;But when I start to feel like I mentioned above, it becomes pretty tough. Sometimes it’s an hour, sometimes a few days, but feeling like that for a month or two? That’s just awful.&lt;/p&gt;

&lt;p&gt;While it’s awful, it’s also common.&lt;/p&gt;

&lt;p&gt;There are two reasons software developers (or anyone) can feel like this. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;Imposter Syndrome &lt;/b&gt; and &lt;b&gt;Burnout&lt;/b&gt;. &lt;/p&gt;



&lt;h2&gt;
  
  
  Imposter Syndrome
&lt;/h2&gt;

&lt;p&gt;Imposter syndrome is a fear that you are not good enough or authentic and that you will be exposed as a phony. It's common among software engineers, but can happen to anyone. &lt;/p&gt;

&lt;p&gt;I first suffered from IS when I was learning in a 12 week coding bootcamp. I thought it must just be something the rookies struggle with.&lt;/p&gt;

&lt;p&gt;Then I successfully built a few full stack web applications and got a certificate. I was really a developer!&lt;/p&gt;

&lt;p&gt;I was asked to be a teaching assistant for the next course at that code school. I was the real deal… and then… I got imposter syndrome again! &lt;/p&gt;

&lt;p&gt;It made no sense, there were days where I was teaching students that knew nothing about software development how to code simple HTML pages, and I still had imposter syndrome. How were they going to expose me as a fake? They didn't know what a variable or function was yet! It made no sense! And what will happen in 10 and 11 weeks when they are really coding real stuff? I’ll be exposed for sure!&lt;/p&gt;

&lt;p&gt;Maybe it isn’t the fear or exposure all of the time, but a feeling where you are just not good enough to be a developer at your current position.&lt;/p&gt;

&lt;p&gt;I was excited to finally just get my first job and not have to deal with IS anymore. &lt;/p&gt;

&lt;p&gt;I was wrong. &lt;/p&gt;

&lt;p&gt;To this day, I still have bouts of this horrible disease. What I have learned is that it is a normal part of life and any job, including coding positions. &lt;/p&gt;

&lt;p&gt;I have heard senior and principal developers and CTOs talk about their Imposter Syndrome.&lt;/p&gt;




&lt;h3&gt;
  
  
  Imposter Syndrome is a normal part of being a software developer. It happens to us all.
&lt;/h3&gt;




&lt;h2&gt;
  
  
  Why Tho?
&lt;/h2&gt;

&lt;p&gt;I think it occurs in our field so much for four reasons:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. I just happen to hear about it with software engineers since it is my field. I am sure plumbers, artists, and truck drivers also can get imposter syndrome. Maybe even farmers (my backup plan if all goes awry.)

2. We have a very intellectual position that requires creativity and precise skill on many levels that not only challenge what we think, but *how* we think. 

3. When we get something wrong or struggle with understanding something, it can feel like a personal attack to our mind, how we think, and who we are..

4. The Dunning Kruger Effect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Dunning-Kruger Effect
&lt;/h2&gt;

&lt;p&gt;The Dunning-Kruger Effect states that people with low skill think they are very good, and those with higher skills think that they are poor at what they do. &lt;/p&gt;






&lt;p&gt;The truth is, if you can code an application, complete code challenges, pass a technical interview, build a portfolio, get a programming position at a company, get a bootcamp certificate or CS degree or be self-taught, or do any of the things that some of us likely have done reading this post, then you are good enough to be a programmer (or at the very least learn on the job a bit and become a programmer). &lt;/p&gt;



&lt;h2&gt;
  
  
  Burnout
&lt;/h2&gt;

&lt;p&gt;The other ailment that can often creep it’s way into a developer’s psyche is &lt;b&gt;Burnout&lt;/b&gt;. &lt;/p&gt;

&lt;p&gt;As software engineers, we take pride in our work and feel accomplished when we get a feature or bug fix written with clean code out to users to enjoy. &lt;/p&gt;

&lt;p&gt;But what happens when we no longer feel that sense of accomplishment and just sitting down at our machine to write that code is a struggle?&lt;/p&gt;

&lt;p&gt;That could be Burnout. &lt;/p&gt;

&lt;p&gt;If you feel overwhelmed and stressed at work and you lose your sense of purpose for your job and no longer feel accomplished or interested in your work, you may be suffering from burnout. &lt;/p&gt;

&lt;p&gt;This is again natural and normal. This is something that especially top performers experience, and it's common among but not limited to technical careers.&lt;/p&gt;

&lt;p&gt;A top performer that we look up to may take on larger projects and have more responsibility… but that can come with increased stress and over the long term, that chronic stress ads up. &lt;/p&gt;

&lt;p&gt;If you feel this now or have in the past, you may be experiencing (or have experienced) Burnout. &lt;/p&gt;

&lt;p&gt;I have experienced it, and I’m sure most if not all developers have. &lt;/p&gt;



&lt;h1&gt;
  
  
  The Cure
&lt;/h1&gt;

&lt;p&gt;The best cure is to prevent &lt;strong&gt;Imposter Syndrome&lt;/strong&gt; and &lt;strong&gt;Burnout&lt;/strong&gt; in the first place. &lt;/p&gt;

&lt;p&gt;If you are experiencing symptoms of these horrific diseases, do these things now. If you are not currently suffering from one of these ailments, keep these in mind to prevent them from occurring. &lt;/p&gt;

&lt;p&gt;Also, I'm not a doctor and this is not medical advice.&lt;/p&gt;



&lt;h2&gt;
  
  
  Take a Vacation
&lt;/h2&gt;

&lt;p&gt;Not feeling work? Burning out? Feel like you aren’t a good developer? Take a week off. Don’t look at your computer, don’t write code, don’t think about work or projects. &lt;/p&gt;

&lt;p&gt;You likely love writing code and building things. Take this time away from all of that. You have associated it with a stressful work environment and that needs to be remedied. &lt;/p&gt;

&lt;p&gt;When you come back to your job and coding projects, you will feel a renewed appreciation for the work. &lt;/p&gt;

&lt;p&gt;I tried this at one point in the summer. My girlfriend and our 2 dogs went to Wyoming to do some camping. I came back relaxed, refreshed, and ready to work.&lt;/p&gt;

&lt;p&gt;Take a vacation before trying the next two suggestions.&lt;/p&gt;



&lt;h2&gt;
  
  
  Learn Something Fun and New
&lt;/h2&gt;

&lt;p&gt;We became developers because we enjoy the challenge and reward of learning new things. Learn something new, that is fun. What has been interesting to you but you haven’t given the time to try yet? Try it out. &lt;/p&gt;

&lt;p&gt;I have a link to a free Pluralsight course and the best books, blogs, and podcasts to learn software development at the end of this post to get you started.&lt;/p&gt;



&lt;h2&gt;
  
  
  Build a Fun Side Project
&lt;/h2&gt;

&lt;p&gt;We also became developers because we enjoy building projects. Have a fun idea you haven’t gotten to start yet? Build it. The reason is that with learning something new and building something fun, you are beginning to associate coding with fun things that you enjoy as opposed to rushing through daily workplace stress.&lt;/p&gt;



&lt;h2&gt;
  
  
  Exercise, Sleep and Eat Well
&lt;/h2&gt;

&lt;p&gt;I wrote about this in my post on Seven Habits of Highly Effective Software Developers. &lt;/p&gt;

&lt;p&gt;If you take care of your health by exercising, sleeping, and eating well, you will be healthier, feel better, and your coding career will improve. Taking care of yourself is a great way to prevent and cure IS and Burnout. &lt;/p&gt;

&lt;p&gt;Nothing alone will prevent and cure these terrible ailments, but it will help and you may be surprised how much it helps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meditate
&lt;/h2&gt;

&lt;p&gt;Have you ever noticed that a lot of successful people and top executives meditate?&lt;/p&gt;

&lt;p&gt;Ray Dalio talks about the importance of transcendental meditation in his life in his book &lt;a href="https://amzn.to/2MrImqJ"&gt; Principles: Life and Work&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In &lt;a href="https://amzn.to/3hMrre0"&gt;5am Club&lt;/a&gt;, the main characters spend 20 minutes every morning mediating. &lt;/p&gt;

&lt;p&gt;These are two books that have been influential to me and coutless others and I highly recommend them.&lt;/p&gt;

&lt;p&gt;Even &lt;strong&gt;Jerry Seinfeld&lt;/strong&gt; recently said that transcendental meditation and weight lifting can &lt;a href="https://www.nbcboston.com/news/business/money-report/jerry-seinfeld-transcendental-meditation-and-weight-training-will-solve-just-about-anyones-life/2269819/"&gt;"solve just about anyone's life"&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;That might be exaggerating some, since it hasn't even solved the fact that he isn't funny, but regardless, meditation is great for clearing the mind and helping you to focus on what is important.&lt;/p&gt;



&lt;h2&gt;
  
  
  Have a Hobby
&lt;/h2&gt;

&lt;p&gt;This is another point that I write about in &lt;a href="https://codewithwolf.com/seven-habits-effective-developers"&gt;Sevent Habits of Highly Effective Software Developers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Having a hobby and spending time doing that outside of the computer is a great way to separate work time, coding time, and other priorities.&lt;/p&gt;

&lt;p&gt;My girlfriend and I made nightstands this weekend. We take our two dogs out for a hike or fetch at the park every day. I like to read, camp, hike, and do just about anything outside with my dogs and girlfriend.&lt;/p&gt;

&lt;p&gt;This separates my time in front of the computer, thinking about code, and I can associate a powerful deep work experience when it is time to code because I am able to separate that focus and association when it is not time to serve up code. &lt;/p&gt;

&lt;p&gt;You may think that being in front of your computer coding all the time will make you a better and more productive developer, maybe. But more likely than not, you are just burning yourself out and frustrating yourself with all that you have to learn. This puts you at risk for both IS &lt;em&gt;AND&lt;/em&gt; Burnout.&lt;/p&gt;

&lt;p&gt;So know how much time you can realistically and honestly spend in front of your computer being productive, and spend the other amount of time away doing something unrelated that you enjoy with people you care about.&lt;/p&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;If there is one point I would like to drive home in this post, it is that Burnout and &lt;/p&gt;

&lt;h2&gt;
  
  
  Imposter Syndrome are normal parts of being a software engineer.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Anyone and everyone can get it.
&lt;/h3&gt;

&lt;p&gt;The top performers that you look up to are not immune, in fact they are at some of the highest risks. &lt;/p&gt;

&lt;p&gt;I give some tips and tricks in this post that have helped me to cure Burnout and Imposter Syndrome in the past and I continue to use to prevent it from occuring in the future. &lt;/p&gt;



</description>
    </item>
    <item>
      <title>How to Build a  REST API with Node and Express
</title>
      <dc:creator>Michael Wolf Hoffman</dc:creator>
      <pubDate>Sun, 03 Jan 2021 14:59:57 +0000</pubDate>
      <link>https://dev.to/mwolfhoffman/how-to-build-a-rest-api-with-node-and-express-nd2</link>
      <guid>https://dev.to/mwolfhoffman/how-to-build-a-rest-api-with-node-and-express-nd2</guid>
      <description>&lt;h2&gt;
  
  
  Why Node and Express?
&lt;/h2&gt;

&lt;p&gt;Node.js (AKA node or nodeJS) is a framework that allows you to write JavaScript on the server so that you can build your backend (server-side) code. &lt;/p&gt;

&lt;p&gt;Before node.js, one team typically wrote the front end code using javascript, and another team would write the backend code in PHP, Java, C#, etc. &lt;/p&gt;

&lt;p&gt;Node.js allows frontend developers to work on the backend of the stack and an entire team to communicate in one programming languange. &lt;/p&gt;

&lt;p&gt;JavaScript is a powerful language and node.js allows that language to expand to the full-stack. &lt;/p&gt;

&lt;p&gt;Express is a popular framework written on top of node.js to make writing server-side javascript easier. &lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisites
&lt;/h2&gt;

&lt;p&gt;It would be good to have at least some knowledge in the follow areas before beginning this tutorial:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. A basic understanding of JavaScript (variables, functions, array methods)
2. Know what a REST API is and what it is used for.
3. Be familiar with HTTP request methods (GET, POST, PUT, DELETE)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will also need these system requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Node.js installed. You can install it &lt;a href="https://nodejs.org/en/"&gt; here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NPM installed. (Should be installed with node above, or &lt;a href="https://www.npmjs.com/"&gt; here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;An editor that you like working in. I use VS Code.&lt;/li&gt;
&lt;li&gt;A terminal you enjoy using such as cmd, powershell, or &lt;a href="https://cmder.net/"&gt;cmder&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Postman installed. Install it &lt;a href="https://www.postman.com/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;



&lt;h2&gt;
  
  
  What we will build
&lt;/h2&gt;

&lt;p&gt;We will build a very basic REST API for a todo-list app. This tutorial will have server side routing and the functionality to Create, Read, Update, and Delete items using nodeJS and express. &lt;/p&gt;



&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;&lt;b&gt;&lt;br&gt;
Before we get started, no tutorial will not be able to explain everything about building a node API. This is only the basics for beginners. &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;If you come across something you are unsure of, it is important to search around on google, stack overflow, forums, etc. A good software developer gets stuck, it is not a sign of weakness or ignorance. The difference between a good developer and a bad developer, is that when the good developer gets stuck, he or she can get themself unstuck by being resourceful and searching for the solution.&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Take your time with this tutorial and try to understand each piece before moving onto the next.
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This will help you a lot to understand node.js, APIs, and code in general&lt;/em&gt;&lt;/p&gt;



&lt;h1&gt;
  
  
  Start the project
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;On a command line, navigate to the directory that you'd like to store your project in and create a new directory.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir todo-api-node-js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Navigate into your new directory
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd mkdir todo-api-node-js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Use this command to create a new node.js project.
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;p&gt;This initializes a new node.js project. It will ask you many options in your console, but you can tap ENTER for all of these for now. &lt;/p&gt;



&lt;h1&gt;
  
  
  The Project Scaffold
&lt;/h1&gt;

&lt;p&gt;So far, the project is very bare bones. You will only see a &lt;code&gt;package.json&lt;/code&gt; file. If you taped ENTER and didn't change any options in the initialization process, you will see this in your package.json:&lt;br&gt;
&lt;/p&gt;

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

{
  "name": "todo-api-node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"
  },
  "author": "",
  "license": "ISC"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an important file that will determine how your project runs. &lt;/p&gt;

&lt;p&gt;It will have a name, description, scripts, and a few other areas. We will explain these more as we go along. &lt;/p&gt;

&lt;h1&gt;
  
  
  Installing NPM Packages
&lt;/h1&gt;

&lt;p&gt;Any node API or project is made up of multiple npm packages. &lt;/p&gt;

&lt;p&gt;NPM is 'Node Package Manager'. These are libraries that can be open source or third party that get installed into your project so that you can use their functionality. &lt;/p&gt;

&lt;p&gt;They are usually very simple to install, we will install a few here and explain what they do as we add them into our main file later. &lt;/p&gt;

&lt;p&gt;First, lets install all of the packages that we will need for this project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save express body-parser nodemon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The installation may take a few moments depending on your network connection's quality. &lt;/p&gt;

&lt;p&gt;After the installation is complete and successful, your &lt;code&gt;package.json&lt;/code&gt; file will have a new property called &lt;code&gt;dependencies&lt;/code&gt; with the packages we just installed and a version number for each one.&lt;br&gt;
&lt;/p&gt;

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

{
  "name": "todo-api-node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "nodemon": "^2.0.6"
  }
}

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

&lt;/div&gt;





&lt;h1&gt;
  
  
  node_modules Folder
&lt;/h1&gt;

&lt;p&gt;You will also see that your file structure changed to include a new folder called &lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is where these &lt;code&gt;npm modules&lt;/code&gt;, &lt;code&gt;dependencies&lt;/code&gt;, &lt;code&gt;npm packages&lt;/code&gt;, or whatever you want to call them will be kept.  (These names are all interchangable). There are likely hundreds of folders with several files each, just from those 3 dependencies that we installed. &lt;/p&gt;

&lt;p&gt;We will soon get to how to use these dependencies. &lt;/p&gt;



&lt;h1&gt;
  
  
  .gitignore
&lt;/h1&gt;

&lt;p&gt;Before I forget, let's add a &lt;code&gt;.gitignore&lt;/code&gt; file. The reason we want this is if we add our project to source control using git, then we want to make sure we don't add this massive &lt;code&gt;node_modules&lt;/code&gt; folder into source control. The file is huge and would slow source control down.&lt;/p&gt;

&lt;p&gt;Add a file at the root level called &lt;code&gt;.gitignore&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Your file structure should now look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File Structure

- node_modules
- package.lock.json
- package.json
- .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets open up the &lt;code&gt;.gitignore&lt;/code&gt; file and simply add the text &lt;code&gt;node_modules&lt;/code&gt; in there.&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;Now, when we start using source control, all of these folders/files inside the &lt;code&gt;node_modules&lt;/code&gt; directory will not be submitted into source control.&lt;/p&gt;



&lt;h1&gt;
  
  
  The Start Script
&lt;/h1&gt;

&lt;p&gt;We now need to create a start script in our &lt;code&gt;package.json&lt;/code&gt; file so that our app knows how to run. Let's open up our &lt;code&gt;package.json&lt;/code&gt; file and add the start script. &lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;scripts&lt;/code&gt; property, we can remove the &lt;code&gt;test&lt;/code&gt; script that is added by default, and we should now add: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;"start": nodemon index.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;our &lt;code&gt;package.json&lt;/code&gt; now looks like this:&lt;br&gt;
&lt;/p&gt;

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

{
  "name": "todo-api-node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "nodemon": "^2.0.6"
  }
}

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

&lt;/div&gt;



&lt;p&gt;What we did was tell node.js to run the index.js file to start our project. &lt;br&gt;
One way to do this is to have the script read:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;If we did that, then every time we make a change in our project, we would have to re-start our server to pick up the new change. &lt;/p&gt;

&lt;p&gt;Depending on the project, this can take a lot of time and if you ever don't remember to re-start your server after each change, you could be debugging forever before realizing why your changes aren't being seen in the project because you forgot to re-start the server.&lt;/p&gt;

&lt;p&gt;With the npm package &lt;code&gt;nodemon&lt;/code&gt;, node.js will see your change and re-start the server for you so you don't have to. You can read more about it &lt;a href="https://www.npmjs.com/package/nodemon"&gt;here&lt;/a&gt;.&lt;/p&gt;



&lt;h1&gt;
  
  
  Starting our project
&lt;/h1&gt;

&lt;p&gt;In your command line, you can now run&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;and our project will run!&lt;/p&gt;

&lt;p&gt;All you should see now is an error saying module not found. &lt;/p&gt;

&lt;p&gt;That makes sense because we are telling node to serve the &lt;code&gt;index.js&lt;/code&gt; file... but we haven't created one yet. Let's do that now...&lt;/p&gt;



&lt;p&gt;# The Main Project File: &lt;code&gt;index.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We have a lot of our basic scaffold set up to create a very simple REST API with node and express. &lt;/p&gt;

&lt;p&gt;It's time to create an &lt;code&gt;index.js&lt;/code&gt; file in our root and spend a lot of time there in the next few steps. &lt;/p&gt;

&lt;p&gt;This is where we will begin to introduce our other two node modues: &lt;code&gt;express&lt;/code&gt; and &lt;code&gt;body-parser&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For now, let's try adding some very simple code in our root directory's &lt;code&gt;index.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

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

console.log("Hello World!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we run &lt;code&gt;npm run start&lt;/code&gt; now, we should see "Hello World!" printed to the console!&lt;/p&gt;

&lt;p&gt;There will also be some messages about nodemon listening for changes in your console. &lt;/p&gt;

&lt;p&gt;Because we are using nodemon, we can change the message in &lt;code&gt;index.js&lt;/code&gt;, and when we save the file, nodemon will re-start our server for us and show the new message.&lt;br&gt;
&lt;/p&gt;

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

console.log("Hello World Again!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we save our &lt;code&gt;index.js&lt;/code&gt;, we should now see the message "Hello World Again!" in our console.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Without nodemon, we would have to stop the server with CTRL + C and then restart it with &lt;code&gt;npm run start&lt;/code&gt; for these changes to appear. That is why I like to skip a step and just use the &lt;code&gt;nodemon&lt;/code&gt; to begin with).&lt;/em&gt;&lt;/p&gt;



&lt;h1&gt;
  
  
  Creating a Server with &lt;code&gt;express&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;express&lt;/code&gt; is a node module that allows us to write javascript to easily create server-side code. &lt;/p&gt;

&lt;p&gt;Let's stay in our &lt;code&gt;index.js&lt;/code&gt; and start a server with &lt;code&gt;express&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;We will remove our &lt;code&gt;console.log&lt;/code&gt;  and start at the beginning of the file by simply importing &lt;code&gt;express&lt;/code&gt; into the file.&lt;br&gt;
&lt;/p&gt;

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

const express = require('express')
const app = express()
const port = 5001

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

&lt;/div&gt;



&lt;p&gt;The variable &lt;code&gt;app&lt;/code&gt; is now our express server. &lt;/p&gt;

&lt;p&gt;We also created a variable &lt;code&gt;port&lt;/code&gt; which is where our app will run on localhost.&lt;/p&gt;

&lt;p&gt;Next, we add a listener event and log a message when our server is running. &lt;/p&gt;

&lt;p&gt;Our message will tell us what port our server is running on.&lt;br&gt;
&lt;/p&gt;

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

const express = require('express')
const app = express()



app.listen(port, () =&amp;gt; {
    console.log(`Node Todo API is running on port: ${port}`)
})

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

&lt;/div&gt;



&lt;p&gt;If our node server is still running, we should see the message:&lt;/p&gt;

&lt;p&gt;"Node Todo API is running on port: 5001" in our console. &lt;/p&gt;

&lt;p&gt;If your server is not running, run it again with: &lt;code&gt;npm run start&lt;/code&gt;.&lt;/p&gt;



&lt;h1&gt;
  
  
  Next NPM Package: Body-Parser
&lt;/h1&gt;

&lt;p&gt;We have used the &lt;code&gt;express&lt;/code&gt; and &lt;code&gt;nodemon&lt;/code&gt; npm packages so far. &lt;/p&gt;

&lt;p&gt;We have one more npm package we haven't used yet. &lt;/p&gt;

&lt;p&gt;An API needs to be able to take data from the requests made to it. This can come in the form of route parameters (just like in the user interface, something like &lt;code&gt;id&lt;/code&gt; in the route &lt;code&gt;website.com/user/123&lt;/code&gt;), but also an API needs the ability to take data from a request's body.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;body-parser&lt;/code&gt; will allow a node API to parse the request's body into a JSON object so our node API can use that data. &lt;/p&gt;

&lt;p&gt;It is very simple to set up in our &lt;code&gt;index.js&lt;/code&gt;. While there is a lot more to learn about requests and data, everything you need to know to get a basic understanding of a request sending data in a node.js API will be explained here very soon. &lt;/p&gt;



&lt;p&gt;We need to import body-parser into our &lt;code&gt;index.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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


const express = require('express')
const app = express()
const port = 5001
const bodyParser = require('body-parser');

...

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

&lt;/div&gt;



&lt;p&gt;Then we need to set it up to use json. &lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;index.js&lt;/code&gt; should look like this:&lt;br&gt;
&lt;/p&gt;

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

const express = require('express')
const app = express()
const port = 5001
const bodyParser = require('body-parser');



app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.listen(port, () =&amp;gt; {
    console.log(`Node Todo API is running on port: ${port}`)
})


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

&lt;/div&gt;





&lt;h1&gt;
  
  
  Where are we?
&lt;/h1&gt;

&lt;p&gt;What do we have now? &lt;/p&gt;

&lt;p&gt;Right now we have used our three node package: &lt;code&gt;nodemon&lt;/code&gt;, &lt;code&gt;express&lt;/code&gt;, and &lt;code&gt;body-parser&lt;/code&gt;, to get to a point where we can start to add real API functionality. &lt;/p&gt;

&lt;p&gt;A basic API should at the very least be able to perform CRUD operations (Create, Read, Update, and Delete).&lt;/p&gt;



&lt;p&gt;We have an API that is running successfully and will be able to take data from incoming requests and process it how we need to in order to do our CRUD processes. &lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;What's next?&lt;/p&gt;

&lt;p&gt;Let's create our routes!&lt;/p&gt;


&lt;h1&gt;
  
  
  Routing
&lt;/h1&gt;

&lt;p&gt;We are at a point where our API can start Creating, Reading, Update, and Deleting todos from a list. &lt;/p&gt;

&lt;p&gt;Routing is a very important concept with node.js APIs.&lt;/p&gt;

&lt;p&gt;Node.js works by listening to events on certain routes and then firing off actions when it "hears" an event on that route that it was listneing for.&lt;/p&gt;

&lt;p&gt;Our routes are the system where we tell the node API what events to listen to, and when that event occurs we can run a handler which is a function that allows our API to process the data in the way we want it to. &lt;/p&gt;

&lt;p&gt;A route can also be called an endpoint.&lt;/p&gt;

&lt;p&gt;This will make more sense with our first route/endpoint...&lt;/p&gt;


&lt;h1&gt;
  
  
  Our First Route
&lt;/h1&gt;

&lt;p&gt;Let's add our first route. It will be very simple. &lt;/p&gt;

&lt;p&gt;in the bottom of our &lt;code&gt;index.js&lt;/code&gt; file we will add this code.&lt;br&gt;
&lt;/p&gt;

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

...

app.get('/', function(req,res){
    return res.send("Hello World!")
});


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

&lt;/div&gt;



&lt;p&gt;In our first route above, our &lt;code&gt;app&lt;/code&gt; (server) is listening for an HTTP GET request to the route &lt;code&gt;'/'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That means if we make a GET request to &lt;code&gt;localhost:5001/&lt;/code&gt;, then the function (handler) in the second parameter above should run. &lt;/p&gt;

&lt;p&gt;Pretty simple, eh? If that makes sense, then you understand how node.js works.&lt;/p&gt;



&lt;p&gt;Acording to the code snippet above, if we make a GET request to the route '/', we should get a resonse that says: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Hello World!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We can make GET requests very easily. With your server running, navigate to 'localhost:5001' in your browser. &lt;/p&gt;

&lt;p&gt;The words "Hello World!" should appear on your screen.&lt;/p&gt;



&lt;h1&gt;
  
  
  Get Todos
&lt;/h1&gt;

&lt;p&gt;Next, let's create some sample todos to use as data in our index.js.&lt;br&gt;
&lt;/p&gt;

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

const express = require('express')
const app = express()
const port = 5001
const bodyParser = require('body-parser');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.listen(port, () =&amp;gt; {
    console.log(`Node Todo API is running on port: ${port}`)
})

const todos = [
    { id: 1, text: "Brush teeth", completed: false },
    { id: 2, text: "Pet dog", completed: false },
    { id: 3, text: "Make Coffee", completed: false },
    { id: 4, text: "Write code", completed: false }

]


app.get('/', function (req, res) {
    return res.send("Hello World")
});


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

&lt;/div&gt;



&lt;p&gt;And at the end of the &lt;code&gt;index.js&lt;/code&gt; file we can add an event to listen to GET requests on the '/todos' route.&lt;br&gt;
&lt;/p&gt;

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

...


app.get('/todos', function (req, res) {
    return res.send(todos)
});

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

&lt;/div&gt;



&lt;p&gt;Now, when we go to the URL "localhost:5001/todos" in our browser to make the GET request, we should see an array of the todos from our &lt;code&gt;index.js&lt;/code&gt; on our screen. &lt;/p&gt;



&lt;h1&gt;
  
  
  Get A Todo by ID
&lt;/h1&gt;

&lt;p&gt;Let's add one more GET request. This request will return a single Todo object depending on what ID we send it in the request parameter.&lt;br&gt;
&lt;/p&gt;

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

...

app.get('/todos/:id', function (req, res) {
    const id = req.params.id;
    let result = null
    for (let i = 0; i &amp;lt; todos.length; i++) {
        const todo = todos[i];
        if (todo.id == id) { // using == instead of === because id is a string.
            result = todo;
        }
    }
    return res.send(result);
});

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

&lt;/div&gt;



&lt;p&gt;If we navigate to 'localhost:5001/todos/1', we should see our first todo in our browser. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;id&lt;/code&gt; variable in our code shows us how node.js can read from the request parameters and get the &lt;code&gt;id&lt;/code&gt; property to use in our API.&lt;/p&gt;



&lt;h1&gt;
  
  
  Add a Todo with a POST request.
&lt;/h1&gt;

&lt;p&gt;We have 2 routes that listen to GET requests and return either a list of all todos or a single todo by id. &lt;/p&gt;

&lt;p&gt;Now, let's add our first POST request and add a todo to our list. &lt;/p&gt;

&lt;p&gt;In &lt;code&gt;index.js&lt;/code&gt; let's add the following route:&lt;br&gt;
&lt;/p&gt;

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

...


app.post('/todos/', function (req, res) {
    const newId = todos.length + 1;
    const newTodo = {
        id: newId,
        todo: req.body.todo,
        completed: false
    }
    todos.push(newTodo)

    return res.send(todos);
});


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

&lt;/div&gt;



&lt;p&gt;When we write a API, we want each item to have a unique ID. There is an npm package called &lt;code&gt;uuid&lt;/code&gt; that works great for this, but for this simple project, I am just going to keep track of each todo by what order it is in, that is what the &lt;code&gt;newId&lt;/code&gt; variable is doing. Also, each todo will start with a &lt;code&gt;completed&lt;/code&gt; property that is set to &lt;code&gt;false&lt;/code&gt; by default. &lt;/p&gt;

&lt;p&gt;You will also see above, that the &lt;code&gt;todo&lt;/code&gt; property is being set to the &lt;code&gt;req.body.todo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's talk more about what the request body, or &lt;code&gt;req.body&lt;/code&gt; is.&lt;/p&gt;



&lt;h1&gt;
  
  
  &lt;code&gt;req&lt;/code&gt;, &lt;code&gt;res&lt;/code&gt;, &lt;code&gt;req.body&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Each node endpoint or route takes the route as the first variable ('&lt;code&gt;/todos&lt;/code&gt;' in our examples). The second parameter in each endpoint is a callback function which takes the parameters &lt;code&gt;req&lt;/code&gt; and &lt;code&gt;res&lt;/code&gt; (it can also take other parameters but that is out of scope for this tutorial). &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;req&lt;/code&gt; is the request object. The &lt;code&gt;res&lt;/code&gt; is the response object. &lt;/p&gt;

&lt;p&gt;Because these are parameters, they can be called anything you want, but &lt;code&gt;req&lt;/code&gt; and &lt;code&gt;res&lt;/code&gt; are the industry standard. It is the order, not the name, that matters.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;res&lt;/code&gt; is pretty simple. It is the response and many times you will use it to send the response back to the client (the consumer of this API.)&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;req&lt;/code&gt; is more complicated and gets sent with potentially a lot of important and useful data that tells node information such as if a user is logged in or not. &lt;/p&gt;

&lt;p&gt;In our example above, the &lt;code&gt;req&lt;/code&gt; object can have a body property on it that sends POST requests useful information. &lt;/p&gt;

&lt;p&gt;Our POST endpoint above shows that there is a body with a property of "todo" that is getting used to create the &lt;code&gt;todo&lt;/code&gt; property on the variable &lt;code&gt;newTodo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;When reading through a node API, you can learn a lot about what kind of properties to add to &lt;code&gt;req.body&lt;/code&gt; so that you use the API correctly (although a good public facing API will have this documented.)&lt;/em&gt;&lt;/p&gt;



&lt;h1&gt;
  
  
  How to Test a POST Endpoint
&lt;/h1&gt;

&lt;p&gt;To test a POST endpoint, developers use a tool called Postman. You can download it &lt;a href="https://www.postman.com/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once it is downloaded, your request should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UhHo1cyK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://codewithwolf.com%255Cassets%255Cimg%255Cpostman-post-req-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UhHo1cyK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://codewithwolf.com%255Cassets%255Cimg%255Cpostman-post-req-example.png" alt="postman-req-example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After clicking the SEND button, you will get your response back. As you scroll through your response, you should see that the new todo has successfully gotten added to the last index of the list of all todos. &lt;/p&gt;

&lt;p&gt;Postman can also be used to test GET, PUT, DELETE, PATCH, and other HTTP methods. &lt;/p&gt;

&lt;p&gt;We were using our browser to test for GET requests earlier (a browser is basically just a fancy GET request making app). I will typically used Postman instead of my browser when testing GET requests. &lt;/p&gt;

&lt;p&gt;Also, there are alternatives to Postman so feel free to search around and find something you like. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6baikU3j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://codewithwolf.com%255Cassets%255Cimg%255Cpostman-post-res-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6baikU3j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://codewithwolf.com%255Cassets%255Cimg%255Cpostman-post-res-example.png" alt="postman-res-example"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h1&gt;
  
  
  Edit a Todo with a PUT request
&lt;/h1&gt;

&lt;p&gt;As we progress in our ability to perform all CRUD processes, we have now arrived at the U part of CRUD, Update. &lt;/p&gt;

&lt;p&gt;Adding the listener for a PUT request to our growing list of endpoints in our &lt;code&gt;index.js&lt;/code&gt; will give us that updating ability. &lt;/p&gt;

&lt;p&gt;Add this code to your &lt;code&gt;index.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

..

app.put('/todos/', function (req, res) {

    //  Find the todo to update by ID

    let todoToUpdate = todos.find((todo) =&amp;gt; {
        return todo.id == req.body.id
    })

    todoToUpdate = {
        id: req.body.id,
        todo: req.body.todo,
        completed: req.body.completed
    };


    //  Find the index of that todo to update.

    let index = todos.findIndex((todo) =&amp;gt; {
        return todo.id == req.body.id
    });


    // Update the todo in the list

    todos[index] = todoToUpdate;


    //  Return the response

    return res.send(todos);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above has a lot going on, so take some time if you need to in order to understand it. &lt;/p&gt;

&lt;p&gt;We use an array method &lt;code&gt;.find()&lt;/code&gt; to get the todo item we want to update from our array. &lt;/p&gt;

&lt;p&gt;Then we update the item in our function. &lt;/p&gt;

&lt;p&gt;After that we use &lt;code&gt;.findIndex()&lt;/code&gt; to get the index of the list in the &lt;code&gt;todos&lt;/code&gt; variable that we want to update.&lt;/p&gt;

&lt;p&gt;Last we update the item in the actual array and return the response. &lt;/p&gt;

&lt;p&gt;We are listening for a PUT request on the '/todos' route. Do you see what properties your request body needs for this endpoint? &lt;/p&gt;

&lt;p&gt;It looks like we will need to send a request body with properties &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;todo&lt;/code&gt;, and &lt;code&gt;completed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To test this in postman, lets use this as our request body.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "id": 1,
    "todo": "Brush teeth",
    "completed":true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The request body above will take the first todo in our list, and set &lt;code&gt;completed&lt;/code&gt; from &lt;code&gt;false&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After we test this out in Postman, we should see in our result that the first item in the array has &lt;code&gt;completed&lt;/code&gt; set to &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;



&lt;h1&gt;
  
  
  Delete a Todo
&lt;/h1&gt;

&lt;p&gt;The last requirement in a CRUD application is the ability to delete an item. &lt;/p&gt;

&lt;p&gt;Add this code to your &lt;code&gt;index.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

...

app.delete('/todos/:id', function (req, res) {

    //  Find the index of that todo to update.
    let index = todos.findIndex((todo) =&amp;gt; {
        return todo.id == req.params.id
    });

    todos.splice(index, 1);

    //  Return the response
    return res.send(todos);
});

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

&lt;/div&gt;



&lt;p&gt;This is similar to our PUT request above. We use the array method &lt;code&gt;.findIndex()&lt;/code&gt; to find the index of the item we want to delete, then we use &lt;code&gt;.splice()&lt;/code&gt; to remove that one item. &lt;/p&gt;

&lt;p&gt;You will also see that instead of sending any information in our &lt;code&gt;req.body&lt;/code&gt;, this time we are only using the &lt;code&gt;req.params&lt;/code&gt; and sending the item's id as a property on that object, similar to our endpoint where we get one todo from the list earlier.&lt;/p&gt;

&lt;p&gt;Can you test this out in Postman? &lt;/p&gt;

&lt;p&gt;If you make a DELETE request to 'localhost:5001/todos/1', you should get back an array of the original todos but without the first item. &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;We now have a working API built with node.js and express! &lt;/p&gt;

&lt;p&gt;Congratulations, that's an achievement. &lt;/p&gt;

&lt;p&gt;However, the honest truth is that this only scratches the surface of what these powerful tools can do. We do not yet have data persistence (using a database), any authentication, error handling, etc. &lt;/p&gt;

&lt;p&gt;There are many more things that any REST API will typically need in a production environment to be ready for users&lt;/p&gt;

&lt;p&gt;I will create more tutorials on these topics in the future, but what we have covered here is enough to get us started and learning more to create some powerful REST APIs with node.js and express.&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>express</category>
    </item>
  </channel>
</rss>
