<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Garret</title>
    <description>The latest articles on Forem by Garret (@garretharp).</description>
    <link>https://forem.com/garretharp</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%2F392442%2Fb5654713-1d71-4972-bc2d-1444c8caf614.png</url>
      <title>Forem: Garret</title>
      <link>https://forem.com/garretharp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/garretharp"/>
    <language>en</language>
    <item>
      <title>Database Choices. NoSQL vs SQL</title>
      <dc:creator>Garret</dc:creator>
      <pubDate>Sun, 23 Aug 2020 07:42:04 +0000</pubDate>
      <link>https://forem.com/garretharp/database-choices-nosql-vs-sql-f5o</link>
      <guid>https://forem.com/garretharp/database-choices-nosql-vs-sql-f5o</guid>
      <description>&lt;p&gt;I have seen a few posts about people saying their favorite database and I am curious now why you might choose a NoSQL database over an SQL database or vice versa.&lt;/p&gt;

&lt;p&gt;Personally, for basically every project, I choose to use DyanmoDB. There are a few reasons why but they all in a way boil down to cost and performance.&lt;/p&gt;

&lt;p&gt;As far as the cost side DynamoDB offers an extremely generous free tier and I have never on my side projects reached passed the free tier capacity which is really nice. One of the said side projects I had 10,000 users and even with doing roughly 150 reads a second it was free.&lt;/p&gt;

&lt;p&gt;Another aspect I love about Dynamo is how good it works with serverless because you never make a constant connecting with the database, every change is done through HTTP requests. Dynamo is also extremely performant no matter how high you scale it. Currently working with a client that wanted to switch off of Postgres to Dynamo and performance has been an insane improvement for them.&lt;/p&gt;

&lt;p&gt;I feel one of the main reasons I do not choose an SQL database is because I do not really have any analytical reads or have access patterns that I do not know about. I think SQL performs best when you need those analytical type queries but it seems a lot of people prefer SQL databases over NoSQL and was curious to see the reasoning.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>database</category>
      <category>healthydebate</category>
    </item>
    <item>
      <title>Best password authentication strategy?</title>
      <dc:creator>Garret</dc:creator>
      <pubDate>Mon, 20 Jul 2020 19:16:58 +0000</pubDate>
      <link>https://forem.com/garretharp/best-password-authentication-strategy-219p</link>
      <guid>https://forem.com/garretharp/best-password-authentication-strategy-219p</guid>
      <description>&lt;p&gt;I was curious based on your personal/professional opinion what is the best way to do password authentication?&lt;/p&gt;

&lt;p&gt;I see so many different ways of handling users' passwords from salts hashing etc. and I wanted to know what you guys would do.&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>The App Stores...</title>
      <dc:creator>Garret</dc:creator>
      <pubDate>Tue, 16 Jun 2020 20:29:05 +0000</pubDate>
      <link>https://forem.com/garretharp/the-app-stores-2837</link>
      <guid>https://forem.com/garretharp/the-app-stores-2837</guid>
      <description>&lt;p&gt;App Stores... we need to talk. Google and Apple both have monopolies in the world of app stores for mobile devices. Since they have this monopoly they charge an outrageous fee for in app purchases, 30%! On top of that Apple also has some extremely strange ruling on apps they decide to run down of their app store, unless you cave into paying them.&lt;/p&gt;

&lt;h3&gt;
  
  
  In App Purchases
&lt;/h3&gt;

&lt;p&gt;Apple and Google, for years have been charging a 30% fee for all purchases made on their app stores. A fee which you would never see in credit processing from services such as Stripe, Braintree, or similar processors. Why? Apple and Google are the only two companies which have a monopoly in their markets. Apple even more so with the extremely strict regulations on their store. Not only does Apple take a fee for app purchases, they also charge $100/year. Google also charges $25, however as a one time fee.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apples Regulations
&lt;/h3&gt;

&lt;p&gt;There has been many cases where Apple will try to remove apps off of the app store who do not subject themselves to the Apple tax by only allowing charges through their own website. An example of this can be found in a recent &lt;a href="https://twitter.com/dhh/status/1272968382329942017"&gt;Twitter thread&lt;/a&gt; which prompted me to write this. &lt;a href="https://twitter.com/dhh/status/1272968382329942017"&gt;https://twitter.com/dhh/status/1272968382329942017&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In that thread you will see one of the tweets included an email from Apple saying they will take down the &lt;a href="https://hey.com"&gt;Hey&lt;/a&gt; app if they do not offer in-app purchases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kX7_U_II--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/x14x0p5qg3l3x4yd8y52.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kX7_U_II--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/x14x0p5qg3l3x4yd8y52.jpg" alt="Apple App Rejection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yet there is also many apps that do the same thing, linking off to external webpage to purchase subscriptions that are still allowed on the app store.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Eyv_j8Uz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xyxv5sg1q4rmsmwqj1kf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Eyv_j8Uz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xyxv5sg1q4rmsmwqj1kf.jpg" alt="Allowed Paid Apps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;Apple is most likely targeting the &lt;a href="https://hey.com"&gt;Hey&lt;/a&gt; app, because Apple sells its own email service &lt;a href="https://www.icloud.com/mail"&gt;iCloud mail&lt;/a&gt;. Therefore &lt;a href="https://hey.com"&gt;Hey&lt;/a&gt; would be considered a direct competitor to Apple, and of course Apple wants to keep all the profits for services to themselves.&lt;/p&gt;

&lt;h3&gt;
  
  
  Things Need Change
&lt;/h3&gt;

&lt;p&gt;Things need to change. Apple should not be allowed this monopolistic approach to the app store. If we keep allowing big tech companies like Apple and Google to go down this road, they will own everything about us, and there is almost nothing we can do to stop it unless we act now.&lt;/p&gt;

&lt;p&gt;My question for you is, what do you think we need to do in order to make this change happen? Do you think anything will change anytime soon?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>ios</category>
      <category>android</category>
    </item>
    <item>
      <title>Git and words...</title>
      <dc:creator>Garret</dc:creator>
      <pubDate>Mon, 15 Jun 2020 00:09:44 +0000</pubDate>
      <link>https://forem.com/garretharp/git-and-words-371l</link>
      <guid>https://forem.com/garretharp/git-and-words-371l</guid>
      <description>&lt;p&gt;So, as many of you know there are some articles about "master" in git being "racist." Obviously master in the case of git, and github is not racist if you look at the connotation of the word.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Connotation?
&lt;/h3&gt;

&lt;p&gt;Conotation is the most important thing in language. A single word can have many different definitions that depend on how the word is used in a sentence.&lt;/p&gt;

&lt;p&gt;The dictionary definition: "an idea or feeling that a word invokes in addition to its literal or primary meaning."&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of Connotation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;"The man is very blue"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This statement would literally mean that the man is colored blue. However, if you use the connotation with how it is used, you would know this means "the man is very sad"&lt;/p&gt;

&lt;h3&gt;
  
  
  The Word Master
&lt;/h3&gt;

&lt;p&gt;The word master does have connection to the fact the slavery happened and people were in fact "masters" to slaves. I am not denying that. However, if you look into the connotation of how "master" is used in github, it refers to the "master copy." The word "master" in the case of git has nothing to do with people owning slaves.&lt;/p&gt;

&lt;h3&gt;
  
  
  My thoughts
&lt;/h3&gt;

&lt;p&gt;Going down this road of people getting offended over every single word because it has any ties to slavery is a very bad road to go down.&lt;/p&gt;

&lt;p&gt;If that is the way we go down we would have to stop using literally every word in the dictionary, because at one point our world was not the best. We stemmed all of our words with some sort of relation to how our world was back then. Rather than getting offended we need to understand the actual meaning of the word in the sentence it is used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Going Down This Path
&lt;/h3&gt;

&lt;p&gt;If we go down this path we would have to stop using words such as, main, control, git. Here's why:&lt;/p&gt;

&lt;p&gt;Main comes from the "power" or "military control." If we look at whats happening in the world right now there is use of military control in the riots for police brutatility against people of color. Therefor main is a poor word since it has to do with the militaries control and power of the people.&lt;/p&gt;

&lt;p&gt;Control literally means "the power to influence or direct people's behavior" which is what slave owners did to their slaves. They held power over everything they did. Therefor control is a bad word to use to define how git is a version control system.&lt;/p&gt;

&lt;p&gt;Git literally means "an unpleasant or contemptible person." That is a pretty rude thing to use. Therefor git should not be used, and it should not be a version control system!&lt;/p&gt;

&lt;p&gt;We could go on for days about every single word used for almost anything in the world. It is just not a good idea, and we instead need to understand that words have a connotation!&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>Where do you go to learn more advanced concepts</title>
      <dc:creator>Garret</dc:creator>
      <pubDate>Sun, 14 Jun 2020 06:10:37 +0000</pubDate>
      <link>https://forem.com/garretharp/where-do-you-go-to-learn-more-advanced-concepts-18ph</link>
      <guid>https://forem.com/garretharp/where-do-you-go-to-learn-more-advanced-concepts-18ph</guid>
      <description>&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;I was curious where is your goto place to learn some more advanced concepts or learn something more than just the basic tutorials of like chat rooms or todo lists etc.&lt;/p&gt;

&lt;p&gt;I would say I am currently at the intermediate level of programming, and I know how to do all of those basic apps, and I know some advanced concepts. I want to be able to read or watch how people solve more advanced problems that require some more thought than the basic apps I see all over youtube.&lt;/p&gt;

&lt;p&gt;Any youtube channels or company articles you always look out for? Any more specific websites dedicated to more advanced concepts?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>The Problem With Mixer Clips</title>
      <dc:creator>Garret</dc:creator>
      <pubDate>Sun, 14 Jun 2020 01:31:45 +0000</pubDate>
      <link>https://forem.com/garretharp/the-problem-with-mixer-clips-49fd</link>
      <guid>https://forem.com/garretharp/the-problem-with-mixer-clips-49fd</guid>
      <description>&lt;p&gt;This post is more so of a rant about &lt;a href="https://mixer.com"&gt;Mixer&lt;/a&gt;, and some of the things they do wrong, this post focusing on Mixer Clips. For those of you who do not know what &lt;a href="https://mixer.com"&gt;Mixer&lt;/a&gt; is, it is a streaming platform similar to &lt;a href="https://twitch.tv"&gt;Twitch&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  TLDR
&lt;/h4&gt;

&lt;p&gt;Mixer does not actually create clips. They save references to the VOD of the stream for clips. If you delete a VOD all your clips will be unwatchable that happened in that stream.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Mixer Create Clips
&lt;/h3&gt;

&lt;p&gt;To start I wanted to go over how Mixer creates their clips. In order to even have clips enabled on your channel you have to have VODs enabled (taken from their &lt;a href="https://watchbeam.zendesk.com/hc/en-us/articles/360005089311"&gt;Knowledge Base for Clips&lt;/a&gt;). This in it of itself is not the worst part, however, should not be a requirement to create clips in my opinion.&lt;/p&gt;

&lt;p&gt;Once you have VODs enabled you can now create clips. When you request to create a clip Mixer creates a clip &lt;code&gt;m3u8&lt;/code&gt; file that references back to the timestamps in the VODs. The file looks like so (shortened):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:4
#EXTINF:2,
https://clips-content.mixer.com/vods/bc379e2c-7ab2-4941-8bb4-6a8cfddde647/0002244.ts
#EXTINF:2,
https://clips-content.mixer.com/vods/bc379e2c-7ab2-4941-8bb4-6a8cfddde647/0002245.ts
#EXTINF:2,
https://clips-content.mixer.com/vods/bc379e2c-7ab2-4941-8bb4-6a8cfddde647/0002246.ts
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note how the URLs point back to the &lt;code&gt;vods&lt;/code&gt; folder. Rather than creating a clip, Mixer instead points back to the VOD. This means if you delete a VOD your clips will not be playable. This also means that the clips cannot last longer than the VODs (which they only save for 14 days for non-partners).&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Does Mixer Do This?
&lt;/h3&gt;

&lt;p&gt;This is a question that I still have myself. My only guess as to why Mixer would do this is maybe to save money on storage costs. This would be a pretty dumb reason for the limitations this brings in, however.&lt;/p&gt;

&lt;h4&gt;
  
  
  How Should Mixer Fix This?
&lt;/h4&gt;

&lt;p&gt;This is such a simple fix that would take less than 3 seconds for any developer to make. They already know the exact file parts they need from the VOD. All they would need to do is copy that data over into a &lt;code&gt;clips&lt;/code&gt; folder. This would allow user to delete their VODs and still keep their clips, and it would also allow Mixer to save clips for longer than the minuscule amount of 14 days.&lt;/p&gt;

&lt;p&gt;The question here though is does Mixer care? My guess, probably not. Mixer clips have been in "beta" for 3 years, and they still just point references to the VOD. I have not seen a bigger joke than this. From my experience in development, I would be willing to bet the reason the developers do it like this is because of the higher ups at Mixer who just do not understand, and do not care.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further on Clips
&lt;/h3&gt;

&lt;p&gt;Since clips for Mixer has been my passion as I am working on &lt;a href="https://smartclips.app"&gt;SmartClips&lt;/a&gt;, which is real clips, I wanted to go a little bit further on how Mixer can actually make a better clip system.&lt;/p&gt;

&lt;p&gt;It is my opinion that VODs should not have to even be enabled for users to create clips. While most streamers will have VODs enabled it is still a limitation that shouldn't need to be there.&lt;/p&gt;

&lt;p&gt;The change Mixer would need to make is rather than copying over the video parts from the VODs they would just need to copy over the files from the HLS stream while the user is still live, before those files are deleted. This is exactly what I do on &lt;a href="https://smartclips.app"&gt;SmartClips&lt;/a&gt;, and is not a hard implementation by any means.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;Do you think that the higher ups at Mixer will ever realize the changes they need to do? I hope they will figure it out eventually. I want Mixer to succeed, that's why I started making 3rd party tools for Mixer (which is also a pain to do, but that's a rant for another day).&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Node Express and WebSockets (WS) Boiler Plate</title>
      <dc:creator>Garret</dc:creator>
      <pubDate>Fri, 22 May 2020 15:43:19 +0000</pubDate>
      <link>https://forem.com/garretharp/node-express-and-websockets-ws-boiler-plate-3h4i</link>
      <guid>https://forem.com/garretharp/node-express-and-websockets-ws-boiler-plate-3h4i</guid>
      <description>&lt;p&gt;In this post I will be sharing with you some of the practices I follow, and how I create my API's using Node, Express, and WebSockets. I have recently publicly published the boiler plate that I use at &lt;a href="https://github.com/itsUnsmart/express-ws-boiler"&gt;https://github.com/itsUnsmart/express-ws-boiler&lt;/a&gt; so I decided to go over it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Project Structure
&lt;/h1&gt;

&lt;p&gt;The main thing I think about when setting up my projects is readability. If I cannot read through the project structure easily to find what I need it can be a pain.&lt;/p&gt;

&lt;p&gt;In order to make things easy I split everything into its own directory. The Express API goes into the &lt;code&gt;web&lt;/code&gt; directory. The WebSocket goes into the &lt;code&gt;sockets&lt;/code&gt; directory. Finally any helpers I made need go into the &lt;code&gt;helpers&lt;/code&gt; directory. In this example I have only one &lt;code&gt;index.js&lt;/code&gt; file in the helpers, however, in bigger projects I recommend making multiple files with a more specific name to the type of helper functions if needed.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/helpers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Any helpers needed.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/sockets&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Anything related to the websocket server.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/web&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Anything related to the express web server.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Express Specifics
&lt;/h3&gt;

&lt;p&gt;Specific to Express I have one main &lt;code&gt;index.js&lt;/code&gt; file which starts the server, and sets up all the routing, as well as any other configuration needed. In order to make the routes in a clean structure I create a &lt;code&gt;routes&lt;/code&gt; folder which contains an &lt;code&gt;index.js&lt;/code&gt; that will parse out the routes into a single object for the main server file.&lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;example&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example it takes a route file called &lt;code&gt;example.js&lt;/code&gt; and maps it to the "/example" path. The way the mapping works in the main &lt;code&gt;index.js&lt;/code&gt; file is it require the route index file, and runs over the object keys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means now any request which has &lt;code&gt;example&lt;/code&gt; in the path will get routed to the code in the &lt;code&gt;example.js&lt;/code&gt; file.&lt;br&gt;
Meaning our simple hello world file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Will run when we go to &lt;code&gt;http://localhost:3000/example&lt;/code&gt; and display:&lt;br&gt;
&lt;code&gt;{"hello": "world"}&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  WebSocket Specifics
&lt;/h3&gt;

&lt;p&gt;Specific to WS I have one main &lt;code&gt;index.js&lt;/code&gt; file which starts the server, and sets up all the methods, as well as any other configuration needed. In order to make the methods in a clean structure I create a &lt;code&gt;methods&lt;/code&gt; folder which contains an &lt;code&gt;index.js&lt;/code&gt; that will parse out the methods into a single object for the main server file. This file is identical to the Express equivalent in the routes folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;example&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is now in order to call the method I look for the method to call in the WebSocket message inside of the &lt;code&gt;method&lt;/code&gt; parameter (Note that I code all WebSocket message to be JSON).&lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Methods&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./methods&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// inside ws.on("message")&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Methods&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Methods&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;WSS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if we were to connect to the socket and send the following message:&lt;br&gt;
&lt;code&gt;{"method": "example"}&lt;/code&gt; it would run our &lt;code&gt;example&lt;/code&gt; method and return a response containing &lt;code&gt;{"hello": "world"}&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Full structure
&lt;/h2&gt;

&lt;p&gt;After this out full project structure would look like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;helpers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The main file combining all other helper files if any.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sockets&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The main server and configuration file.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;methods&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The main methods file which combines all methods.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;web&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Same as sockets replacing methods with routes.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Errors
&lt;/h2&gt;

&lt;p&gt;After working on projects that integrate with 3rd party services I truly understand how useful good error messages can be. I always make sure to give as much detail into why an error happened so anyone using it can understand what went wrong.&lt;/p&gt;

&lt;p&gt;I do this by giving my errors an easy to read error message, a machine readable error code useful for doing switch statements on. As well as context into the error(s) that occured.&lt;/p&gt;

&lt;p&gt;Example of a 404 error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Not Found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;not_found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;context_info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid_path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The requested path could not be found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/invalid/path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This error may be a bit overkill for a simple 404 error, however, it gives a user or even yourself a good insight into exactly what went wrong in the request. This is very useful, and makes debugging super easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Easy Install
&lt;/h2&gt;

&lt;p&gt;Would you like to use this boiler plate in your projects? The easiest way to install it into your projects is by using &lt;a href="https://www.npmjs.com/package/degit"&gt;&lt;code&gt;degit&lt;/code&gt;&lt;/a&gt;. &lt;br&gt;
Run the command &lt;code&gt;degit itsUnsmart/express-ws-boiler&lt;/code&gt;, and it will clone the repository into your current directory.&lt;/p&gt;

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

&lt;p&gt;That is the basics for how I structure my Node, Express, and WebSocket applications, and how I handle things such as errors. I am curious how do you structure your projects, and what do you like or dislike about how I structure mine?&lt;/p&gt;

</description>
      <category>node</category>
      <category>websockets</category>
      <category>express</category>
      <category>boilerplate</category>
    </item>
  </channel>
</rss>
