<?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: allen-woods</title>
    <description>The latest articles on DEV Community by allen-woods (@allenwoods).</description>
    <link>https://dev.to/allenwoods</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%2F139063%2F68a86f88-67c7-40ae-a68b-55558f44ed10.jpeg</url>
      <title>DEV Community: allen-woods</title>
      <link>https://dev.to/allenwoods</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/allenwoods"/>
    <language>en</language>
    <item>
      <title>How to Patch and Run DieHarder on Alpine Linux</title>
      <dc:creator>allen-woods</dc:creator>
      <pubDate>Wed, 09 Dec 2020 15:27:05 +0000</pubDate>
      <link>https://dev.to/allenwoods/how-to-patch-and-run-dieharder-on-alpine-linux-1c2</link>
      <guid>https://dev.to/allenwoods/how-to-patch-and-run-dieharder-on-alpine-linux-1c2</guid>
      <description>&lt;p&gt;I am neither a cryptographer nor a security engineer, so when it came time to consider cryptographic best practices for my project I innocently searched for entropy test utilities. A few skimmed lists later, I had set my sites on one that I kept hearing good things about -- something called &lt;code&gt;dieharder&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/CxwvAGYoBTGYU/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/CxwvAGYoBTGYU/giphy.gif" alt="It'll be fun, they said."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nakatomi Tower as a CLI? A Digital John McClane? I had to track it down and learn more.&lt;/p&gt;

&lt;h1&gt;
  
  
  DieHarder DOA?
&lt;/h1&gt;

&lt;p&gt;DieHarder is a CLI entropy testing utility written by &lt;a href="https://webhome.phy.duke.edu/~rgb/General/dieharder.php"&gt;Robert G. Brown at Duke University&lt;/a&gt;. It implements several rigorous tests that can measure a system's performance calculating random data. To vastly oversimplify, it goes far beyond &lt;code&gt;/dev/urandom&lt;/code&gt;. "Perfect," I thought. "I'll just grab that and include it as a nice-to-have."&lt;/p&gt;

&lt;p&gt;Unfortunately, when I followed the installation instructions the compilation failed. Trying to find a solution only pulled up threads dedicated to CentOS or Ubuntu that were years out of date. So, I decided to solve how to compile it on Alpine myself.&lt;/p&gt;

&lt;h1&gt;
  
  
  Sed to the Rescue
&lt;/h1&gt;

&lt;p&gt;Luckily, the necessary changes are brief and can be made using the built-in stream editor &lt;code&gt;sed&lt;/code&gt;. The addition of a missing &lt;code&gt;typedef&lt;/code&gt; and a missing &lt;code&gt;define&lt;/code&gt; of a constant are all that it takes to make the compilation succeed; aside from renaming a required dependency.&lt;/p&gt;

&lt;p&gt;Without further ado, here's how to install, patch, compile, and run this utility on Alpine!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;

&lt;span class="c"&gt;# Install static packages.&lt;/span&gt;
apk add &lt;span class="se"&gt;\&lt;/span&gt;
  apk-tools-static &lt;span class="se"&gt;\&lt;/span&gt;
  busybox-static

&lt;span class="c"&gt;# Install packages needed to compile DieHarder.&lt;/span&gt;
apk.static &lt;span class="nt"&gt;-U&lt;/span&gt; add &lt;span class="se"&gt;\&lt;/span&gt;
  chrpath &lt;span class="se"&gt;\&lt;/span&gt;
  gsl &lt;span class="se"&gt;\&lt;/span&gt;
  gsl-dev &lt;span class="se"&gt;\&lt;/span&gt;
  haveged &lt;span class="se"&gt;\&lt;/span&gt;
  libtool &lt;span class="se"&gt;\&lt;/span&gt;
  make &lt;span class="se"&gt;\&lt;/span&gt;
  rng-tools &lt;span class="se"&gt;\&lt;/span&gt;
  rpm-dev &lt;span class="se"&gt;\&lt;/span&gt;
  build-base

&lt;span class="c"&gt;# Create a valid build tree for RPM.&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-pm&lt;/span&gt; 0700 &lt;span class="se"&gt;\&lt;/span&gt;
~/rpmbuild/&lt;span class="o"&gt;{&lt;/span&gt;BUILD,RPMS,SOURCES,SPECS,SRPMS&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Point to the 'rpmbuild' path in the macro file.&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'%_topdir %(echo $HOME)/rpmbuild'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.rpmmacros

&lt;span class="c"&gt;# Create a path of your choice to install into.&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-pm&lt;/span&gt; 0700 /your/install/path
&lt;span class="nb"&gt;chown &lt;/span&gt;root:root /your/install/path

&lt;span class="c"&gt;# Download the latest version of dieharder.&lt;/span&gt;
wget &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
http://webhome.phy.duke.edu/~rgb/General/dieharder/dieharder.tgz &lt;span class="nt"&gt;-O&lt;/span&gt; - | &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xz&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; /your/install/path/

&lt;span class="c"&gt;# Set current directory to the top level of the build&lt;/span&gt;
&lt;span class="c"&gt;# extracted from the tarball.&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /your/install/path/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# Generate makefiles and compilation resources.&lt;/span&gt;
./autogen.sh

&lt;span class="c"&gt;# ---- Patch dieharder.spec file.&lt;/span&gt;

&lt;span class="c"&gt;# Patch line 16 to point to 'gsl-dev' package.&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s1"&gt;'16s/.*/chrpath gsl-dev/'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
./dieharder.spec

&lt;span class="c"&gt;# Patch line 129 to prevent 'macro expanded' error.&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'129s/.*/# /'&lt;/span&gt; ./dieharder.spec

&lt;span class="c"&gt;# ---- Patch libdieharder.h file.&lt;/span&gt;

&lt;span class="c"&gt;# Insert new line to define 'M_PI' constant.&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s1"&gt;'66i #define M_PI    3.14159265358979323846'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
./include/dieharder/libdieharder.h

&lt;span class="c"&gt;# Insert new line to create 'uint' typedef.&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s1"&gt;'262i typedef unsigned int uint;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
./include/dieharder/libdieharder.h

&lt;span class="c"&gt;# Compile dieharder.&lt;/span&gt;
make &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Run all tests in dieharder.&lt;/span&gt;
dieharder &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This has been tested using &lt;code&gt;dieharder 3.31.1&lt;/code&gt; running on Alpine 3.12 Stable inside a HashiCorp Vault 1.5.4 image built with &lt;code&gt;docker-compose&lt;/code&gt;. Results may vary.&lt;/p&gt;

&lt;p&gt;Hope this helps you in your cryptographic projects, and thanks for reading!&lt;/p&gt;

</description>
      <category>bash</category>
      <category>devops</category>
      <category>docker</category>
      <category>linux</category>
    </item>
    <item>
      <title>Why You Should Try Using GraphQL</title>
      <dc:creator>allen-woods</dc:creator>
      <pubDate>Thu, 18 Apr 2019 16:30:47 +0000</pubDate>
      <link>https://dev.to/allenwoods/why-you-should-try-using-graphql-457o</link>
      <guid>https://dev.to/allenwoods/why-you-should-try-using-graphql-457o</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2F1%2F17%2FGraphQL_Logo.svg%2F450px-GraphQL_Logo.svg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2F1%2F17%2FGraphQL_Logo.svg%2F450px-GraphQL_Logo.svg.png" alt="GraphQL icon courtesy of Wikipedia"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Often when creating a full-stack application, a lot of time is consumed by back-end development — usually more than expected. &lt;/p&gt;

&lt;p&gt;Querying for data must be specific, which typically means some excess or deficit of the data we need when interacting with a RESTful API. This can further impact user experience and app performance due to excess overhead introduced by inefficient requests when deployed at scale.&lt;/p&gt;

&lt;p&gt;It would be great if we didn't have to delicately tip toe through our data or pull down heavy chunks just to retrieve or update specific information.&lt;/p&gt;

&lt;p&gt;Luckily, a technology was designed for that very purpose and its name is &lt;a href="http://graphql.org" rel="noopener noreferrer"&gt;&lt;code&gt;GraphQL&lt;/code&gt;&lt;/a&gt;. Today we will review the potential it has for our next projects from the perspective of a curious novice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concise Questions Within Detailed Data
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fpluspng.com%2Fimg-png%2Fpng-pointing-finger-pointing-finger-png-image-43096-878.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fpluspng.com%2Fimg-png%2Fpng-pointing-finger-pointing-finger-png-image-43096-878.png" alt="GraphQL lets you ask for only what you need"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GraphQL is an open-source querying language developed by &lt;a href="//www.facebook.com"&gt;Facebook&lt;/a&gt; that was released in 2015. Its primary premise is to provide a way for client-side requests to ask concise questions about the data in your API.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only What You Need&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the best aspects of implementing GraphQL is that you can retrieve or update only the information you want to interact with while retaining freedom in how your data store is structured.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data Typing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another terrific addition to workflow is the stronger typing of data that is sent and received through GraphQL, complete with debugging tools that make development easier overall.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database Agnostic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fact that GraphQL can be used with both relational and non-relational databases, such as &lt;code&gt;PostgreSQL&lt;/code&gt; and &lt;code&gt;MongoDB&lt;/code&gt;, among others, is definitely a plus not to be overlooked.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not a Middleware
&lt;/h3&gt;

&lt;p&gt;In practice, GraphQL essentially acts as a form of translator for your database, whereby client-side communication is relayed through it rather than passed to your data store directly.&lt;/p&gt;

&lt;p&gt;In the short term, this adds a layer of planning to a project that requires time to be allocated for design of requests themselves. However, the intuitive syntax affords a greater degree of freedom, faster turn around, and more accurate debugging when taking the long view.&lt;/p&gt;

&lt;p&gt;To put it simply, the added value in workflow alone more than makes up for the time taken to implement it.&lt;/p&gt;

&lt;p&gt;Let's take a closer look at the overview of how GraphQL is structured to get a better sense of what it does.&lt;/p&gt;

&lt;h3&gt;
  
  
  Services
&lt;/h3&gt;

&lt;p&gt;All data returned through GraphQL are effectively requested values that correspond to keys that match specific fields. These keys and values exist on a special &lt;em&gt;"root"&lt;/em&gt; object that is used to pass data to the client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Services can be written in any language, allowing for seamless integration on your server — even if your app has already been deployed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The way that GraphQL interacts with data is through &lt;code&gt;services&lt;/code&gt;, defined as blocks comprised of a data &lt;code&gt;type&lt;/code&gt; that contains one or more &lt;code&gt;fields&lt;/code&gt;. Those types and fields are then associated with callback functions that are used to process information. For example, the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Query {
  opponent: Player
}

type Player {
  id: ID!
  name: String!
}

function Query_opponent(request) {
  return request.auth.player;
}

function Player_name(player) {
  return player.getName();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run the above code, the request would take the following form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    opponent {
        name
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While the syntax looks similar to &lt;code&gt;JSON&lt;/code&gt;, it is important to note that the above GraphQL syntax is written in multi-line string format, typically surrounded by back-ticks (also known as &lt;em&gt;"grave diacritics"&lt;/em&gt;), and must be parsed during translation by the included server runtime.&lt;/p&gt;

&lt;p&gt;There are many topics involved in the definition and use of GraphQL and the rabbit holes can go rather deep.&lt;/p&gt;

&lt;p&gt;For now, we are most interested in taking a broad overview of the main building blocks. Let's start with Queries and Mutations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Queries and Mutations
&lt;/h3&gt;

&lt;p&gt;Queries are &lt;code&gt;GET&lt;/code&gt; requests written more intuitively and executed more dynamically using GraphQL. Conversely, Mutations are effectively &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, or &lt;code&gt;PATCH&lt;/code&gt; requests.&lt;/p&gt;

&lt;p&gt;To that end, all requests made through GraphQL are functionally no different from less efficient RESTful requests, in principle. However, GraphQL makes it possible to embed conditionals into requests themselves, as well as aggregate data more cohesively into a single return of data.&lt;/p&gt;

&lt;p&gt;Here is an example of what a query and a mutation might look like in GraphQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  hero {
    name
    # Queries can have comments!
    friends {
      name
    }
  }
}

mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Source: &lt;a href="https://graphql.github.io/learn/queries/" rel="noopener noreferrer"&gt;GraphQL Docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Schemas and Types
&lt;/h3&gt;

&lt;p&gt;A schema effectively operates as a rule set for GraphQL services, whereby returned data is validated using the master definition for a given service block.&lt;/p&gt;

&lt;p&gt;Types are object types that you define to describe the properties of the data you expect to return from your server. These are the container objects used to reference a given service block where data fields are contained.&lt;/p&gt;

&lt;p&gt;Here is an example of how you might write a schema of GraphQL object types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;schema {
  query: Query
  mutation: Mutation
}

query {
  hero {
    name
  }
  droid(id: "2000") {
    name
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Source: &lt;a href="https://graphql.github.io/learn/schema/#the-query-and-mutation-types" rel="noopener noreferrer"&gt;GraphQL Docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Putting It Into Practice
&lt;/h3&gt;

&lt;p&gt;The cursory nature of this overview is meant to give an impression of the possibilities made available by implementing GraphQL rather than an in-depth instructional walkthrough.&lt;/p&gt;

&lt;p&gt;In order to provide a snapshot of what can be accomplished, let's skip ahead to an example of what all of the features look like when put into practice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query Hero($episode: Episode, $withFriends: Boolean!) {
  hero(episode: $episode) {
    name
    friends @include(if: $withFriends) {
      name
    }
  }
}

query HeroForEpisode($ep: Episode!) {
  hero(episode: $ep) {
    name
    ... on Droid {
      primaryFunction
    }
    ... on Human {
      height
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Sources:&lt;br&gt;
&lt;a href="https://graphql.github.io/learn/queries/#directives" rel="noopener noreferrer"&gt;GraphQL Docs - Directives&lt;/a&gt;&lt;br&gt;
&lt;a href="https://graphql.github.io/learn/queries/#inline-fragments" rel="noopener noreferrer"&gt;GraphQL Docs - Inline Fragments&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A great example of how to use GraphQL in the context of MongoDB using the &lt;code&gt;MERN&lt;/code&gt; stack can be found in this ongoing tutorial series by Code Realm on YouTube:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/HKqbBrl_fKc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I hope that this overview has given you an idea of what GraphQL can do in your next project and that your RESTful APIs will be more relaxing.&lt;/p&gt;

&lt;p&gt;I look forward to writing an in-depth walkthrough once I have had a chance to utilize this technology in my next app design.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>nosql</category>
      <category>postgres</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Setup a Domain on VPS: From Registration to SSL Certification</title>
      <dc:creator>allen-woods</dc:creator>
      <pubDate>Thu, 04 Apr 2019 18:29:04 +0000</pubDate>
      <link>https://dev.to/allenwoods/how-to-setup-a-domain-on-vps-from-registration-to-ssl-certification-4doh</link>
      <guid>https://dev.to/allenwoods/how-to-setup-a-domain-on-vps-from-registration-to-ssl-certification-4doh</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.maintech.com%2Fwp-content%2Fuploads%2F2016%2F09%2FiStock_70297009_XXXLARGE.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.maintech.com%2Fwp-content%2Fuploads%2F2016%2F09%2FiStock_70297009_XXXLARGE.jpg" alt="Server Room"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  There is Never a "Right" Time
&lt;/h1&gt;

&lt;p&gt;This article is meant for those who have been thinking about hosting their first domain, but may be holding back. The right project will come along, the right moment will line up, &lt;em&gt;but not yet&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;After going through this process, I can tell you that there is no better time than right now to get started hosting your first domain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The best way to predict your future is to create it."&lt;/em&gt;&lt;br&gt;
— &lt;em&gt;Abraham Lincoln&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This walkthrough is geared toward those who choose to do things manually and &lt;em&gt;"learn by doing"&lt;/em&gt;. If this is not your approach, you can still follow along using the easy one-click versions of what I discuss.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; &lt;code&gt;This tutorial is written from a Mac user's perspective.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There are many different ways to achieve the same outcome, but for the purposes of this article we will be discussing domain name registration through &lt;a href="https://www.namecheap.com" rel="noopener noreferrer"&gt;Namecheap&lt;/a&gt; and VPS hosting through &lt;a href="https://www.digitalocean.com" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ready? &lt;strong&gt;Let's go!&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What's In a Name
&lt;/h1&gt;

&lt;p&gt;The hardest part of this entire process is unfortunately one I cannot help you with -- &lt;strong&gt;choosing your domain name&lt;/strong&gt;. While I can't help you come up with the exact name itself, I can share the advice I have received to help make it easier for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Personal or Professional?
&lt;/h3&gt;

&lt;p&gt;To start off on the right foot, we must be direct: &lt;u&gt;what kind of programmer are you&lt;/u&gt;?&lt;/p&gt;

&lt;p&gt;Are you career focused and want to build and maintain a selection of apps as a resume pitch toward landing a role?&lt;/p&gt;

&lt;p&gt;Are you passionate about code and find yourself constantly diving into projects beyond your assignments or daily standups for the thrill of understanding and learning new things?&lt;/p&gt;

&lt;p&gt;The difference comes down to commitment and time scale — both important factors that will guide how to choose your first domain name. For example, a personal site may adapt to changes within your career path while a professional site is more likely to represent a specific narrative within a set domain.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt; &lt;/th&gt;
&lt;th&gt;Personal&lt;/th&gt;
&lt;th&gt;Professional&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Based on&lt;/td&gt;
&lt;td&gt;Your legal name or nickname.&lt;/td&gt;
&lt;td&gt;Distinctive, memorable identifier.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Developers who view tech as a chapter in their overall career path, rather than a passion.&lt;/td&gt;
&lt;td&gt;Aspiring Engineers who are passionate about code itself.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical use&lt;/td&gt;
&lt;td&gt;Resume pitch while job searching.&lt;/td&gt;
&lt;td&gt;Showcasing an ongoing body of work to build an online presence and curated brand image representative of your passion for code.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Can be used by passionate programmers to build an &lt;a href="https://en.wikipedia.org/wiki/Asch_conformity_experiments" rel="noopener noreferrer"&gt;Asch phenomenon&lt;/a&gt; surrounding their online presence, but works best with distinctive legal names or nicknames.&lt;/td&gt;
&lt;td&gt;Harder to come up with and often harder to register.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The ideal case would be to have both types of domains as a "catch all" approach, but I would recommend starting with what your passion level is and use that to pick one domain to start with.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checking Availability
&lt;/h3&gt;

&lt;p&gt;Many, many, many times I have had a perfect idea in my head for a domain name, only to find out that it isn't available. This used to mean encountering landing pages on the sites I went to check for, but I have recently discovered that just because a site appears to be unregistered does not mean that it's unregistered.&lt;/p&gt;

&lt;p&gt;This brings me to our first axiom:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A registered domain is more expensive than an unregistered domain.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unless you really intend to make back your investment and can afford to pay the asking price, try to purchase an unregistered domain whenever possible.&lt;/p&gt;

&lt;p&gt;To make sure your site is actually available instead of privately parked, I recommend taking the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://whois.icann.org/en" rel="noopener noreferrer"&gt;WHOIS (ICANN)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Look to see if the domain is registered by anyone.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://namechk.com/" rel="noopener noreferrer"&gt;Namechk&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;If the site is available, look to see how much reach that name would have across social media platforms.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you have settled on your passion level and your domain name of choice, it's time to commit and make the purchase.&lt;/p&gt;

&lt;p&gt;If you have read this far, you know that you're ready. &lt;strong&gt;Let's do it!&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Registration
&lt;/h1&gt;

&lt;p&gt;The domain name broker I went through was &lt;a href="https://www.namecheap.com" rel="noopener noreferrer"&gt;Namecheap.com&lt;/a&gt;. I highly recommend them when registering a domain because of how incredibly straight forward and easy to follow the overall process is.&lt;/p&gt;

&lt;p&gt;That said, there are some things we should go over in terms of what you &lt;em&gt;need&lt;/em&gt; to purchase and what you &lt;em&gt;don't need&lt;/em&gt; to purchase.&lt;/p&gt;

&lt;h3&gt;
  
  
  What to Purchase
&lt;/h3&gt;

&lt;p&gt;You should only be paying for or selecting the following items when registering your domain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Domain name itself.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WHOIS Guard&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last one is important. WHOIS Guard effectively protects your email, address, and legal name from WHOIS searches. Without this selected, your personal information would not be anonymized and would be publicly available.&lt;/p&gt;

&lt;p&gt;When entering "webmaster" type emails later in this guide, you can use the special "WHOIS" protected email address you are provided by this service instead of an established webmaster email address to remain anonymous.&lt;/p&gt;

&lt;p&gt;Namecheap does make an SSL certificate available to you that lasts for a period of one year, but this is &lt;em&gt;&lt;u&gt;not&lt;/u&gt;&lt;/em&gt; required in order to setup HTTPS on your domain. &lt;em&gt;(I learned that the hard way so you don't have to.)&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We will cover how to configure Certbot to generate an SSL certificate through &lt;a href="https://letsencrypt.org" rel="noopener noreferrer"&gt;Letsencrypt.org&lt;/a&gt; toward the end of this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You will not really need to setup anything more advanced than this to get started. Now that your domain name is newly registered, it may take up to 72 hours for the registration to be completed. In the mean time, let's set up our hosting!&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating A Droplet on DigitalOcean
&lt;/h1&gt;

&lt;p&gt;I researched many hosting providers before I committed to a decision. The primary providers that I ultimately chose from were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/ec2/" rel="noopener noreferrer"&gt;AWS EC2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linode.com/" rel="noopener noreferrer"&gt;Linode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mediatemple.net/" rel="noopener noreferrer"&gt;MediaTemple&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ovh.com/world/" rel="noopener noreferrer"&gt;OVH&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I selected DigitalOcean because their name kept getting mentioned and recommended by other devs in threads on web-development subreddits and because their free documentation has so much depth.&lt;/p&gt;

&lt;p&gt;I am very much a "learn by doing" type of person and the predominantly DIY nature of DigitalOcean's services felt like a right fit with what I wanted — to develop skills by doing things myself.&lt;/p&gt;

&lt;p&gt;That said, this can feel daunting for one reason in particular.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linux
&lt;/h3&gt;

&lt;p&gt;It takes a certain kind of person to make it through this tutorial. To put that more succinctly, you have to feel slightly more excitement than fear when you open bash and only see this in your terminal:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;That is not very much to go on. Luckily, there are tons of resources online regarding the use of Linux and the community is very welcoming and supportive.&lt;/p&gt;

&lt;p&gt;This brings us to our second axiom:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The more dynamic your skill set is, the more valuable you are.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You don't need to already know Linux to follow along, but placing yourself in the position of having to learn it should be bundled into your desire to embark on this experience.&lt;/p&gt;

&lt;p&gt;Being able to navigate and use Linux, as well as being able to say that you manage your own VPS, is better than not knowing those supportive technologies first-hand.&lt;/p&gt;

&lt;p&gt;For now, I have journeyed long into these rabbit holes and done all the research for you. &lt;strong&gt;Onward, to the command line!&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Commanding the Line (Ubuntu)
&lt;/h3&gt;

&lt;p&gt;There are a lot of Linux distributions — known as &lt;em&gt;"distros"&lt;/em&gt; — but we will be focusing on the server version of Ubuntu Linux for this walkthrough.&lt;/p&gt;

&lt;p&gt;Linux is versioned in varying levels of granularity all the way down to a frequency of as often as nightly build changes. However, the version type that we want to use on our VPS is something called Long Term Support or LTS for short.&lt;/p&gt;

&lt;p&gt;As of this writing, the current LTS release is Ubuntu Server 18.04, released in April of 2018. This is what we will select to have pre-installed on to our VPS.&lt;/p&gt;

&lt;p&gt;LTS versions remain dependable for a period of up to two years, requiring far fewer updates to your server and less maintenance to perform. We should probably take this opportunity to go over our third axiom:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Always use the LTS version.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are not just LTS versions of Linux, but NodeJS and other frameworks as well. Ideally, you should aim to identify and use an LTS versioned stack whenever possible to reduce pain points maintaining a project. Alternatively, you can create Docker containers for your applications.&lt;/p&gt;

&lt;p&gt;If you would like to know more about Docker, please see the following article by one of my peers at Flatiron School Seattle:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/matthewbrophy/docker-basics-46k7"&gt;Docker Basics&lt;/a&gt; by Matthew Brophy&lt;/p&gt;

&lt;p&gt;This is a lot to go through before getting started, so let's take this a step at a time. To start things off, we need to do some things on your local machine first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Secure Shell (SSH)
&lt;/h3&gt;

&lt;p&gt;Everything we do regarding how we interact with our VPS should be encrypted to remain secure. To accomplish this, we use Secure Shell, or &lt;em&gt;"SSH"&lt;/em&gt; to connect. In order to prepare, before even purchasing a VPS on DigitalOcean, we need to generate a new SSH key pair.&lt;/p&gt;

&lt;p&gt;Open terminal on your computer and enter the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -f ~/your-domain-name-here-rsa -t rsa -b 4096
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For more, see: &lt;a href="https://www.ssh.com/ssh/keygen/" rel="noopener noreferrer"&gt;SSH Keygen&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Be sure to replace &lt;code&gt;your-domain-name-here&lt;/code&gt; with the name of your newly registered site.&lt;/p&gt;

&lt;p&gt;If you are prompted that creation of the new key will overwrite an existing key, cancel. Agreeing to overwrite an existing key is a permanent and destructive act that will erase the overwritten key forever.&lt;/p&gt;

&lt;p&gt;Now that we have the keys we need to create our Droplet on DigitalOcean, let's start building our castle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing a Droplet Type
&lt;/h3&gt;

&lt;p&gt;You should generally aim for the amount of hosting you need based on your comfort level, available time, budget, and the demands of your project(s).&lt;/p&gt;

&lt;p&gt;I would also say that there should be some element of incentivized participation trough economic pressure, whereby increased use of the VPS is insured as a result of "having to pay for it."&lt;/p&gt;

&lt;p&gt;In my case, I knew that I wanted to build apps that would use computationally more expensive functions for some things, as well as the need to stream data in real time to achieve some of the results I wanted to accomplish. To that end, I measured twice and cut once by getting their $20 a month option.&lt;/p&gt;

&lt;p&gt;At the time of this writing, this is what DigitalOcean offers on their $20 VPS tier:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtnzp36rm70xnl0la293.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtnzp36rm70xnl0la293.png" alt="4 GB Memory, 2 vCPU, 80 GB SSD, 4 TB Transfer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the Droplet configuration that meets your criteria. Follow the setup procedure, but once you see an option button titled "Add SSH Keys" appear on screen, wait until you have read the next step before continuing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to: &lt;a href="https://www.digitalocean.com/pricing/" rel="noopener noreferrer"&gt;DigitalOcean Droplet Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Binding SSH
&lt;/h3&gt;

&lt;p&gt;Back in your bash terminal, go ahead and type the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pbcopy &amp;lt; ~/.ssh/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will copy your personal SSH key to the clipboard, so don't select and copy any text until you have attached this key to your Droplet.&lt;/p&gt;

&lt;p&gt;Click the "Add SSH Keys" button on DigitalOcean and paste the key's text into the form that appears. You should see a very large hash of encrypted data when pasting the text if this is successful.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For more, see: &lt;a href="https://www.digitalocean.com/docs/droplets/how-to/add-ssh-keys/to-account/" rel="noopener noreferrer"&gt;How to Upload SSH Public Keys to a DigitalOcean Account&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The reason we are binding the SSH key to our Droplet in this way is because it does three things that are very important.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It disables password authentication at time of creation for the Droplet.&lt;/li&gt;
&lt;li&gt;It makes all use of the Droplet secure over SSH from the start.&lt;/li&gt;
&lt;li&gt;It prevents email delivery of any login information related to our VPS.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This makes sure that people can't even attempt a password access on the VPS at the moment it becomes activated, much less before we are able to login.&lt;/p&gt;

&lt;p&gt;By default without an SSH key attached, the VPS would have password authentication enabled, which is less secure and requires manual deactivation. It also would require us to add the SSH key in a far less easy manner, although DigitalOcean does allow you to add an SSH key from the browser while in the managing editor for the Droplet itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Importance of IPv6
&lt;/h3&gt;

&lt;p&gt;Make sure that you have selected the checkbox for "IPv6" on your VPS options. This will generate a longer IP address that will allow your server to be accessible once the older IPv4 standard is phased out years in the future.&lt;/p&gt;

&lt;p&gt;Many technologies provided by DigitalOcean, as well as web technologies in general, benefit from the availability of an IPv6 connection, so it's a nice option to have activated.&lt;/p&gt;

&lt;p&gt;At this point, we are ready to communicate with our VPS for the first time and get down to business. Be sure to copy down your IPv4 address from DigitalOcean and prepare to login to your server!&lt;/p&gt;

&lt;h3&gt;
  
  
  Becoming a Superuser
&lt;/h3&gt;

&lt;p&gt;For the sake of clarity, I will be condensing the necessary commands into coherent blocks. For those unfamiliar to the syntax, all lines beginning with a &lt;code&gt;#&lt;/code&gt; symbol are descriptive comments, not bash commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh root@&amp;lt;your_server_ipv4&amp;gt;
# Confirm "yes" to connect.

adduser &amp;lt;your_first_name&amp;gt;
# Type a strong password and skip everything else.

usermod -aG sudo &amp;lt;your_first_name&amp;gt;
ufw app list
# You should see OpenSSH listed.

ufw allow OpenSSH
ufw enable
# Type yes to confirm.

ufw status
# You should see OpenSSH and Open SSH (v6) ALLOW from Anywhere.

rsync --archive --chown=&amp;lt;your_first_name&amp;gt;:&amp;lt;your_first_name&amp;gt; ~/.ssh /home/&amp;lt;your_first_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your bash terminal press Command+T to create a new parallel tab. &lt;strong&gt;Remain logged into the "root" user in the first terminal tab.&lt;/strong&gt; This is important in case anything goes wrong during the configuration of your user account.&lt;/p&gt;

&lt;p&gt;Inside the parallel tab, enter the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh &amp;lt;your_first_name&amp;gt;@&amp;lt;your_server_ipv4&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are logged into your user account in the second tab, you can now toggle back to your "root" session and continue. Enter the following in the "root" user tab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/ssh/sshd_config
# Press the down arrow to scroll the editor until you see PermitRootLogin.
# Edit the line to read: PermitRootLogin no

# Press the down arrow to scroll the editor until you see PasswordAuthentication.
# Edit the line to read: PasswordAuthentication no

# Press Ctrl + X, then Y and Enter to save and exit the editor.

sudo systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch back to your user account tab and enter the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logout
ssh &amp;lt;your_first_name&amp;gt;@&amp;lt;your_server_ipv4&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all has gone well up until this point with no snags, you can now safely logout of the "root" user terminal and close all terminal tabs.&lt;/p&gt;

&lt;p&gt;To briefly summarize what we just did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We gained access to our VPS.&lt;/li&gt;
&lt;li&gt;We created a new user.&lt;/li&gt;
&lt;li&gt;We gave our user account the same powers as "root" (sudo).&lt;/li&gt;
&lt;li&gt;We raised the firewall against everything except for SSH logins.&lt;/li&gt;
&lt;li&gt;We allowed our user account SSH access.&lt;/li&gt;
&lt;li&gt;We removed the "root" user from being able to login again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reason we removed the "root" user is because most attacks on a server will come through the "root" login. By preventing this user from accessing the system, we add a layer of security to the system.&lt;/p&gt;

&lt;p&gt;Now that our user account has been granted the same powers, we don't need "root" to be accessible anymore.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For more, see: &lt;a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04" rel="noopener noreferrer"&gt;Initial Server Setup with Ubuntu 18.04&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Setting Up the Server
&lt;/h1&gt;

&lt;p&gt;Now that our VPS is secured, it's time to get everything up to speed in terms of system updates and necessary software. Log in using your user account and enter the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get upgrade
# Press Y and Enter to confirm.

sudo apt-get install curl imagemagick subversion wget lynx iperf rsync
# Press Y and Enter to confirm.

sudo apt-get install unrar unzip iptraf nmap tcpdump sysstat zip
# Press Y and Enter to confirm.

sudo apt remove cmdtest
# This might say cmdtest doesn't exist, but better to be sure.
# We remove this application to allow for installation of Yarn.

sudo nano ~/.bash_aliases
# Inside the editor, add this line (without leading # symbol):
# alias node=nodejs
# Press Ctrl + X, Y and Enter to save and exit the editor.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For more, see: &lt;a href="http://www.pkill-9.com/enabling-bash_aliases/" rel="noopener noreferrer"&gt;How to Enable .bash_aliases&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;A Word About NodeJs on Ubuntu&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The way that the alias for NodeJS works on Ubuntu Server, a separate alias called "nodejs" must be made to point to the NodeJS install on the VPS.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The workaround we have used in the last file edit process above is to use a new alias named "node" to point to the "nodejs" command, thereby patching the node command to be canonical with the local environment. |&lt;/p&gt;

&lt;p&gt;The ground work is nearly complete for serving our first page over HTTP. We only have two more major installs to carry out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing Nginx
&lt;/h3&gt;

&lt;p&gt;If you are hosting a more advanced project using a stack, such as MERN or similar, you will need to do further reading on these topics in addition to this walkthrough. For now, we just want to serve a static page over HTTPS. This is our first time going through this process, so we will stick to the basics.&lt;/p&gt;

&lt;p&gt;The HTTP server that our VPS uses is called &lt;em&gt;"Nginx"&lt;/em&gt;. The installation is the following series of commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt install nginx
sudo ufw app list
# The output should show new options for Nginx Full, Nginx HTTP, and HTTPS.

sudo ufw allow 'Nginx HTTP'
sudo ufw status
# The output should show ALLOW from Anywhere for Nginx HTTP and Nginx HTTP (v6).

systemctl status nginx
# The output should include "Active: active (running)".
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For more, see: &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-18-04" rel="noopener noreferrer"&gt;How To Install Nginx on Ubuntu 18.04&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we have Nginx setup, we need to have something to serve and a way to serve it. Nginx is a tool, but it doesn't run by itself. We'll need to setup a server block for it to run, as well as upload our "hello world" to the server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uploading Your Hello World
&lt;/h3&gt;

&lt;p&gt;It's time to place your first static page on the VPS itself. Follow this sequence in your VPS login terminal session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir -p /var/www/yourdomainname.com/html
# Be sure to replace "yourdomainname" with your domain name.

sudo chown -R $&amp;lt;your_first_name&amp;gt;:$&amp;lt;your_first_name&amp;gt; /var/www/example.com/html
sudo chmod -R 755 /var/www/yourdomainname.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside of a second terminal tab pointing to your local machine, enter the following command to transfer the local root folder to the VPS root folder being used by Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scp -r /local/root &amp;lt;your_user&amp;gt;@&amp;lt;your_ipv4&amp;gt;:/var/www/yourdomainname.com/html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For more, see: &lt;a href="https://stackabuse.com/copying-a-directory-with-scp/" rel="noopener noreferrer"&gt;Copying a Directory with SCP&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If this is successful, you should see your files uploading into the server. Great, your files are on the internet now. But using an IPv4 address to reach them isn't the most attractive option. Let's fix that.&lt;/p&gt;

&lt;h1&gt;
  
  
  Binding Your Domain to Your Host
&lt;/h1&gt;

&lt;p&gt;By default, Namecheap will park your domain name on their nameservers. These addresses associate your registered domain as an idle "parking" page that shows a form letter message suggesting your domain could be for sale.&lt;/p&gt;

&lt;p&gt;We need to change these nameservers to reflect our VPS on DigitalOcean, as well as bind our domain name to the IP of the VPS itself. Let's go through the steps needed to complete this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nameservers, IP and SSL
&lt;/h3&gt;

&lt;p&gt;Log into your Namecheap account and click "Manage" on your domain name. Once inside of your dashboard, scroll down to "Nameservers" and enter the following addresses:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Nameservers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ns1.digitalocean.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ns2.digitalocean.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ns3.digitalocean.com&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Scroll down until you find an option named "Parking Page" and disable it. This will unlink the domain from the template saying "this site might be for sale" that is automatically hosted by Namecheap.&lt;/p&gt;

&lt;p&gt;Now the domain name will point to the nameservers on DigitalOcean where the actual data of your VPS will be located and served to your visitors. The second half of binding will be carried out on DigitalOcean. Log into your DigitalOcean account and add your domain to your dashboard.&lt;/p&gt;

&lt;p&gt;Inside of this domain's management features, you will need to create the following records:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Hostname&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CAA&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.yourdomain.com" rel="noopener noreferrer"&gt;www.yourdomain.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;authorization: &lt;strong&gt;letsencrypt.org&lt;/strong&gt; [&lt;code&gt;issue&lt;/code&gt;]&lt;/td&gt;
&lt;td&gt;3600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AAAA&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.yourdomain.com" rel="noopener noreferrer"&gt;www.yourdomain.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;directs to &lt;strong&gt;IPv6&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;3600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.yourdomain.com" rel="noopener noreferrer"&gt;www.yourdomain.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;directs to &lt;strong&gt;IPv4&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;3600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NS&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.yourdomain.com" rel="noopener noreferrer"&gt;www.yourdomain.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;directs to &lt;strong&gt;ns1.digitalocean.com&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;1800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NS&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.yourdomain.com" rel="noopener noreferrer"&gt;www.yourdomain.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;directs to &lt;strong&gt;ns2.digitalocean.com&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;1800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NS&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.yourdomain.com" rel="noopener noreferrer"&gt;www.yourdomain.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;directs to &lt;strong&gt;ns3.digitalocean.com&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;1800&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Binding to your VPS occurs by choosing your Droplet in the dashboard of each record entry. The IPv6 and IPv4 addresses are entered for you automatically by entering the &lt;code&gt;@&lt;/code&gt; symbol in those fields on DigitalOcean. Additionally, the &lt;code&gt;issue&lt;/code&gt; flag is a dropdown menu selection within the DigitalOcean dashboard when filling out this section.&lt;/p&gt;

&lt;p&gt;What we have just done is complete the link between the domain we registered and our VPS, as well as enable SSL certification through &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Letsencrypt.org&lt;/a&gt;. But enabling the possibility of SSL certification is not the same as being certified. Let's configure and generate an SSL certificate for our "hello world".&lt;/p&gt;

&lt;h1&gt;
  
  
  SSL Certification
&lt;/h1&gt;

&lt;p&gt;There are two steps to completing this process. Installation of Certbot, and generation of a SSL key pair. This proved to be the trickiest part for me during my experience setting this up on my VPS, but lucky for you I am able to set you off on the right path to make this as easy as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing Certbot
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Letsencrypt.org&lt;/a&gt; provides a utility for issuing and renewing SSL certificates using OpenSSL. From the VPS login session terminal, the installation process is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python3-certbot-dns-digitalocean
sudo certbot --nginx
sudo certbot -a certbot-dns-digitalocean -i nginx -d "*.example.com" -d example.com --server https://acme-v02.api.letsencrypt.org/directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For more, see: &lt;a href="https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx" rel="noopener noreferrer"&gt;Nginx on Ubuntu 18.04 LTS&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that Certbot is installed on the VPS, we must generate and use an SSL key pair to enable it. Follow these commands to complete our SSL certification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install python-certbot-nginx
sudo nano /etc/nginx/sites-available/yourdomainname.com
# Locate lines that begin with: server_name
# These lines should read: server_name yourdomain.com www.yourdomain.com;
# If this is not how it reads, update the lines to match.

sudo nginx -t
# The output should show no errors.

sudo systemctl reload nginx
sudo ufw status
# Output should show ALLOW from Anywhere on OpenSSH and Nginx HTTP

sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
sudo ufw status
# Confirm that Nginx HTTP has been disabled from the ALLOW from Anywhere list.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all has gone well, the following command will be the last step in the process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For more, see: &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04" rel="noopener noreferrer"&gt;How To Secure Nginx with Let's Encrypt on Ubuntu 18.04&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;This has been quite the journey. If you have paced yourself and made it through this process, give yourself a standing ovation because this really is a rather "involved" undertaking.&lt;/p&gt;

&lt;p&gt;The main point of this article is to show how important it is to set yourself ambitious but obtainable goals. Yes, it was difficult and complicated, but the achievement of having accomplished something that pushed you past your prior perception of your personal limits makes it all worth it.&lt;/p&gt;

&lt;p&gt;I hope that anyone reading this from a novice perspective comes away from this walkthrough with a greater sense of confidence and the beginning of a whole new set of skills. I had no experience in this, just as you might not have. Yet, here we are.&lt;/p&gt;

&lt;p&gt;There is no telling how far you will go from here, but the odds are good it will be very far. You have already begun to master an important concept that a famous quote sums up nicely:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Whether you believe you can do a thing or not, you're right.&lt;/strong&gt;&lt;br&gt;
— Henry Ford&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Happy hosting!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have questions, I will do my best to answer in the comments.&lt;br&gt;
You can visit my own humble "hello world" of a random doodle at &lt;a href="https://www.thesupertask.com" rel="noopener noreferrer"&gt;The Supertask&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>vps</category>
      <category>ubuntu</category>
      <category>nginx</category>
      <category>ssl</category>
    </item>
    <item>
      <title>Defining Private Members in JavaScript Classes: How and Why</title>
      <dc:creator>allen-woods</dc:creator>
      <pubDate>Thu, 21 Mar 2019 22:09:40 +0000</pubDate>
      <link>https://dev.to/allenwoods/defining-private-members-in-javascript-classes-how-and-why-244m</link>
      <guid>https://dev.to/allenwoods/defining-private-members-in-javascript-classes-how-and-why-244m</guid>
      <description>&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;One of the more important concepts in Object Oriented Programming is the use of private properties and methods, collectively referred to as private members from here on.&lt;/p&gt;

&lt;p&gt;The basic idea is that any data that is critical data to an application should be made private to prevent catastrophic faults or exploits that would otherwise be possible if those private members were accessible.&lt;/p&gt;

&lt;p&gt;While it is possible to achieve truly private members using technologies such as webpack or ES6 modules, I will be discussing how you can achieve a very similar result using closures, Symbol(), and WeakMap().&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details on this subject that go beyond the scope of this article, please give &lt;a href="http://2ality.com/2016/01/private-data-classes.html"&gt;the inspiration for this article&lt;/a&gt;, by &lt;a href="https://twitter.com/rauschma"&gt;Axel Rauschmayer&lt;/a&gt; a read.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Naming Convention
&lt;/h2&gt;

&lt;p&gt;When researching how to accomplish private members on classes in vanilla JavaScript, I found several articles and Stackoverflow threads suggesting the use of a common naming convention that places underscores at the beginning of variable names to indicate a "private" status.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class NamingConventionClass {
  constructor() {
    this._hidden = "Can you see me?";
  }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The problem with this approach is that it is a way to indicate to other programmers whether a member is intended to be private or not. In short, something that is "_hidden" through naming convention is still visible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let peekaboo = new NamingConventionClass();
console.log(peekaboo._hidden + '...Yes I can.');

// outputs 'Can you see me? ...Yes I can.'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is a problem if the intention is to keep certain members on our class objects inaccessible from the outside. Anybody using inspect in their browser could manipulate variables with undesirable results that could have real consequences beyond DOM manipulation.&lt;/p&gt;

&lt;p&gt;We need some sort of private container to place our private members into without losing track of either where they are or what instance they belong to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter the WeakMap
&lt;/h2&gt;

&lt;p&gt;The best solution provided by vanilla JavaScript that I have found (as of this writing) is the WeakMap class. A WeakMap is simply a collection of keys and values. Each key must be a reference to an object and each corresponding value can be any arbitrary data. Because each &lt;code&gt;key, value&lt;/code&gt; pair is added at the same time, their indexes always correspond.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let myWeakMap = new WeakMap();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The main advantage of using WeakMaps as opposed to other options provided by the map API is that their references are held "weakly", allowing for garbage collection. This means that if the data referenced in the WeakMap is deleted, such as the destruction of a class instance, the allocation of the WeakMap will be removed from memory along with it.&lt;/p&gt;

&lt;p&gt;One way to use WeakMaps to obfuscate private members from a class is to do something similar to the example provided in Axel's article, as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let _variableOne = new WeakMap();
let _variableTwo = new WeakMap();

class WeakMapPrivateMembers {
  constructor(valueOne, valueTwo) {
    _variableOne.set(this, valueOne);
    _variableTwo.set(this, valueTwo);
  }
  combineValuesInString() {
    let v1 = _variableOne.get(this);
    let v2 = _variableTwo.get(this);
    return `${v1}, ${v2}`;
  }
};

const hideTwoVariables = new WeakMapPrivateMembers('foo', 'bar');
console.log(hideTwoVariables.combineValuesInString());
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This approach has at least three major problems listed below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WeakMaps are accessible in global namespace.&lt;/li&gt;
&lt;li&gt;WeakMaps are inefficiently defined for each variable.&lt;/li&gt;
&lt;li&gt;WeakMaps can still be accessed and overwritten.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We're making progress, but now we have a problem based on the scope that our data is being stored in. We need to redefine how our class is being instantiated in such a way that our WeakMap data can remain inaccessible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Class as Closure
&lt;/h2&gt;

&lt;p&gt;It turns out that you can wrap an entire class definition inside of an Immediately Invoked Function Expression, or &lt;code&gt;IIFE&lt;/code&gt; &lt;em&gt;(pronounced "iffy")&lt;/em&gt;. The basic syntax of how this would look is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const MyClosureClass = ((param1, param2, param3) =&amp;gt; {

  // Define a variable inside the scope of the closure to keep it hidden.
  // This WeakMap will act as a repository for all instances of this class.

  const _wm = new WeakMap();

  return class MyClosureClass {
    constructor(param1, param2, param3) {
      // add this class instance's private members

      _wm.set(this, {
        property1: param1,
        property2: param2,
        property3: param3
      });
    }
    get privateMembers() {
      // return the object stored at object key of "this"

      return _wm.get(this);
    }
  };
})();

let myPrivacy = new MyClosureClass("something important");

console.log(myPrivacy.privateMembers);
// The above line will return 'something important'

console.log(myPrivacy.params);
// The above line will return undefined

console.log(_wm);
// The above line will return undefined as well
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What this means is that our class can now be instantiated with incoming data that can only be obtained through sanctioned getter methods. Also, we can nest an object containing a more complex structure of private members we want to associate with the class instance.&lt;/p&gt;

&lt;p&gt;We could take this a step further and apply transformations to the data before returning it, or simply use the privately stored value(s) to perform conditionals that dictate the return of safer values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// (code abridged)

    // rewrite the getter method as a confirmation method
    hasPrivateMembers() {
      return !!_wm.get(this);
    }

// (code continued)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It is important to note that you should be writing a helper method in the scope of your closure to abstract the need to type &lt;code&gt;_wm.get(this).params[privateMemberName]&lt;/code&gt; every time you want to access the private member &lt;code&gt;privateMemberName&lt;/code&gt;, as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Inside the scope of our closure...

const _self = function(objRef) {
  _wm.get(objRef);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Embedding Symbols to Introduce Entropy
&lt;/h2&gt;

&lt;p&gt;If you really, really, really need something to be private, other options are more suitable for this -- securing data within your database with no client side visibility being chief among them.&lt;/p&gt;

&lt;p&gt;However, if you want to take the privacy of client side data to a paranoid level, you can also nest your private members deeper by using a Symbol to point to them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// (code abridged)
    constructor(param1, param2, param3) {
      _wm.set(this, {
        [Symbol('root')]: {
          property1: param1,
          property2: param2,
          property3: param3
        }
      });
    }
// (code continued)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The primary drawback to applying this emphatic level of privacy is that you need a rather convoluted helper method to access these private members. However, if you want to pursue this route to explore how it operates, the helper method would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Inside the scope of our closure...

const _self = function(objRef) {
  let obj = _wm.get(objRef)[
    Object.getOwnPropertySymbols( _wm.get(objRef) )[0]
  ];

  return obj;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



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

&lt;p&gt;If you don't want to rely on an entire framework to do the work for you, using a WeakMap and an &lt;code&gt;IIFE&lt;/code&gt; wrapper to convert your classes into closures is a terrific solution to private members on classes as of this writing.&lt;/p&gt;

&lt;p&gt;I hope that this article can help guide you in improving your design considerations when building OOJS applications that require both public and private members.&lt;/p&gt;

&lt;p&gt;Here in its final form is a reference of our example class utilizing everything we have just discussed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const MyClosureClass = ((param1, param2, param3) =&amp;gt; {

  const _wm = new WeakMap();

  const _self = function(objRef) {
    let obj = _wm.get(objRef)[
      Object.getOwnPropertySymbols( _wm.get(this) )[0]
    ];
    return obj;
  };

  return class MyClosureClass {
    constructor(param1, param2, param3) {

      _wm.set(this, {
        [Symbol('root')]: {
          property1: param1,
          property2: param2,
          property3: param3
        }
      });
    }
    get privateMembers() {
      return _self(this);
    }

    getSpecificMember(memberName) {
      return _self(this)[memberName];
    }

    hasPrivateMembers() {
      return !!_self(this);
    }
  };
})();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>oojs</category>
      <category>private</category>
      <category>closure</category>
    </item>
    <item>
      <title>JavaScript: A Primer for Rubyists</title>
      <dc:creator>allen-woods</dc:creator>
      <pubDate>Thu, 07 Mar 2019 18:20:01 +0000</pubDate>
      <link>https://dev.to/allenwoods/javascript-a-primer-for-rubyists-3hep</link>
      <guid>https://dev.to/allenwoods/javascript-a-primer-for-rubyists-3hep</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmemeguy.com%2Fphotos%2Fimages%2Fyou-can-do-the-thing-114423.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmemeguy.com%2Fphotos%2Fimages%2Fyou-can-do-the-thing-114423.jpg" alt="Do the thing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I first began to learn Ruby at &lt;a href="https://flatironschool.com/campuses/seattle/" rel="noopener noreferrer"&gt;Flatiron&lt;/a&gt;, I brought my previous experience with JavaScript along for the journey in hopes of narrowing the gap between the two syntaxes. While understanding some key concepts of programming fundamentals was helpful, I soon found myself in the far reaches of a very alien landscape of implied abstraction that seemed to counter everything I had previously known.&lt;/p&gt;

&lt;p&gt;Now that I have trekked these past 6 weeks from the southern shores of simple &lt;code&gt;do&lt;/code&gt; and &lt;code&gt;def&lt;/code&gt;, all the way to the northern highlands of Rails 5, I find myself ironically jarred by setting foot in the familiar territory of JavaScript again.&lt;/p&gt;

&lt;p&gt;Herein I will endeavor to describe the fundamental differences between JavaScript and Ruby syntax from a Rubyist's perspective and offer my strategies for achieving better mental dexterity when alternating between these two languages.&lt;/p&gt;

&lt;h1&gt;
  
  
  Explicit Implications
&lt;/h1&gt;

&lt;p&gt;At the ground level, the major disconnect between Ruby and JavaScript is that Ruby is considered to be "strongly typed," meaning data types relate to one another in very specific ways; while JavaScript is considered to be "weakly typed," meaning data types are much more mutable and can relate to one another in less specific ways.&lt;/p&gt;

&lt;p&gt;Where Ruby allows for implied logic with explicit rules for its data types, JavaScript requires explicit logic with more implied rules for its data types.&lt;/p&gt;

&lt;p&gt;A perfect example of the difference in the rule sets is how Ruby treats integers and floating point numbers as separate data types that must be converted to act on each other, while JavaScript simply has numbers that can be either integers or floating values.&lt;/p&gt;

&lt;p&gt;This clearly means there is a lot more freedom in a programmer's range of motion when working with JavaScript, however, that same range of freedom can yield unexpected results when embracing it from the background of a Rubyist.&lt;/p&gt;

&lt;p&gt;A perfect example of the divide in how logic is treated differently is the fact that unless a value is explicitly returned using the &lt;code&gt;return&lt;/code&gt; bare word in JavaScript, functions have an undefined return value.&lt;/p&gt;

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

&lt;p&gt;This flies in the face of Ruby conventions that favor implied returns at the final line of a method. But if one thing has become clear so far on my journey of learning to code, it is that repetition breeds knowledge and knowledge breeds skill. In other words, doing things in a standardized way helps cement concepts. To that end, I have found that using either a commented &lt;code&gt;return&lt;/code&gt; above my last line or actually applying the &lt;code&gt;return&lt;/code&gt; bare word to my last line in Ruby helps me stay grounded across both languages.&lt;/p&gt;

&lt;h1&gt;
  
  
  Do or Do Not, There Is No Pry
&lt;/h1&gt;

&lt;p&gt;There are &lt;code&gt;do&lt;/code&gt; loops in JavaScript that emulate behavior that is similar to the &lt;code&gt;do&lt;/code&gt; blocks found in Ruby, but they have a very important difference.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;do&lt;/code&gt; blocks in Ruby do not trigger if either their condition isn't met or the iterator they are passed to is unable to fire at least once.&lt;/li&gt;
&lt;li&gt;In JavaScript, &lt;code&gt;do&lt;/code&gt; loops evaluate their condition only after executing their code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This means that&lt;/strong&gt; &lt;code&gt;do&lt;/code&gt; &lt;strong&gt;loops always trigger at least once in JavaScript,&lt;/strong&gt; as illustrated below.&lt;/p&gt;

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

&lt;p&gt;The differences in how &lt;code&gt;do&lt;/code&gt; behaves between these two languages presents the first challenge when navigating JavaScript syntax as a Rubyist. The muscle memory we develop in Ruby can insert itself all too easily when we're writing in JavaScript without us even catching it when it happens. Luckily, there is a strategy we can use in Ruby to help minimize this growing pain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Curly Boys to the Rescue
&lt;/h3&gt;

&lt;p&gt;Some situations will still require you to employ the &lt;code&gt;do end&lt;/code&gt; syntax, such as embedding logic into &lt;code&gt;.erb&lt;/code&gt; files. But for the most part, the best way I have found to develop cross-language muscle memory is to pass blocks in Ruby using curly braces whenever possible.&lt;/p&gt;

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

&lt;p&gt;The added advantage to adopting this syntax is it leaves the possibility open for method chaining for those occasions where the rule of adhering to functional readability can be flexed to write logic as a single line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkwji503cd9naimt57bw0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkwji503cd9naimt57bw0.png" alt="There can be only one"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The case for using curly braces over &lt;code&gt;do end&lt;/code&gt; is strengthened by adding shorthand &lt;code&gt;key: value&lt;/code&gt; hash notation into the mix. When used in combination, these conventions of syntax apply to not only JSON but also CSS, creating a much more unified vocabulary of muscle memory overall.&lt;/p&gt;

&lt;p&gt;Perhaps the biggest difference when adjusting to JavaScript that ranks very near the least popular among Rubyists is the lack of native support for a utility resembling &lt;code&gt;binding.pry&lt;/code&gt; or &lt;code&gt;byebug&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;While there are solutions for this as mentioned in &lt;a href="https://medium.com/@kevinyckim33/javascripts-equivalent-of-ruby-s-binding-pry-2cc895582943" rel="noopener noreferrer"&gt;this article&lt;/a&gt; by &lt;a href="https://twitter.com/kevinyckim" rel="noopener noreferrer"&gt;Kevin Kim&lt;/a&gt; that are functionally synonymous with &lt;code&gt;pry&lt;/code&gt; in the context of JavaScript, problems that occur when developing front-end code tend to show up as nasty surprises in the browser the majority of the time.&lt;/p&gt;

&lt;p&gt;These situations do not necessarily imply that a given project will be created on NodeJS or that a given bug will crop up when testing in Chrome. This means that despite having utilities available under NodeJS or Chrome's developer tools, there will be times where these may not apply.&lt;/p&gt;

&lt;p&gt;Enter our hero: &lt;code&gt;console.log()&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  It's Better Than Bad, It's Good
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FpJag78s.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FpJag78s.jpg" alt="All devs love log"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The simplest explanation of how &lt;code&gt;console.log()&lt;/code&gt; works is that it is a utility function that prints a copy of its string argument to the console window of the browser. By interpolating variables into a string using template literals, an approximation of the same behavior as &lt;code&gt;pry&lt;/code&gt; can be achieved; albeit not as user friendly.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;It is important to note that depending on the scope of the function where&lt;/strong&gt; &lt;code&gt;console.log()&lt;/code&gt; &lt;strong&gt;is called, it may be impossible to render the output of the function in the console.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because of this, it is best to be aware of how to use &lt;code&gt;console.log()&lt;/code&gt;, but factor in the availability of debugging tools when deciding how to develop the front-end code of a project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Template Literals
&lt;/h3&gt;

&lt;p&gt;Thankfully, the learning curve for interpolating variables into strings is a lot more straight forward. The syntax is nearly identical, as shown here.&lt;/p&gt;

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

&lt;p&gt;Fun fact: the type of the "back tick" character is something called a "diacritic" and the name of the back tick character itself is a "grave". As a way of remembering what type of string quotation allows for interpolation in JavaScript, you can use the mental association:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Interpolating variables is 'gravely' important"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Inverted Instantiation
&lt;/h1&gt;

&lt;p&gt;One of the most difficult aspects of transitioning to JavaScript from Ruby is the muscle memory involved in instantiating a class. While we have always written a call to &lt;code&gt;Class.new&lt;/code&gt; in Ruby, now we have to come to terms with &lt;code&gt;new Class()&lt;/code&gt;. It may seem like a small difference, but it can have quite an impact on the flow of a project.&lt;/p&gt;

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

&lt;p&gt;Because the majority of the class instantiation I write in Ruby now occurs inside of Rails controllers, a strategy that I have found for standardizing between these two syntaxes is to completely abstract my &lt;code&gt;#new&lt;/code&gt; action into a &lt;code&gt;before_action&lt;/code&gt; helper method. This simultaneously declutters my code and allows me to mentally conceptualize these two situations as unique, evading crosstalk.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exhibitionism in ES6
&lt;/h1&gt;

&lt;p&gt;Now that we are taking how classes are instantiated into consideration, let's step back a moment and review how helper methods like &lt;code&gt;before_action&lt;/code&gt; are defined. According to Rails convention, these methods are defined below the &lt;code&gt;private&lt;/code&gt; bare word inside our controllers. What this means is that the helper methods are private to that controller instance when it is created during a server request. Things work very differently in JavaScript.&lt;/p&gt;

&lt;p&gt;As of this writing, all properties and methods of all class instances are effectively (and natively) public in JavaScript.&lt;/p&gt;

&lt;p&gt;Returning to the point that JavaScript implies how data types interact, this implied system of relationships also extends to function scope. By exploiting aspects of how function scope works in JavaScript, it is possible to approximate the same behavior as the &lt;code&gt;private&lt;/code&gt; bare word in Rails, but with a lot more work and high level understanding involved.&lt;/p&gt;

&lt;p&gt;Currently, the intricacies of available means of privatizing class properties and methods extends beyond the scope of my skillset and the topic is a very deep rabbit hole that exceeds the reach of this article. More information about this process can be found &lt;a href="https://gomakethings.com/public-vs.-private-functions-in-javascript/" rel="noopener noreferrer"&gt;here&lt;/a&gt; by &lt;a href="http://twitter.com/ChrisFerdinandi" rel="noopener noreferrer"&gt;Chris Ferdinandi&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That said, it is important to understand that unlike working in Ruby, acting upon data in JavaScript does not always act upon data that already exists, but rather can create data through the expectation that data exists.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One prime example is assigning a value to an object property that does not exist, thereby creating and appending it to the object in the process.&lt;/p&gt;

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

&lt;p&gt;This article is being published while the most recent standard of JavaScript is still ES6. However, the next iteration of the standard — currently referred to as ESNext — is anticipated for release some time in 2019 or soon after. With it will come native support for private class properties and methods that will remove the necessity of using closures to conceal class variables.&lt;/p&gt;

&lt;h1&gt;
  
  
  Let it Let
&lt;/h1&gt;

&lt;p&gt;Unfortunately there is one elephant of syntax difference in the room that is large enough no amount of workflow adjustments in either language can hide it. This elephant is the diverse ways in which the structure of statements and the use of bare words differ between these two languages.&lt;/p&gt;

&lt;p&gt;The purpose of this article is to provide tactics for reducing the impact of higher level differences when writing in JavaScript from a Rubyist's perspective.&lt;/p&gt;

&lt;p&gt;Due to the breadth of the information regarding exact syntactical differences you will encounter, I recommend reading &lt;a href="https://medium.com/learning-to-code/ruby-vs-javascript-a-quick-comparison-ebd3b63ebc49" rel="noopener noreferrer"&gt;this excellent article&lt;/a&gt; by &lt;a href="https://twitter.com/edzye101" rel="noopener noreferrer"&gt;Edozié Izegbu&lt;/a&gt; to better prepare for these inevitable sticking points.&lt;/p&gt;

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

&lt;p&gt;While my journey of learning to code is only just beginning, I hope that these strategies can help to guide or inspire you to begin standardizing how you approach writing in multiple languages.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ruby</category>
      <category>flatiron</category>
    </item>
  </channel>
</rss>
