<?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: Jacob Orshalick</title>
    <description>The latest articles on DEV Community by Jacob Orshalick (@jorshali).</description>
    <link>https://dev.to/jorshali</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%2F1013520%2F0fffdca2-1a96-4973-9895-6da724deaa64.jpeg</url>
      <title>DEV Community: Jacob Orshalick</title>
      <link>https://dev.to/jorshali</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jorshali"/>
    <language>en</language>
    <item>
      <title>LLM Development with JavaScript: Is that a thing?</title>
      <dc:creator>Jacob Orshalick</dc:creator>
      <pubDate>Thu, 07 Mar 2024 21:20:06 +0000</pubDate>
      <link>https://dev.to/jorshali/the-busy-javascript-developers-guide-to-generative-ai-4omo</link>
      <guid>https://dev.to/jorshali/the-busy-javascript-developers-guide-to-generative-ai-4omo</guid>
      <description>&lt;p&gt;This tutorial is a fast track to developing JavaScript apps that talk to LLM models. You'll have a REST service up and talking to an LLM in under 10 minutes.  Let the coding magic begin!&lt;/p&gt;




&lt;p&gt;This is part 1 from my free e-book:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fjorshali%2Fai-for-developers%2Fblob%2Fmain%2Fbusy_developers_guide_to_genai.pdf" rel="noopener noreferrer"&gt;The Busy Developers Guide to Generative AI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fex5kha4h8qpa4t67inrc.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%2Fex5kha4h8qpa4t67inrc.png" alt="Fig 1: The Busy Developers Guide to Gen AI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All source code is available on &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fjorshali%2Fai-for-developers" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;ChatGPT vaulted generative AI into mainstream culture. But, it's really just a user interface, powered by the true marvel that lies beneath - the large language model (LLM). &lt;/p&gt;

&lt;p&gt;More precisely, LLMs are very large deep learning models that are pre-trained on vast amounts of data. The keyword there is pre-trained. &lt;/p&gt;

&lt;p&gt;All we have to do to make use of these same models is send them a prompt telling it what we want. We can do that by calling the OpenAI APIs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdanmfblu2djwndjrrq4.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%2Ffdanmfblu2djwndjrrq4.png" alt="Fig 2: Your REST service can call the same APIs used by ChatGPT"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Install Node
&lt;/h2&gt;

&lt;p&gt;Download and install: &lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;https://nodejs.org&lt;/a&gt;. Verify the install in your terminal:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ % node -v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If the installation succeeded, the version will print.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Initialize your project
&lt;/h2&gt;

&lt;p&gt;Create a new directory for your project. Navigate to it in your terminal and run the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/ai-for-devs % npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This creates a new package.json file, initializing the project.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Node modules&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The node modules we'll be using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;express&lt;/strong&gt;: which makes server creation quick and easy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;langchain&lt;/strong&gt;: which provides a framework for building Apps with LLMs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;@langchain/openai&lt;/strong&gt;: which provides OpenAI integrations through their SDK&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cors&lt;/strong&gt;: Express middleware to enable CORS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the same terminal, run the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/ai-for-devs % npm install express langchain @langchain/openai cors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  4. Create the server file
&lt;/h2&gt;

&lt;p&gt;Create a file called &lt;code&gt;server.mjs&lt;/code&gt; in the project directory. Open it in a text editor and add the following lines of code:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from "express";
import { ChatOpenAI } from "@langchain/openai";
import cors from 'cors';

const app = express();

app.use(cors());

const chatModel = new ChatOpenAI({});

app.get('/', async (req, res) =&amp;gt; {
  const response = 
    await chatModel.invoke(
      "Can you simply say 'test'?");

  res.send(response.content);
});

app.listen(3000, () =&amp;gt; {
  console.log(`Server is running on port 3000`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  5. Create an OpenAI account
&lt;/h2&gt;

&lt;p&gt;Register here: &lt;a href="https://platform.openai.com" rel="noopener noreferrer"&gt;https://platform.openai.com&lt;/a&gt;.  Obtain an API key:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simply select 'API keys' in the upper left navigation&lt;/li&gt;
&lt;li&gt;Select '+ Create new secret key'&lt;/li&gt;
&lt;li&gt;Copy the key somewhere safe for now&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fks4erkz00g526kjtclqx.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%2Fks4erkz00g526kjtclqx.png" alt="Fig 3: The API keys in Open AI's interface"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  6. Set an environment variable
&lt;/h2&gt;

&lt;p&gt;In the same terminal, run the following command with your key value:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/ai-for-devs % export OPENAI_API_KEY=&amp;lt;YOUR_KEY_VALUE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Optionally&lt;/em&gt; add this command to your bash profile: &lt;code&gt;~/.zshrc&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Launch your server
&lt;/h2&gt;

&lt;p&gt;Back in the terminal, run the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/node-openai % node server.mjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Open your web browser and visit: &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll see the response from the OpenAI model: "test"&lt;/p&gt;

&lt;h2&gt;
  
  
  Congratulations!
&lt;/h2&gt;

&lt;p&gt;You've successfully built a functional REST service. Beyond its ability to prompt an AI and generate responses, it forms the foundation for the remainder of my free to download e-book:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jorshali/ai-for-developers/blob/main/busy_developers_guide_to_genai.pdf" rel="noopener noreferrer"&gt;The Busy Developer's Guide to Gen AI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Part 2, we'll explore the process of streaming longer responses so our users don't have to wait. Part 3 and part 4 will guide you through creating a complete RAG (Retrieval Augmented Generation) implementation.&lt;/p&gt;

&lt;p&gt;Download the book to learn more!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>beginners</category>
      <category>openai</category>
    </item>
    <item>
      <title>Becoming the developer every organization wants</title>
      <dc:creator>Jacob Orshalick</dc:creator>
      <pubDate>Fri, 10 Feb 2023 16:41:40 +0000</pubDate>
      <link>https://dev.to/jorshali/becoming-the-developer-every-organization-wants-33ff</link>
      <guid>https://dev.to/jorshali/becoming-the-developer-every-organization-wants-33ff</guid>
      <description>&lt;h4&gt;
  
  
  Are they looking for the best technical skills or something else?  The formula for the developer every organization wants.
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://jacoborshalick.me/posts/the-formula-for-the-developer-every-organization-wants" rel="noopener noreferrer"&gt;jacoborshalick.me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;When we think about what makes a great developer, technical skills are usually what come to mind.&lt;/p&gt;

&lt;p&gt;A great developer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;writes clean and elegant code&lt;/li&gt;
&lt;li&gt;architects and designs great solutions&lt;/li&gt;
&lt;li&gt;has a vast understanding of technologies&lt;/li&gt;
&lt;li&gt;is always learning and staying on top of the latest trends&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may throw in some specific coding practices like TDD, Continuous Delivery, and others, but the focus tends to be on their technical ability.&lt;/p&gt;

&lt;p&gt;Technical skills may get you hired, but the ability to operate efficiently within a team is what will get you promoted. Technical skills are invidually focused and software development is a team activity.&lt;/p&gt;

&lt;h3&gt;
  
  
  The formula for a great developer
&lt;/h3&gt;

&lt;p&gt;Every organization wants a developer with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Technical skills + business acumen + people skills&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the combination of skills that leads to long-term success. You shouldn't stop leveling up your technical skills, but you can't neglect the other parts of the equation.&lt;/p&gt;

&lt;p&gt;The key to building both business accumen and people skills is learning to communicate.  Developers are often great at technical tasks, but bad communicators.  But, this is a skill that can be learned.&lt;/p&gt;

&lt;p&gt;So you're already leveling up your technical skills but you need to build your communication skills.  What should you do?&lt;/p&gt;

&lt;h2&gt;
  
  
  Start by posting what you're learning
&lt;/h2&gt;

&lt;p&gt;You can start by posting to LinkedIn, dev.to, Medium, or even better, &lt;a href="https://jacoborshalick.me/posts/nextjs-and-aws-amplify-host-a-personal-blog-in-under-30-minutes" rel="noopener noreferrer"&gt;your own portfolio site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It will help you solidify your knowledge and will improve your communication skills along the way. Being able to explain yourself clearly and concisely will help you in conversations with product owners, users, clients, interviewers, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow up by presenting
&lt;/h2&gt;

&lt;p&gt;Presenting not only builds notoriety, it builds your confidence. The best developers are able to present ideas to a group effectively.  You can start by presenting to your team, a local user group, and even progress to conferences.&lt;/p&gt;

&lt;p&gt;Standing in front of your peers and presenting anything, even a topic you are intimately familiar with can certainly rattle your nerves. Remember, the nerves will pass and everyone in the crowd is rooting for you. Everyone wants to learn something from the presenter. Why else would they have shown up!&lt;/p&gt;

&lt;p&gt;Presenting also requires you to dive deep into a topic. In order to teach something, you have to truly understand the topic yourself. Presenting provides similar benefits to writing and can help you become more of a “people person” at the same time.&lt;/p&gt;

&lt;h3&gt;
  
  
  So remember...
&lt;/h3&gt;

&lt;p&gt;Technical skills are important, but being able to communicate is just as important.  Start posting and presenting what you're learning to build those communication skills today.&lt;/p&gt;

&lt;p&gt;What do you think?  Leave it in the comments.&lt;/p&gt;




&lt;p&gt;Follow me for more tips.  You can also &lt;a href="https://jacoborshalick.me" rel="noopener noreferrer"&gt;subscribe to my &lt;strong&gt;Friday Developer Focus&lt;/strong&gt; newsletter&lt;/a&gt; to get tips like these in your inbox every Friday.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Configure a custom domain for your AWS Amplify App</title>
      <dc:creator>Jacob Orshalick</dc:creator>
      <pubDate>Mon, 30 Jan 2023 16:27:07 +0000</pubDate>
      <link>https://dev.to/jorshali/configure-a-custom-domain-for-your-aws-amplify-app-54f1</link>
      <guid>https://dev.to/jorshali/configure-a-custom-domain-for-your-aws-amplify-app-54f1</guid>
      <description>&lt;h4&gt;
  
  
  A custom domain lets you share your AWS Amplify App with the world.  This tutorial will show you how to do just that.
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://jacoborshalick.me/posts/configure-a-custom-domain-for-your-aws-amplify-app"&gt;jacoborshalick.me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;You've created an AWS Amplify App and you're ready to share it with the world.  You need a custom domain.  AWS Amplify and Route 53 make it easy and this guide will step you through it!&lt;/p&gt;

&lt;p&gt;If you want your own portfolio site, start with my &lt;a href="https://dev.to/jorshali/host-a-personal-blog-with-nextjs-and-aws-in-under-30-minutes-3431"&gt;tutorial to setup your portfolio site in AWS Amplify under 30 minutes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you get started
&lt;/h2&gt;

&lt;p&gt;You'll need a few things. You may already have some of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com"&gt;Setup an AWS Account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Deployed &lt;a href="https://aws.amazon.com/amplify/"&gt;AWS Amplify&lt;/a&gt; App&lt;/li&gt;
&lt;li&gt;&lt;a href="https://domains.google"&gt;Custom domain name&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tutorial will use Google Domains as the example, but each domain provider has the same custom name server capability.  Simply run a search for your provider.&lt;/p&gt;

&lt;p&gt;If you have been following along with my &lt;a href="https://dev.to/jorshali/host-a-personal-blog-with-nextjs-and-aws-in-under-30-minutes-3431"&gt;tutorial to build a portfolio site&lt;/a&gt;, all you will need is your custom domain.  I would suggest your name (dot) me.  As an example, my custom domain name is:  &lt;a href="https://jacoborshalick.me"&gt;https://jacoborshalick.me&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If that's not available, consider adding your middle name or initial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup your custom domain in Route 53
&lt;/h2&gt;

&lt;p&gt;Login to the AWS Console.  Once logged in search for &lt;strong&gt;Route 53&lt;/strong&gt; and open it.  When you get to the Route 53 Dashboard, select &lt;strong&gt;Hosted Zones&lt;/strong&gt; in the left column.&lt;/p&gt;

&lt;p&gt;This will display any existing hosted zones, or none if you haven't created any yet.  Here you want to select the &lt;strong&gt;Create hosted zone&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hbbawaqevrysfabv677.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hbbawaqevrysfabv677.png" alt="Route 53 hosted zones" width="800" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now enter your domain name and a description for your site.  Once you have entered this information, click &lt;strong&gt;Create hosted zone&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5uaanjy81anljqylgmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5uaanjy81anljqylgmd.png" alt="Create a hosted zone" width="800" height="961"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will now see your domain name listed in the &lt;strong&gt;Hosted zones&lt;/strong&gt;.  Click on your domain name.  Here you will see an &lt;strong&gt;NS&lt;/strong&gt; record.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flo1l1zalr3uyi0e0jtnk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flo1l1zalr3uyi0e0jtnk.png" alt="Name server records" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are the name servers for DNS routing.  Just copy the 4 name servers somewhere so you can use them when we configure your domain provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup AWS Amplify with your custom domain
&lt;/h2&gt;

&lt;p&gt;In the AWS Console, search for AWS Amplify and access it.  Here you will select your AWS Amplify App first.&lt;/p&gt;

&lt;p&gt;Once selected, click on the &lt;strong&gt;Domain Management&lt;/strong&gt; in the left navigation panel.  In the &lt;strong&gt;Domain Management&lt;/strong&gt; interface, click the &lt;strong&gt;Add Domain&lt;/strong&gt; button on the upper left.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq2l30cawm8u81kskuxa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq2l30cawm8u81kskuxa.png" alt="Add a custom domain" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you should see the domain you just configured in Route 53 when you select the dropdown.  Select it and click &lt;strong&gt;Configure Domain&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzdayl6ph1n6d5y0hbqt9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzdayl6ph1n6d5y0hbqt9.png" alt="Configure your domain" width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uncheck "Setup redirect from..." and click the &lt;strong&gt;Save&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;At this point, AWS Amplify will start to configure SSL for your site.  This will take some time.  Wait until the &lt;strong&gt;Domain Activation&lt;/strong&gt; step is complete before moving on to the next step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxg9jbl27khb4o2dwhcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxg9jbl27khb4o2dwhcw.png" alt="AWS Amplify configuring the domain" width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure the Custom name servers on your domain provider
&lt;/h2&gt;

&lt;p&gt;You now need to point your domain provider to the &lt;strong&gt;Custom name servers&lt;/strong&gt; you copied in the previous step.  You copied them somehwere right?  If not, you can always go back to Route 53 and find them.  For simplicity, I will use &lt;a href="https://domains.google.com"&gt;Google Domains&lt;/a&gt; as the example here.&lt;/p&gt;

&lt;p&gt;In Google Domains, you would select your custom domain.  Once selected, you would then select &lt;strong&gt;DNS&lt;/strong&gt; in the left navigation.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Default name servers&lt;/strong&gt; will be configured to start with.  Select the &lt;strong&gt;Custom name servers&lt;/strong&gt; tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5gcnja7scjb4bcn9rkt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5gcnja7scjb4bcn9rkt.png" alt="Using custom name servers in Google Domains" width="800" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will see a warning that &lt;em&gt;Your domain isn't using these settings&lt;/em&gt;.  Select &lt;strong&gt;Switch to these settings&lt;/strong&gt; and add all 4 custom name servers you copied into the &lt;strong&gt;Name server&lt;/strong&gt; input list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;  Make sure there is not an extra period at the end of any of your name server hostnames.&lt;/p&gt;

&lt;p&gt;Once you have copied them in, select &lt;strong&gt;Save&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Access your AWS Amplify App through your custom domain
&lt;/h2&gt;

&lt;p&gt;That's it!  You will now be able to access your AWS Amplify App from your custom domain name.&lt;/p&gt;

&lt;p&gt;Be aware that while the DNS replication will likely happen very fast, it could take some time.  Give the replication at least a couple of hours before you assume it's not working.&lt;/p&gt;




&lt;p&gt;Subscribe to my newsletter to get posts straight to your inbox:  &lt;a href="https://jacoborshalick.me"&gt;https://jacoborshalick.me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>serverless</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Start tracking subscribers in AWS in under 30 minutes</title>
      <dc:creator>Jacob Orshalick</dc:creator>
      <pubDate>Mon, 30 Jan 2023 16:13:28 +0000</pubDate>
      <link>https://dev.to/jorshali/start-tracking-subscribers-in-aws-in-under-30-minutes-mgl</link>
      <guid>https://dev.to/jorshali/start-tracking-subscribers-in-aws-in-under-30-minutes-mgl</guid>
      <description>&lt;h4&gt;
  
  
  Building an audience is key to growing your brand.  You need a way to keep them informed!  This tutorial will have you tracking your subscribers in AWS in no time.
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://jacoborshalick.me/posts/build-a-subscriber-rest-api-on-aws-in-under-30-minutes"&gt;jacoborshalick.me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;We've all said it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want to track my site subscribers&lt;/li&gt;
&lt;li&gt;I want to try out serverless computing on AWS&lt;/li&gt;
&lt;li&gt;I want to learn about IoC (Infrastructure as Code)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How can I do it all?&lt;/p&gt;

&lt;p&gt;Here's your chance.  Finally, a tutorial where you learn while actually building something useful.&lt;/p&gt;




&lt;p&gt;This tutorial will have you tracking your subscribers in AWS in no time.  By the end of this article, you'll have a REST API in AWS that stores subscriber records in a &lt;a href="https://aws.amazon.com/dynamodb/"&gt;DynamoDB&lt;/a&gt; table.  You'll also automate the setup of all AWS infrastructure using &lt;a href="https://aws.amazon.com/cloudformation/"&gt;CloudFormation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Need proof?  My &lt;a href="https://jacoborshalick.me"&gt;portfolio site&lt;/a&gt; uses the APIs shown here to track subscribers.&lt;/p&gt;

&lt;p&gt;If you want your own portfolio site, start with my &lt;a href="https://dev.to/jorshali/host-a-personal-blog-with-nextjs-and-aws-in-under-30-minutes-3431"&gt;tutorial to setup your portfolio site in under 30 minutes&lt;/a&gt;.  If you've already setup the portfolio site, I'll show you how to plug in your subcriber API at the end.&lt;/p&gt;

&lt;p&gt;So let's get your subscriber API built!&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you Get Started
&lt;/h2&gt;

&lt;p&gt;You'll need a few things. You may already have some of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com"&gt;Setup an AWS Account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org"&gt;Install Node.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html"&gt;Install the AWS CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html"&gt;Install the SAM CLI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tutorial assumes you are comfortable working in the terminal and using Git. Outside of that, the tutorial will walk you through what you need to know.&lt;/p&gt;

&lt;h2&gt;
  
  
  About the AWS subscribers project
&lt;/h2&gt;

&lt;p&gt;The complete source for the service you'll be setting up can be found on GitHub: &lt;a href="https://github.com/jorshali/aws-subscribers"&gt;aws-subscribers&lt;/a&gt;.  The project creates a REST API hosted on AWS that will support 2 simple requests:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;POST /subscriber&lt;/code&gt; &lt;em&gt;(creates a new subscriber)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  email: "info@focus.dev"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;PUT /subscriber/info@focus.dev&lt;/code&gt; &lt;em&gt;(updates subscriber information allowing unsubscribe)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  email:  "info@focus.dev",`
  unsubscribeAll:  true`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The components of the REST API that will be generated by the project can be represented in AWS by the following diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80g4nqil1tcju0emrdut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80g4nqil1tcju0emrdut.png" alt="AWS representation of the REST API that will be generated by CloudFormation" width="800" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This project serves as a great base for any functionality you may want to add.  Here's a quick summary of what the project provides you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated infrastructure and deployment using &lt;a href="https://aws.amazon.com/serverless/sam/"&gt;AWS SAM&lt;/a&gt; and &lt;a href="https://aws.amazon.com/cloudformation/"&gt;CloudFormation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Standardized-project structure&lt;/li&gt;
&lt;li&gt;Lambda function coded in TypeScript&lt;/li&gt;
&lt;li&gt;NoSQL database access using &lt;a href="https://aws.amazon.com/dynamodb/"&gt;DynamoDB&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;REST API exposed through &lt;a href="https://aws.amazon.com/api-gateway/"&gt;API Gateway&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the Project
&lt;/h2&gt;

&lt;p&gt;Once you have installed the necessary prerequisites you can setup the project with the following terminal commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir &amp;lt;project-directory&amp;gt;
$ cd &amp;lt;project-directory&amp;gt;
$ sam init --location git@github.com:jorshali/aws-subscribers.git
$ npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The starter project will now be available in the project directory you specified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create an AWS Profile
&lt;/h2&gt;

&lt;p&gt;This is the most involved part of the tutorial, but it's a one-time process.&lt;/p&gt;

&lt;p&gt;The steps below will guide you through the creation of a user with &lt;strong&gt;Administrator&lt;/strong&gt; rights and a local AWS profile for that user.  This will allow you to execute the remote commands that fully automate the setup of necessary infrastructure and code deployment.&lt;/p&gt;

&lt;p&gt;We'll start by logging into the AWS Console.  You will want to search for and select the &lt;strong&gt;IAM&lt;/strong&gt; service.  Once in the IAM interface, select &lt;strong&gt;Users&lt;/strong&gt; in the left panel.  Here you will want to select &lt;strong&gt;Add User&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You will be presented with the &lt;strong&gt;Create user&lt;/strong&gt; steps.  Start by providing a valid user name and select &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgfw5chvithfb32prsn8o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgfw5chvithfb32prsn8o.png" alt="Define the username" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the next step, select the &lt;strong&gt;Add user to group&lt;/strong&gt; option and click the &lt;strong&gt;Create Group&lt;/strong&gt; button.  Search for &lt;strong&gt;AdministratorAccess&lt;/strong&gt; and select the check box to the left.  Name the group &lt;strong&gt;Administrator&lt;/strong&gt;.  Scroll to the bottom and select &lt;strong&gt;Create user group&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftft6scuqtf58a7u9f347.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftft6scuqtf58a7u9f347.png" alt="Apply AdministratorAccess to your group" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will now be taken back to the user permission options, but you will see your newly created &lt;strong&gt;Administrator&lt;/strong&gt; group.  Check the box to the left of your newly created group and select &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1s6u2cix3rdrqh9c7wx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1s6u2cix3rdrqh9c7wx.png" alt="Make your new user an Administrator" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will take you to the &lt;strong&gt;Review and Create&lt;/strong&gt; screen.  Simply select &lt;strong&gt;Create User&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcvtbhkmmebl2egf5axk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcvtbhkmmebl2egf5axk.png" alt="Review and create the user" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have our user, we need to generate an access key that will be used locally for running our commands.  Back on the &lt;strong&gt;Users&lt;/strong&gt; screen, select the user you just created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgkos9g2numai5zo3n3j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgkos9g2numai5zo3n3j.png" alt="Select the user you just created" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the &lt;strong&gt;Security Credentials&lt;/strong&gt; tab and scroll down to the &lt;strong&gt;Access Keys&lt;/strong&gt; section.  Here you will want to select the &lt;strong&gt;Create access key&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9sj1f4i9v9mojszdzm43.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9sj1f4i9v9mojszdzm43.png" alt="Select the security credentials tab" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When presented with Step 1, select the &lt;strong&gt;Command Line Interface (CLI)&lt;/strong&gt; option.  Select the "I Understand..." checkbox and select &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqoin8aa3u7fherk1ojdu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqoin8aa3u7fherk1ojdu.png" alt="Create an access key for the user" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On Step 2, there's no need to create any description tags so simply select &lt;strong&gt;Create Access Key&lt;/strong&gt;.  You will now see the following with your &lt;strong&gt;Access Key&lt;/strong&gt; and &lt;strong&gt;Secret Access Key&lt;/strong&gt;.  Leave this page open for the next step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flhjzq3mgx5x8nrhyhmiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flhjzq3mgx5x8nrhyhmiw.png" alt="Specify Command Line Interface (CLI) access" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now in your terminal, execute 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;aws configure --profile aws-subscribers-prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will ask you for your &lt;strong&gt;AWS Access Key ID&lt;/strong&gt; and &lt;strong&gt;AWS Secret Access Key&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Open back up  the page you left open so you can copy and paste those values.  Complete the questions 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;AWS Access Key ID [None]: &amp;lt;copy and paste the Access Key ID here&amp;gt;
AWS Secret Access Key [None]: &amp;lt;copy and paste the Secret Access Key here&amp;gt;
Default region name [None]: us-west-2
Default output format [None]: json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it!  The hard part is over.  Now let's get this service deployed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Project
&lt;/h2&gt;

&lt;p&gt;We have to start by telling the AWS CLI that we want to use the profile we just created to deploy the project. For example, in your terminal on a Mac:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ export AWS_PROFILE=aws-subscribers-prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now make sure you are in your project directory in your terminal.  Once there, we can build the project with AWS SAM:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:  The beta-features flag is necessary since we are using TypeScript.&lt;/p&gt;

&lt;p&gt;Once the build completes, it's time to deploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying the Project to AWS
&lt;/h2&gt;

&lt;p&gt;You can now deploy to your account using the profile you selected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sam deploy --guided
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While being guided through the deployment, the defaults are generally recommended.  There are only a couple of exceptions. You can customize the Stack Name to something specific to your project.  When presented with the following prompt, answer &lt;strong&gt;y&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SubscriberFunction may not have authorization defined, Is this okay? [y/N]: y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the deployment completes, it will print out 3 results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6r1wd5ispk0z1t5uh0ey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6r1wd5ispk0z1t5uh0ey.png" alt="Results from the SAM deployment" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hang onto the &lt;strong&gt;WebEndpoint&lt;/strong&gt; value as this is the URL you will be using to call your Subscriber API.&lt;/p&gt;

&lt;p&gt;You can now login and browse your AWS Console to see the various components that were installed. For example, you will find the &lt;code&gt;subscriberFunction&lt;/code&gt; within the Lambda console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx0p53e18r5pv2fts3tj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx0p53e18r5pv2fts3tj4.png" alt="Lambda console with subscriberFunction" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring your personal site (optional)
&lt;/h2&gt;

&lt;p&gt;If you followed my &lt;a href="https://jacoborshalick.me/posts/nextjs-and-aws-amplify-host-a-personal-blog-in-under-30-minutes"&gt;tutorial to setup a portfolio site&lt;/a&gt; you can start using your API immediately.  In your &lt;code&gt;personal-site-starter&lt;/code&gt; project, open the file &lt;code&gt;src/constants.ts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this file, find the constant &lt;code&gt;SUBSCRIBER_REQUEST_URL&lt;/code&gt; and replace the value with the &lt;strong&gt;WebEndpoint&lt;/strong&gt; value that was output by the SAM deployment.&lt;/p&gt;

&lt;p&gt;Save the file and open a terminal in your &lt;code&gt;personal-site-starter&lt;/code&gt; directory.  Start your local server by running 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;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open your site in your browser at &lt;a href="https://localhost:3000"&gt;https://localhost:3000&lt;/a&gt;.  As soon as the landing page opens, put in your email address and click &lt;strong&gt;Subscribe Now&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now open your AWS console and search for &lt;strong&gt;DynamoDB&lt;/strong&gt;.  Open it and in the left navigation select &lt;strong&gt;Tables &amp;gt; Explore Items&lt;/strong&gt;.  Under &lt;strong&gt;Tables&lt;/strong&gt; select &lt;strong&gt;SUBSCRIBER&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fww5920p4t05f9nv54dm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fww5920p4t05f9nv54dm2.png" alt="Entries in SUBSCRIBER table in DynamoDB" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you will see an entry for your email address!&lt;/p&gt;

&lt;p&gt;If everything worked, simply commit these changes and push them to your Git provider.  AWS Amplify will automatically redeploy your site with the subscriber API configured.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the Service Locally (optional)
&lt;/h2&gt;

&lt;p&gt;You can test your service locally using Docker. You can &lt;a href="https://docs.docker.com/get-docker/"&gt;install Docker here&lt;/a&gt;. Once Docker is installed, you can start the project locally with 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;$ sam build
$ sam local start-api --port 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this is running you can test the API at: &lt;code&gt;http://127.0.0.1:8080/subscriber&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you are testing the &lt;code&gt;personal-site-starter&lt;/code&gt; locally, simply change the value of &lt;code&gt;SUBSCRIBER_REQUEST_URL&lt;/code&gt; in &lt;code&gt;src/constants.ts&lt;/code&gt; to: &lt;code&gt;http://127.0.0.1:8080&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Organization
&lt;/h2&gt;

&lt;p&gt;This guide is purely focused on getting the Subscriber API up-and-running on AWS quickly. In an upcoming series, I will walk you through more project specifics.&lt;/p&gt;

&lt;p&gt;If you want to get started customizing the project right away, here's a quick rundown of the project structure. You can browse this code from the project root in an IDE like &lt;a href="https://code.visualstudio.com"&gt;VS Code&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;template.yml&lt;/code&gt;: the CloudFormation template that defines the service requirements. If you want to customize the REST API URL, DynamoDB table definitions, etc, this is the place to do it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;subscriber&lt;/code&gt;: contains the code for the &lt;code&gt;subscriberFunction&lt;/code&gt;. This is where you will find the &lt;code&gt;package.json&lt;/code&gt; dependency definitions, TypeScript files, and general configuration.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;subscriber/index.ts&lt;/code&gt;: the TypeScript function that handles all &lt;code&gt;/subscriber&lt;/code&gt; requests. You can use this to experiment with your own functionality.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Your service is live on AWS
&lt;/h2&gt;

&lt;p&gt;That's it!  You now have an API for capturing subscribers and allowing them to unsubscribe.&lt;/p&gt;

&lt;p&gt;If you run into any issues along the way, feel free to ask questions or post issues at:  &lt;a href="https://github.com/jorshali/aws-subscribers"&gt;aws-subscribers&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;In the next post I'll be showing you how to register a domain and connect it through &lt;a href="https://aws.amazon.com/route53/"&gt;Route 53&lt;/a&gt; in AWS so you can share your site with the world.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>typescript</category>
      <category>cloud</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Host a personal blog with Next.js and AWS in under 30 minutes</title>
      <dc:creator>Jacob Orshalick</dc:creator>
      <pubDate>Thu, 26 Jan 2023 15:25:41 +0000</pubDate>
      <link>https://dev.to/jorshali/host-a-personal-blog-with-nextjs-and-aws-in-under-30-minutes-3431</link>
      <guid>https://dev.to/jorshali/host-a-personal-blog-with-nextjs-and-aws-in-under-30-minutes-3431</guid>
      <description>&lt;h3&gt;
  
  
  A tutorial where you can learn how to use Next.js with AWS while actually building something useful.
&lt;/h3&gt;

&lt;p&gt;We've all said it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want to setup a portfolio site&lt;/li&gt;
&lt;li&gt;I want to learn Next.js&lt;/li&gt;
&lt;li&gt;I want to try out AWS Amplify&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How can I do it all?&lt;/p&gt;

&lt;p&gt;Here's your chance.  Finally, a tutorial where you learn while actually building something useful.&lt;/p&gt;




&lt;p&gt;By the end of this article, you'll have your own personal blog, built with Next.js, and hosted on AWS.  As an encore, I'll even show you how to setup your own domain and a subscriber service so you can share it with the world.  It's never been easier to start some self-promotion.&lt;/p&gt;

&lt;p&gt;Need proof?  The article your reading was originally published to &lt;a href="https://jacoborshalick.me/posts/nextjs-and-aws-amplify-host-a-personal-blog-in-under-30-minutes" rel="noopener noreferrer"&gt;jacoborshalick.me&lt;/a&gt;.  That site and article were created using the steps shown here.&lt;/p&gt;

&lt;p&gt;So let's get your personal blog built!&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you get started
&lt;/h2&gt;

&lt;p&gt;You'll need a few things.  You may already have some of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com" rel="noopener noreferrer"&gt;Setup an AWS Account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;Install Node.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nextjs.org" rel="noopener noreferrer"&gt;Install Next.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Supported Git provider (e.g. &lt;a href="https://github.com" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tutorial assumes you have some JavaScript development experience.  It also assumes you are comfortable working in the terminal and using Git.  Outside of that, the tutorial will walk you through what you need to know.&lt;/p&gt;

&lt;h2&gt;
  
  
  About the personal site starter
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/jorshali/personal-site-starter" rel="noopener noreferrer"&gt;personal site starter&lt;/a&gt; creates a site that includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;professional information&lt;/li&gt;
&lt;li&gt;links to your online presence&lt;/li&gt;
&lt;li&gt;ability to subscribe&lt;/li&gt;
&lt;li&gt;blog posts&lt;/li&gt;
&lt;li&gt;responsiveness for mobile&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see an example at &lt;a href="https://jacoborshalick.me" rel="noopener noreferrer"&gt;https://jacoborshalick.me&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The application was built with &lt;a href="https://nextjs.org" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; and &lt;a href="https://tailwindcss.com" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt;.  The starter is a custom template inspired by the following projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/vercel/next.js/tree/canary/examples/blog-starter" rel="noopener noreferrer"&gt;blog-starter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ixartz/Next-JS-Landing-Page-Starter-Template" rel="noopener noreferrer"&gt;Next-JS-Landing-Page-Starter-Template&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieve the personal site starter
&lt;/h2&gt;

&lt;p&gt;Start by running &lt;a href="https://github.com/vercel/next.js/tree/canary/packages/create-next-app" rel="noopener noreferrer"&gt;&lt;code&gt;create-next-app&lt;/code&gt;&lt;/a&gt; with &lt;a href="https://docs.npmjs.com/cli/init" rel="noopener noreferrer"&gt;npm&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app --example https://github.com/jorshali/personal-site-starter personal-site-starter-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this completes, simply run:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now your personal site starter should be up and running on &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Customize the project
&lt;/h2&gt;

&lt;p&gt;You don't want my face and name on your blog.  Let's fix that.  Open the following file in your favorite editor:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/lib/constants.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here's how the constants modify the landing page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fr1vvwmf5k5z37mij81a7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fr1vvwmf5k5z37mij81a7.png" alt="Site constants for landing page" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;About Me&lt;/strong&gt; section can be customized with the following constants:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ft3i55bo0p6kpe2p475hd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ft3i55bo0p6kpe2p475hd.png" alt="Site constants for About Me section" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And finally, here's how the constants modify the footer:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fiv7afy513h78g3ban1cx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fiv7afy513h78g3ban1cx.png" alt="Site constants for articles and footer" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's see how the new blog posts can be added in the &lt;code&gt;_posts&lt;/code&gt; directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding blog posts
&lt;/h2&gt;

&lt;p&gt;All blog posts are stored in &lt;code&gt;/_posts&lt;/code&gt; as Markdown files.  If you're unfamiliar with the Markdown format you can &lt;a href="https://www.markdownguide.org/basic-syntax/" rel="noopener noreferrer"&gt;learn about it here&lt;/a&gt;.  The Markdown is converted to HTML and displayed to the page.&lt;/p&gt;

&lt;p&gt;The metadata of every post is handled by &lt;a href="https://github.com/jonschlinkert/gray-matter" rel="noopener noreferrer"&gt;&lt;code&gt;gray-matter&lt;/code&gt;&lt;/a&gt; and also sent in props to the page.&lt;br&gt;&lt;br&gt;
As an example, &lt;a href="https://github.com/jorshali/personal-site-starter/blob/main/_posts/nextjs-and-aws-amplify-host-a-personal-blog-in-under-30-minutes.md?plain=1" rel="noopener noreferrer"&gt;here is the markdown&lt;/a&gt; (with metdata) for the post your reading now.&lt;/p&gt;

&lt;p&gt;You'll see examples in the starter, but you should define the following at the top of every markdown file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
title: 'My new blog post'
excerpt: 'This is the latest technology I have been learning'
coverImage: '/assets/blog/my-new-blog-post/image.jpg'
coverImageAttribution: 'Photo by John Doe on Unsplash'
date: '2023-01-20T07:00:00.000Z'
ogImage:
  url: '/assets/blog/my-new-blog-post/image.jpg'
---
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a Markdown file is added, simply reload the landing page to see your new post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commit your project to a public Git repository
&lt;/h2&gt;

&lt;p&gt;Commit your code to Git, then push your repository to the provider of your choice.  Amplify supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://about.gitlab.com" rel="noopener noreferrer"&gt;GitLab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bitbucket.org" rel="noopener noreferrer"&gt;Bitbucket&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/codecommit/" rel="noopener noreferrer"&gt;AWS CodeCommit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Now let's deploy to AWS Amplify
&lt;/h2&gt;

&lt;p&gt;Open the AWS Console, search for AWS Amplify, and open it.  If you have not created an Amplify app before, simply scroll to the bottom of the page and select: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amplify Hosting&lt;br&gt;
&amp;gt; Host your web app &amp;gt; Get started&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have created an app before, select:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New app &amp;gt; Host web app&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now choose your Git repository provider and select &lt;strong&gt;Continue&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F0optr9kxt37g8qf1k49i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F0optr9kxt37g8qf1k49i.png" alt="Choose your Git repository provider" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For most Git providers, you will be prompted to allow Amplify Hosting access to your repositories.  Once you authorize access, choose the repository for the starter app and select &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftqg3clfti5jnuwrevaax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftqg3clfti5jnuwrevaax.png" alt="Choose your Git repository" width="800" height="574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Amplify will automatically detect the correct build settings.  Simply select &lt;strong&gt;Next&lt;/strong&gt; to accept the default settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fcm0j1sdtxr7qm4bald3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fcm0j1sdtxr7qm4bald3i.png" alt="Accept the default build settings" width="800" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you reach the Review page, simply select &lt;strong&gt;Save and Deploy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fptjfio4exo8unuu6tujp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fptjfio4exo8unuu6tujp.png" alt="Review the settings and deploy" width="800" height="572"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, Amplify will build the project and deploy it. Expect to wait about 2–3 minutes for the build to complete.  You can monitor progress in the Amplify console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fddl6ovj8ybz1kkdpum78.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fddl6ovj8ybz1kkdpum78.png" alt="Monitor the build progress" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Any change to the branch you selected during setup will now result in a new build and deployment.  You can always return to the Amplify console to see the progress of a build or view the logs if a build fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  View your site live on AWS
&lt;/h2&gt;

&lt;p&gt;That's it!  Your professional site is now live.  You can access your site from the &lt;strong&gt;Domain&lt;/strong&gt; link in the project build details.&lt;/p&gt;

&lt;p&gt;If you run into any issues along the way, feel free to ask questions or post issues at:  &lt;a href="https://github.com/jorshali/personal-site-starter" rel="noopener noreferrer"&gt;personal-site-starter&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;In the following posts, I'll show you how to track subscribers in AWS and how to setup a custom domain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/jorshali/start-tracking-subscribers-in-aws-in-under-30-minutes-mgl"&gt;Start tracking your subscribers in AWS in under 30 minutes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/jorshali/configure-a-custom-domain-for-your-aws-amplify-app-54f1"&gt;Configure a custom domain for your AWS Amplify App&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Setting up subscribers is optional.  If you aren't ready for that just yet, you can disable subscribers in &lt;code&gt;src/lib/constants.ts&lt;/code&gt;.  Simply set &lt;code&gt;SUBSCRIBE_ENABLED&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can now register a custom domain and connect it through &lt;a href="https://aws.amazon.com/route53/" rel="noopener noreferrer"&gt;Route 53&lt;/a&gt; in AWS.  That way you can share your new portfolio site with the world.&lt;/p&gt;




&lt;p&gt;Subscribe to my newsletter to get posts straight to your inbox:  &lt;a href="https://jacoborshalick.me" rel="noopener noreferrer"&gt;https://jacoborshalick.me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>How to 2x your Developer Salary in a Year</title>
      <dc:creator>Jacob Orshalick</dc:creator>
      <pubDate>Tue, 24 Jan 2023 17:03:27 +0000</pubDate>
      <link>https://dev.to/jorshali/how-to-2x-your-developer-salary-in-a-year-5bon</link>
      <guid>https://dev.to/jorshali/how-to-2x-your-developer-salary-in-a-year-5bon</guid>
      <description>&lt;h4&gt;
  
  
  Throw in better work-life balance, the ability to choose what projects you work on, and where you work from. Learn how I took control of my career by independent consulting.
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://jacoborshalick.me/posts/2x-your-developer-salary-this-year" rel="noopener noreferrer"&gt;jacoborshalick.me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;As a full-time software developer you can make more by contracting. According to GlassDoor, the average software developer salary is $101,611. You may make more, maybe less. In a great year, you may get a raise of 10%, but a 2-3% cost of living increase is more typical.&lt;/p&gt;

&lt;p&gt;I've been an independent consultant for 15 years. Once you become an independent, the sky is the limit for your salary, but I started off doubling my salary in a single year by becoming a contractor. As you grow your list of clients and your expertise, you can demand higher rates, take out the middle man (placement firms), and even start placing your own sub-contractors.&lt;/p&gt;

&lt;p&gt;Before getting started, here's what you need to know about contracting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;These roles pay better than full-time because the employer is shifting risk to the contractor&lt;/li&gt;
&lt;li&gt;The roles are limited to a specific length of time (e.g. 6 month term) but can be extended&lt;/li&gt;
&lt;li&gt;These are usually not learn on the job roles, you’re expected to hit the ground running&lt;/li&gt;
&lt;li&gt;You may have different tax considerations and have to cover your own health insurance (based on country)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here are the list of steps I followed to get my career as an independent started along with some valuable lessons learned along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Build an emergency fund
&lt;/h2&gt;

&lt;p&gt;I recommend doing this before you start. It's also my number 1 recommendation in &lt;a href="https://medium.com/gitconnected/weathering-uncertainty-as-a-software-pro-141305ffabce" rel="noopener noreferrer"&gt;Weathering Uncertainty as a Software Pro&lt;/a&gt;. An emergency fund is recommended by most of the budget gurus out there so this should come as no surprise. That said, as a consultant, I try to extend this beyond the standard recommendation of 3 months of salary.&lt;/p&gt;

&lt;p&gt;Being a bit more conservative than most, I feel that a full 9 months of salary prepares you for the worst. The last thing you want to do is be forced to take an opportunity you don't want because you weren't prepared.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Start your own company
&lt;/h2&gt;

&lt;p&gt;It's easy and low cost to start a company. Having your own company makes you more reputable and gives you more flexibility when negotiating contract arrangements. If you start off sub-contracting through a placement firm, you can work in what's called a corp-to-corp arrangement to demand a higher rate.&lt;/p&gt;

&lt;p&gt;This is going to vary by country, but in a corp-to-corp arrangement in the United States you must pay your share of self-employment tax. You will also need to cover your own health insurance. Standard financial disclaimer, I’m not a CPA and you should consult with a tax professional for true tax advice.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Choose a technology niche
&lt;/h2&gt;

&lt;p&gt;Do your research! Target a technology that is in demand, pays high contract rates, and grabs your interest. To find in-demand, high-paying contract opportunities, look on sites like Indeed and LinkedIn for contract opportunities posted in your area or for remote work.&lt;/p&gt;

&lt;p&gt;If you have on the job experience with the technology that's great, but it's not necessary. I've landed many opportunities where I had no real "on-the-job" experience with the technology the client was using. Start building something with the technology on your own. Follow tutorials, contribute to open source projects, answer questions on StackOverflow, write your own articles / blog posts... there are many ways to build experience outside of your job.&lt;/p&gt;

&lt;p&gt;Contract roles are very specific. They are looking for someone with expertise in a particular area to fill an immediate need and they will pay top dollar for it. They may have something specific that needs to be built or they may be augmenting an existing team. They don't want someone who is learning on the job, they want someone who can jump in and make a difference day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Know your worth
&lt;/h2&gt;

&lt;p&gt;Do your research! Are you experienced in a technology that is in high demand? What type of contract rates are being offered? Calculating how much a contract opportunity pays in terms of salary is often written as a simple equation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;50 (work weeks) x 40 (hours / wk) x rate = salary equivalent
2,000 (hours / yr) x rate = salary equivalent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not exactly. 2,000 hours is based on a 40 hour week with 2 weeks of vacation in a year. If you plan to take 4 weeks of vacation, you will be working 48 weeks. In the United States, this formula also doesn't account for your share of self-employment taxes (for 1099 consulting) or potentially covering your own health insurance (unless you are covered under a spouse).&lt;/p&gt;

&lt;p&gt;Don't consider opportunities below your worth. If you need more experience to demand those higher rates, go back to step 3.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Start talking to placement firms
&lt;/h2&gt;

&lt;p&gt;Placement firms are a means to an end. They are the middle man that can help you find opportunities when you don't have a client list of your own.  When you come across contract opportunities on LinkedIn or Indeed, they are usually who you will be dealing with. You will contact a recruiter and, if you pass their sniff test, they will put you in contact with the client for an initial interview.&lt;/p&gt;

&lt;p&gt;When talking to placement firms make sure you are showcasing your technical chops. Recruiters and potential clients will be reviewing your LinkedIn profile and resume for experience in the areas they need. Make sure and highlight everything you can about the technology you will be working with.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Pay attention to the contract you sign
&lt;/h2&gt;

&lt;p&gt;Here's what you need to know about placement firms. They are the man in the middle. They are being paid by the client you will be working for and you will get paid by them. This means they get a cut of your rate, often a very large cut! Your goal is to eventually cut out the middle man get the rate all to yourself. You need to work directly for the client, but there's a catch.&lt;/p&gt;

&lt;p&gt;Pay close attention to the contact the placement firm wants you to sign. The non-compete agreement an area of the contract where the placement firm tries to guarantee that if you work for their client, you must work through them. Of course, they want to get paid for finding you!&lt;/p&gt;

&lt;p&gt;The contract will state a period of time you have to work elsewhere before you can contract directly for the client. It's typical to see a 12 month period, but I've seen as high as 24 months. Try to negotiate this period down as low as possible. You want to be able to come back and work for the client without the middle man as soon as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Build your reputation
&lt;/h2&gt;

&lt;p&gt;As a contractor, do nothing but fantastic work. You need to strive to be at least twice as productive as the full-time employees on the team. Focus on building relationships with your team members and management. Make sure everyone sees you as an indispensable asset to the team.&lt;/p&gt;

&lt;p&gt;In the future your reputation will proceed you. When you leave, the people you worked with will know that you are a resource who can be relied on. They will be happy to bring you back for future opportunities and you won't need the involvement of a placement firm.&lt;/p&gt;

&lt;p&gt;Avoid leaving contracts before the end of the contract term. There may be extenuating circumstances, but this is almost always a bad idea. It simply leaves a bad taste in the clients mouth and makes you look like you're not dependable.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Use contract terms to your advantage
&lt;/h2&gt;

&lt;p&gt;Contracts are set for a specific term (e.g. 6 months). When the term is up, if you've follow step 7, the client will often want to extend the contract. This is where you have leverage. Can you negotiate a higher rate? Do you want to move to a new client to gain additional experience or higher pay? Maybe a higher rate has been offered and you want to negotiate a longer term?&lt;/p&gt;

&lt;p&gt;I see the limited timeframe of a contract as more of an advantage than a drawback. The term lets you make changes without burning any bridges. Just make sure you are aware of the timeframe. Even if the client loves the work you've done, budget constraints may mean that an extension is not possible. Don't worry, and go back to step 5.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Keep your radar up
&lt;/h2&gt;

&lt;p&gt;Be on the lookout for opportunities, especially with clients where you’ve built a reputation and any non-compete agreement has expired. This is where you cut out the middle man. Keep in contact with management and decision makers.&lt;/p&gt;

&lt;p&gt;Have lunch, get together for coffee, simply check in with a friendly "catching up" email. Almost all of my clients now come from past colleagues and referrals. Trust that's already been built is the easiest way to find new opportunities.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Become the expert in the room
&lt;/h2&gt;

&lt;p&gt;Over time you will expand your expertise beyond the niche technology you focused on. You'll gain new, invaluable experience with each contract you take. The goal is to become the expert your clients want in the room. You &lt;a href="https://medium.com/gitconnected/becoming-the-expert-in-the-room-df9d01829458" rel="noopener noreferrer"&gt;can read more about how to do that here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  So remember...
&lt;/h2&gt;

&lt;p&gt;Going independent means trusting in your abilities and betting on yourself. You can do it. Double your salary this year and remember, the sky is the limit!&lt;/p&gt;




&lt;p&gt;Want to know more?  Subscribe to my newsletter at &lt;a href="https://jacoborshalick.me" rel="noopener noreferrer"&gt;jacoborshalick.me&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Never fear another layoff</title>
      <dc:creator>Jacob Orshalick</dc:creator>
      <pubDate>Mon, 23 Jan 2023 18:45:00 +0000</pubDate>
      <link>https://dev.to/jorshali/never-fear-another-layoff-36ni</link>
      <guid>https://dev.to/jorshali/never-fear-another-layoff-36ni</guid>
      <description>&lt;p&gt;My first layoff experience was in college. As an intern my department got eliminated when the telecom bubble burst.&lt;/p&gt;

&lt;p&gt;The experience opened my eyes to the limits of the comfort zone called a job. There was no safe haven, so I'd better stop pretending.&lt;/p&gt;

&lt;p&gt;I never wanted to fear another layoff. I wanted to be prepared for anything. Here's how I did it:&lt;/p&gt;

&lt;h2&gt;
  
  
  Be honest with yourself
&lt;/h2&gt;

&lt;p&gt;Start by honestly assess where you're at in your career:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are you employable?&lt;/li&gt;
&lt;li&gt;Have your skills stayed current? &lt;/li&gt;
&lt;li&gt;Are you are continuing to grow?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don't like what you see, create an action plan to fix it.  Remember, you are responsible for your own career.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get out of your comfort zone
&lt;/h2&gt;

&lt;p&gt;The comfort zone is our safe haven.  But, if you &lt;a href="https://medium.com/carl-pullein/why-your-comfort-zone-is-the-most-dangerous-place-on-earth-aec44723888e" rel="noopener noreferrer"&gt;read nearly any self help guide&lt;/a&gt;, the message is clear.  Staying in our comfort zone impedes our growth.&lt;/p&gt;

&lt;p&gt;Transfer to that new project with the new technology.  Take the time to learn new technologies on your own.  Start building a product you think you could sell.  Learn, write about it, present, contribute, rinse, repeat.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put the work in
&lt;/h2&gt;

&lt;p&gt;Success in your career, your relationships, everything important in life, comes from putting in the work.  Those who are willing to go the extra mile will always have a leg up on everyone else.&lt;/p&gt;

&lt;p&gt;I've competed in two &lt;a href="https://www.ironman.com" rel="noopener noreferrer"&gt;IronMan&lt;/a&gt; races.  Every single time someone finds out, they tell me the same thing.  I could never do that.  My response is always the same.  That's bullshit.  Unless you have a true physical limitation, anyone can do it if they're just willing to put the work in.&lt;/p&gt;

&lt;p&gt;I had never done a triathlon.  I had never swam laps in a pool.  I'd never ridden a bike further than 8 miles when I started.  A friend of mine suggested we try it and after a year and a half of daily training, we both completed our first race.  I read and listened to a lot of &lt;a href="https://lioncrest.com/books/cant-hurt-me-david-goggins/" rel="noopener noreferrer"&gt;David Goggins&lt;/a&gt; along the way.&lt;/p&gt;

&lt;p&gt;When you're at your job, give it your all.  This doesn't mean you have to work 80 hours a week, but don't be lazy.  Stay off social media at work, limit the socializing, get it done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Never stop interviewing
&lt;/h2&gt;

&lt;p&gt;Interviewing is a skill, just like anything else.  You don't have to take interviews every day or even every week.  But, setting up at least a monthly phone screen or in-person interview will help keep your skills sharp.&lt;/p&gt;

&lt;p&gt;Interviewing also helps you understand what you want in a job and what skills are in-demand.  You'll encounter different types of teams, technologies, ways of working, personalities...  You may realize you love the job you have or decide you want to make a change.&lt;/p&gt;

&lt;p&gt;Don't burn any bridges along the way by stringing a company along, but it never hurts to test the waters.  Who knows, you may find your dream job along the way.  To get those interviews...&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a professional online presence
&lt;/h2&gt;

&lt;p&gt;You may have seen your LinkedIn feed explode with posts over the past few months from those who have been impacted by the layoffs.  My heart goes out to all of them.  But, if you pay close attention, you'll notice that those who have curated their online presence over the years have received significant responses and offers to help.&lt;/p&gt;

&lt;p&gt;Maintaining an online presence increases your exposure to potential opportunities. Even if you love what you're doing and plan to never change, you want to be able to reach out to those who can help if the need arises. Which brings up my next tip...&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep networking
&lt;/h2&gt;

&lt;p&gt;My network has been invaluable to me in finding opportunities over the years. 95% of the opportunities I've had have come from my network. I try to reach out to at least 2 previous or new contacts every week.&lt;/p&gt;

&lt;p&gt;This ensures that I'm actively building new connections and continuing to stay on the radar of those I've worked with in the past. If an opportunity comes up in their organization, they are much more likely to think of me if we spoke recently.&lt;/p&gt;

&lt;p&gt;Always connect with those you meet on LinkedIn and keep up with your connection requests. While it can be annoying sifting through the requests that are just trying to sell you something, it's easy enough to ignore the noise. The long-term payoff is worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Believe in yourself
&lt;/h2&gt;

&lt;p&gt;It may be cliche, but you can do it.  Believing in yourself is confidence, and that confidence shines through.  It's something everyone is naturally attracted to.&lt;/p&gt;

&lt;p&gt;Confidence will help you sell your ideas to others, land jobs, get promotions, and generally feel better about yourself.  But, it's not free.&lt;/p&gt;

&lt;h2&gt;
  
  
  So remember...
&lt;/h2&gt;

&lt;p&gt;No one is going to be confident in their job search when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they've been doing the minimum necessary to get by at their job&lt;/li&gt;
&lt;li&gt;their skills are outdated&lt;/li&gt;
&lt;li&gt;they haven't interviewed in years &lt;/li&gt;
&lt;li&gt;they have a resume that looks unimpressive&lt;/li&gt;
&lt;li&gt;they have no network to fall back on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You have my guide.  Use it.  I promise you, you will never fear another layoff.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://jacoborshalick.me/posts/never-fear-another-layoff" rel="noopener noreferrer"&gt;jacoborshalick.me&lt;/a&gt; on January 23, 2023.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
  </channel>
</rss>
