<?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: Artur Ceschin</title>
    <description>The latest articles on DEV Community by Artur Ceschin (@artur_ceschin).</description>
    <link>https://dev.to/artur_ceschin</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%2F1202484%2F4dbf6432-8b45-4982-ae62-4dcd4c44534b.jpeg</url>
      <title>DEV Community: Artur Ceschin</title>
      <link>https://dev.to/artur_ceschin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/artur_ceschin"/>
    <language>en</language>
    <item>
      <title>Serverless APIs on AWS with API Gateway and Lambda Functions (First Steps)</title>
      <dc:creator>Artur Ceschin</dc:creator>
      <pubDate>Thu, 29 Feb 2024 14:10:47 +0000</pubDate>
      <link>https://dev.to/artur_ceschin/serverless-apis-on-aws-with-api-gateway-and-lambda-functions-first-steps-53da</link>
      <guid>https://dev.to/artur_ceschin/serverless-apis-on-aws-with-api-gateway-and-lambda-functions-first-steps-53da</guid>
      <description>&lt;p&gt;In this article will explore how serverless computing works; despite its name, it still depends on servers. Additionally, we will provide an AWS tutorial, so make sure you have an active account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding ways to deploy your application
&lt;/h2&gt;

&lt;p&gt;First, let's examine the traditional method of running and storing your project: Typically, we &lt;strong&gt;"rent"&lt;/strong&gt; computing resources, such as a virtual machine, from cloud providers like **AWS, Azure, or GCP, among can access we have access to these resources, we configure our project by installing dependencies and running it on a designated port.&lt;/p&gt;

&lt;p&gt;Using the traditional method on AWS, a suitable service for this approach is Amazon &lt;strong&gt;EC2 (Elastic Compute Cloud)&lt;/strong&gt;. With EC2, you can select the operating system and customize the hardware specifications according to your project's requirements. However, it's important to note that the more hardware resources you allocate, the higher the cost will be. &lt;/p&gt;

&lt;p&gt;EC2 guarantees &lt;strong&gt;24/7&lt;/strong&gt; availability for your application. The cost varies based on instance type and allocated resources. A primary EC2 instance with 500MB of memory typically costs &lt;strong&gt;USD 4.00/month&lt;/strong&gt;. However, this method may have problematic characteristics depending on your specific needs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Manual Updates:&lt;/strong&gt; To keep your project up-to-date on services like Amazon EC2, you'll need to update it manually. Although this gives you complete control over your machine, it also means you are responsible for ensuring that everything is up-to-date.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scaling Responsibility:&lt;/strong&gt; When you scale your server, you can either increase the power of existing instances (vertical scaling) or create new instances (horizontal scaling). This provides you with greater flexibility but requires careful planning to ensure that your infrastructure effectively meets your needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;EC2 incurs &lt;strong&gt;charges per hour&lt;/strong&gt;, even when it's not in use. Although you can save costs by shutting down your project during idle periods, it also means that it won't be accessible in case of emergencies. However, you can downscale or upscale your server to adjust your project's computational needs during idle hours.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using EC2 requires an &lt;strong&gt;understanding of infrastructure&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Serverless
&lt;/h2&gt;

&lt;p&gt;At first glance, 'Serverless' might imply &lt;strong&gt;no servers at all&lt;/strong&gt;. However, in reality, &lt;strong&gt;it means utilizing a server to host your APIs without needing you to manage it directly&lt;/strong&gt;. Instead, cloud providers like AWS take care of the server management on your behalf.&lt;/p&gt;

&lt;p&gt;When discussing Serverless, we refer to 'FaaS' &lt;strong&gt;(Function As a Service)&lt;/strong&gt;. Each cloud provider offers Serverless products, with AWS offering AWS Lambda.&lt;/p&gt;

&lt;p&gt;Serverless computing typically comes with significantly lower costs, especially for small and medium applications.&lt;/p&gt;

&lt;p&gt;In Serverless architecture, our application only runs upon API requests, which can result in a &lt;strong&gt;'Cold Start'&lt;/strong&gt; the first time. Our serverless platform checks if the application is running and looks for a previously started container to handle &lt;strong&gt;requests quickly&lt;/strong&gt;. If it is not running, it creates one within &lt;strong&gt;milliseconds&lt;/strong&gt; using technologies like &lt;strong&gt;Firecracker&lt;/strong&gt;. Subsequent requests for the same service are handled without starting a new container, known as a 'Warm,' ensuring speedy response times for users.&lt;/p&gt;

&lt;p&gt;Keeping our Serverless Functions &lt;strong&gt;small and granular&lt;/strong&gt; is &lt;strong&gt;crucial&lt;/strong&gt; to ensure that our 'Cold Start' is as fast as possible. Moreover, the container will shut down if there is &lt;strong&gt;no activity&lt;/strong&gt; on the server for a while, usually between 5 to 15 minutes. This process helps us save significant costs by using resources only when necessary.&lt;/p&gt;

&lt;p&gt;It is important to note that we do not pay for the time the container executes. Instead, we are billed based on &lt;strong&gt;how many times the function is executed&lt;/strong&gt; and the duration of each execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hands-on Tutorial
&lt;/h2&gt;

&lt;p&gt;Let's see this process in practice on AWS.&lt;br&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%2F0e2oic3d844mbq3m6acf.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%2F0e2oic3d844mbq3m6acf.png" alt="Create a function first step" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll name my &lt;strong&gt;function listUser&lt;/strong&gt; and use Node.js with the arm64 architecture. It's cost-effective and works well for our needs, as our application won't rely heavily on system methods.&lt;/p&gt;

&lt;p&gt;To change the &lt;strong&gt;default execution role&lt;/strong&gt;, we'll create a new role with &lt;strong&gt;basic permissions&lt;/strong&gt;. Lambda allows us to &lt;strong&gt;customize&lt;/strong&gt; permissions for each function. By default, Lambda enables &lt;strong&gt;CloudWatch&lt;/strong&gt;, ensuring all our logs are readily available. This is particularly useful for tracking errors and viewing the execution details of our applications.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;"Advanced settings"&lt;/strong&gt;, we'll keep everything as default, leaving it empty. Then, we'll move on to creating the function.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, Lambda automatically integrates with CloudWatch to log every request, which is particularly useful for error handling. To observe this in action, insert a &lt;code&gt;throw new Error()&lt;/code&gt; function before the main function continues. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;An error occurred here&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from Lambda!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After inserting this, click '&lt;strong&gt;Deploy&lt;/strong&gt;,' navigate to the 'Test' tab, and send a request. It doesn't matter what you send for this example; I typically send an object with an email. Then, click on &lt;strong&gt;' Test'&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Next, go to &lt;strong&gt;CloudWatch &amp;gt; Logs &amp;gt; Log Group&lt;/strong&gt;, and you'll find the logs there! You'll likely see something similar to this:&lt;br&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%2Ffljiucugc3taer1lr8gm.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%2Ffljiucugc3taer1lr8gm.png" alt="Error in CloudWatch" width="765" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating the function, navigate to the Configuration page. Here, you'll find options for "Memory", &lt;strong&gt;"Ephemeral storage"&lt;/strong&gt;, and &lt;strong&gt;"Timeout"&lt;/strong&gt;. It's important to note that increasing these values can affect pricing. By default, "Memory" is set to 128 MB, but you can increase it to 10 GB. The "Ephemeral storage" is temporary and cleared each time the Lambda function is invoked, making it essential for our function to be stateless. The minimum storage value is 512 MB, and the maximum is 10 GB.&lt;/p&gt;

&lt;p&gt;Additionally, consider the "Timeout" setting. The minimum timeout is 1 second, and the maximum is 15 minutes. However, Lambda functions are intended to be fast, and if your process exceeds 15 minutes, the function will be terminated.&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%2Ffdzwqqke0ff57y5kvs10.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%2Ffdzwqqke0ff57y5kvs10.png" alt="Lambda Configuration" width="800" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, how can we see that working? Lambda wasn't just built for API development! It was designed with event-driven scenarios in mind. Lambda works with &lt;strong&gt;triggers&lt;/strong&gt;. For example, we might want to &lt;strong&gt;execute&lt;/strong&gt; our Lambda function when an HTTP request is sent or our S3 bucket changes, such as an upload. In such cases, we can configure our Lambda function to be invoked.&lt;/p&gt;

&lt;p&gt;Let's start with an HTTP trigger example; go to your Lambda &amp;gt; Configuration &amp;gt; Function URL &amp;gt; Create function URL&lt;br&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%2F2juiuzmm2jqh6hse49cl.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%2F2juiuzmm2jqh6hse49cl.png" alt="Create function" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the 'Auth type' section, I'll leave it set to 'NONE, which will generate a basic 'Policy statement.' I won't make any changes there. Next, in the 'Invoke mode' section, I'll stick with the default option, 'BUFFERED.' I'll keep the CORS configuration as it is for now and then click on &lt;strong&gt;Save&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Once saved, we'll get a URL. If you click on that URL, you'll probably see something like this:&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%2Fk6asyv7tny0009l18j88.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%2Fk6asyv7tny0009l18j88.png" alt="Lambda URl" width="769" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's explore how to &lt;strong&gt;upload multiple&lt;/strong&gt; files containing logic and libraries to AWS Lambda.&lt;/p&gt;

&lt;p&gt;This exercise will demonstrate that Lambda functions can consist of &lt;strong&gt;multiple files&lt;/strong&gt; and utilize various &lt;strong&gt;libraries&lt;/strong&gt;. While the application we're building is simple, it will showcase the flexibility of Lambda in handling multiple packages and files.&lt;/p&gt;

&lt;p&gt;I'll create a new folder and initialize a Node.js project by running &lt;code&gt;yarn init -y&lt;/code&gt;. This will set up the basic configuration for our project.&lt;/p&gt;

&lt;p&gt;Next, I'll create a src folder within the project directory. Inside this folder, I'll create an &lt;code&gt;index. mjs&lt;/code&gt; file. Utilizing the new ECMAScript Modules syntax with &lt;strong&gt;import and export&lt;/strong&gt;, this file will serve as the entry point for our Lambda function.&lt;/p&gt;

&lt;p&gt;Now, let's create another folder named &lt;code&gt;utils&lt;/code&gt; and add a file named &lt;code&gt;response.mjs&lt;/code&gt;. In this file, we'll define a function called &lt;strong&gt;response&lt;/strong&gt; that takes a &lt;strong&gt;statusCode&lt;/strong&gt; and a &lt;strong&gt;body&lt;/strong&gt;, converting the body to a string before returning it as part of the response object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in our &lt;code&gt;index.mjs&lt;/code&gt; file, let's define a '&lt;strong&gt;handler&lt;/strong&gt;' function. For demonstration purposes, we'll import &lt;code&gt;randomUUID&lt;/code&gt; from the &lt;code&gt;node:crypto&lt;/code&gt; module and &lt;strong&gt;jwt&lt;/strong&gt; from the &lt;code&gt;jsonwebtoken&lt;/code&gt; library, which we'll install using &lt;code&gt;yarn add jsonwebtoken&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;randomUUID&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsonwebtoken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./utils/response.mjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Artur&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;token&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To set **environment variables **in Lambda, navigate to your Lambda configuration and locate the 'Environment variables' section below the Function URL. Here, you can add the key-value pairs for your variables.&lt;br&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%2Fnry5givj1th365qyv58z.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%2Fnry5givj1th365qyv58z.png" alt="Lambda Environment variable" width="800" height="483"&gt;&lt;/a&gt;&lt;br&gt;
Now, our code will have access to the environmental variable.&lt;/p&gt;

&lt;p&gt;Now, let's discuss how to upload our code. We have two options: &lt;strong&gt;uploading a zip file&lt;/strong&gt; directly or using the &lt;strong&gt;code stored in an S3 bucket&lt;/strong&gt;. To start, click the 'Upload from' button in the top right corner and choose your preferred option; I will use the &lt;strong&gt;zip&lt;/strong&gt; option for now.&lt;/p&gt;

&lt;p&gt;Let's upload the zip file containing the code we just created. Once uploaded, your Lambda function configuration should look like the following image:&lt;br&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%2Ffhkea2m0vf7lpf5vtm9k.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%2Ffhkea2m0vf7lpf5vtm9k.png" alt="Code in Lambda" width="764" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But if we access the URL provided, you will probably see the &lt;code&gt;Internal Server Error&lt;/code&gt; error. We haven't set the correct path to access our handler. To fix that, go to the &lt;strong&gt;Runtime settings&lt;/strong&gt; section, click on edit, and change it to the desired path for the handler. In my case, that will be &lt;strong&gt;live009/src/index.handler&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We've uploaded our code, but how do we see it in action? It's a bit of a manual process—like flipping a switch and hoping for the best! But fear not. There are &lt;strong&gt;better ways to do this&lt;/strong&gt;; we'll dive into those in the following tutorials.&lt;/p&gt;

&lt;p&gt;But first, let's address a couple of things. Firstly, we haven't told our Lambda function which methods it should be able to handle—like &lt;strong&gt;POST, PUT, GET, or DELETE&lt;/strong&gt;. And have you noticed how our URLs are all over the place and don't make much sense? Yeah, we need to fix that, too.&lt;/p&gt;

&lt;p&gt;Introducing &lt;strong&gt;Amazon API Gateway&lt;/strong&gt;! This fantastic service enables us to define precisely how our** HTTP routes** should operate*&lt;em&gt;. It acts as a **traffic controller for our requests&lt;/em&gt;&lt;em&gt;, guaranteeing they **always reach the correct destination&lt;/em&gt;&lt;em&gt;. Additionally, it performs other essential tasks such as **caching and configuring authentication&lt;/em&gt;*, ensuring that only authorized personnel can access our resources!&lt;/p&gt;

&lt;p&gt;To get started, go to API Gateway and select the &lt;strong&gt;HTTP API&lt;/strong&gt; option. This option is faster and more &lt;strong&gt;cost-effective&lt;/strong&gt; than the REST API option. After making your selection, click on the '&lt;strong&gt;Build&lt;/strong&gt;' button. This will take you to a screen that looks &lt;strong&gt;similar&lt;/strong&gt; to the one below:&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%2Fxhi5p7clx57k4s3ixqs8.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%2Fxhi5p7clx57k4s3ixqs8.png" alt="API Gateway first step screen" width="800" height="632"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the image, I selected Lambda as my integration, chose our listUser Lambda function, and gave our API a name (you can name it whatever you like).&lt;/p&gt;

&lt;p&gt;Next, I clicked' Next' to set the &lt;strong&gt;HTTP method&lt;/strong&gt;. In the 'Configure routes' section, I put the URL code to GET, changed the path to '/users', and specified that it should be redirected to the listUsers function when this request happens.&lt;/p&gt;

&lt;p&gt;Then, in the &lt;strong&gt;Configure stages&lt;/strong&gt; section, I kept the settings as default for now and clicked &lt;strong&gt;Create&lt;/strong&gt; to complete the process.&lt;/p&gt;

&lt;p&gt;Once created, you can access the &lt;strong&gt;Invoke URL&lt;/strong&gt;, and add '/users' at the end of the URL. This will trigger the Lambda function we set up earlier, and you'll see the return we defined previously.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using S3 as our Trigger
&lt;/h2&gt;

&lt;p&gt;To conclude this tutorial, we will now create a function that will &lt;strong&gt;execute&lt;/strong&gt; each time a new file is &lt;strong&gt;uploaded&lt;/strong&gt; to an &lt;strong&gt;S3 bucket&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To begin, follow the same steps we did earlier to create a new Lambda function. Once the function is created, navigate to the 'Configuration' section and choose '&lt;strong&gt;Triggers&lt;/strong&gt;' in the &lt;strong&gt;left sidebar&lt;/strong&gt;. Click on the 'Add trigger' button.&lt;/p&gt;

&lt;p&gt;In the trigger configuration, select 'S3' as the trigger source, pick the bucket you have previously created, and specify that the event should be triggered when a new object is created. If you only want to trigger for &lt;strong&gt;JSON files&lt;/strong&gt;, you can set the event suffix to '&lt;strong&gt;.json&lt;/strong&gt;'. Before clicking 'Add', make sure to check the &lt;strong&gt;'Recursive invocation'&lt;/strong&gt; option.&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%2Flc8b52en6z9uuzk5v94g.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%2Flc8b52en6z9uuzk5v94g.png" alt="Lambda trigger configuration" width="800" height="869"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see what data is passed in the event object to our handler function, add a &lt;code&gt;console.log(event)&lt;/code&gt; within the function. Then, open your S3 bucket and CloudWatch. Create a simple JSON file like the one below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"artur.ceschin@gmail.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Artur Ceschin"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Joe.doeh@gmail.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Joe Doeh"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upload this file to your S3 bucket, and check CloudWatch to see the console.log output. You should see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Records:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;eventVersion:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mf"&gt;2.1&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;eventSource:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'aws:s&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;awsRegion:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'us-east&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;eventTime:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;2024-02-27&lt;/span&gt;&lt;span class="err"&gt;T&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;31.025&lt;/span&gt;&lt;span class="err"&gt;Z'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;eventName:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'ObjectCreated:Put'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;userIdentity:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;requestParameters:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;responseElements:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;s&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For better readability, you can stringify the event object using &lt;code&gt;console.log('EVENT=&amp;gt;', JSON.stringify(event, null, 2))&lt;/code&gt;. This will provide a nicely formatted output in your CloudWatch logs.&lt;br&gt;
If you try to upload a file that is not a .json file, it does not trigger our Lambda.&lt;/p&gt;

&lt;p&gt;Let's now read the file uploaded to our S3 bucket. First, let's modify our Lambda function to log the bucket name and key of the uploaded file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;S3Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GetObjectCommand&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-sdk/client-s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Records&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FILES&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After uploading a new file, check CloudWatch logs. You should see output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FILES { bucket: 'artur.ceschin.dev', key: 'users2.json'}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's read the contents of the file. We'll use the &lt;code&gt;@aws-sdk/client-s3&lt;/code&gt; package, which comes pre-installed in AWS Lambda. We'll import the &lt;code&gt;S3Client&lt;/code&gt; and &lt;code&gt;GetObjectCommand&lt;/code&gt; methods to locate and retrieve the file from our S3 bucket. Here's the updated code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;S3Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GetObjectCommand&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-sdk/client-s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Records&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;S3Client&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GetObjectCommand&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RESPONSE =&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, if you run this code and upload a file, you'll likely encounter an &lt;strong&gt;'Access Denied'&lt;/strong&gt; error. Navigate to your Lambda function's &lt;strong&gt;Configuration &amp;gt; General Configuration&amp;gt; Edit&lt;/strong&gt; to fix this. At the bottom of 'Basic settings,' click the link: &lt;em&gt;View the processJSON-role-x5iz5f89&lt;/em&gt;. This will take you to the IAM role associated with your Lambda function.&lt;/p&gt;

&lt;p&gt;Next, click &lt;strong&gt;Add permission &amp;gt; Create inline policy&lt;/strong&gt;. Select the service (S3) and search for 'GetObject.' Add the ARN of your bucket as the resource. Leave all actions as '&lt;em&gt;,' and click **Add ARN&lt;/em&gt;&lt;em&gt;. Finally, click **Next&lt;/em&gt;&lt;em&gt;, provide a description, and click **Create policy&lt;/em&gt;*. In the two images below, you can see the two processes you will encounter as described: &lt;br&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%2Fdvf2yf9ykfocyknt66nn.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%2Fdvf2yf9ykfocyknt66nn.png" alt="Actions in policy" width="800" height="501"&gt;&lt;/a&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%2Fhwzhmpcqrsya7tg7b4vm.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%2Fhwzhmpcqrsya7tg7b4vm.png" alt="Add RNSARN" width="800" height="409"&gt;&lt;/a&gt;&lt;br&gt;
After completing that process, you will likely see your request in CloudWatch. But what if we want to read the JSON file inside our object?&lt;/p&gt;

&lt;p&gt;In the code below, we retrieve the &lt;strong&gt;Body&lt;/strong&gt; from the request, push chunks (pieces from our object) to our array, and then display them in the console.log.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Records&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;S3Client&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GetObjectCommand&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Buffer =&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow, we've covered a lot in this tutorial! I hope you found it enjoyable and informative. If you have any &lt;strong&gt;doubts&lt;/strong&gt; or &lt;strong&gt;suggestions&lt;/strong&gt;, please leave them in the comments below. Before we wrap up, let's briefly discuss the pros and cons of using Lambda functions:&lt;/p&gt;

&lt;h3&gt;
  
  
  Props ✅
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Having a &lt;strong&gt;deep understanding&lt;/strong&gt; of your &lt;strong&gt;infrastructure&lt;/strong&gt; is &lt;strong&gt;not&lt;/strong&gt; necessary.&lt;/li&gt;
&lt;li&gt;Maintaining your infrastructure is &lt;strong&gt;easier&lt;/strong&gt; than maintaining other services.&lt;/li&gt;
&lt;li&gt;Automatic configuration is available through &lt;strong&gt;CloudWatch&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The service is highly &lt;strong&gt;scalable&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You only pay for what you use.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;responsibilities&lt;/strong&gt; are minimal.&lt;/li&gt;
&lt;li&gt;Triggers can be set up based on &lt;strong&gt;events&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cons 🛑
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;A cold start &lt;strong&gt;can be an issue&lt;/strong&gt; if there are too many requests, as it can slow down the process.&lt;/li&gt;
&lt;li&gt;Lambda has some &lt;strong&gt;size limitations&lt;/strong&gt; that may impact your usage. These include:

&lt;ul&gt;
&lt;li&gt;a maximum code size of 250MB&lt;/li&gt;
&lt;li&gt;10GB of Ephemeral storage&lt;/li&gt;
&lt;li&gt;a timeout limit of 15 minutes&lt;/li&gt;
&lt;li&gt;a maximum memory usage of 10GB&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;can get complicated&lt;/strong&gt;, especially when one Lambda function calls another.&lt;/li&gt;
&lt;li&gt;Cost can be a concern if there are &lt;strong&gt;too many requests&lt;/strong&gt;, mainly when using API Gateway. In this case, it may be more expensive than providing an &lt;strong&gt;instance that runs 24/7&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;In this article, we explored serverless computing using AWS Lambda, a cost-effective and scalable solution. We have compared it with &lt;strong&gt;traditional methods&lt;/strong&gt; and highlighted its automation benefits and the &lt;strong&gt;simplified&lt;/strong&gt; deployment process it offers.&lt;/p&gt;

&lt;p&gt;Our &lt;strong&gt;tutorial&lt;/strong&gt; has covered the process of &lt;strong&gt;setting up Lambda functions&lt;/strong&gt;, configuring &lt;strong&gt;triggers&lt;/strong&gt;, and handling &lt;strong&gt;events&lt;/strong&gt; such as S3 file uploads. We have also shown some challenges, such as cold starts and size limitations, and provided solutions to overcome them.&lt;/p&gt;

&lt;p&gt;Overall, AWS Lambda is a &lt;strong&gt;powerful tool for modern applications&lt;/strong&gt; that streamlines deployment reduces costs, and simplifies scalability.&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions for the next articles, please comment below! 👋&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deploying React apps to production on AWS ☁️</title>
      <dc:creator>Artur Ceschin</dc:creator>
      <pubDate>Mon, 22 Jan 2024 12:52:24 +0000</pubDate>
      <link>https://dev.to/artur_ceschin/deploying-react-apps-to-production-on-aws-2hn</link>
      <guid>https://dev.to/artur_ceschin/deploying-react-apps-to-production-on-aws-2hn</guid>
      <description>&lt;p&gt;In this article, we will explore how to deploy your Front-End project on AWS. I will demonstrate this using a React project, but these steps can be applied to Vue, Angular, or any other stack.&lt;/p&gt;

&lt;p&gt;To follow this tutorial, you will need to meet the following 3 requirements.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You will first require an &lt;strong&gt;AWS account&lt;/strong&gt;. To set up your account, you'll need to provide your credit card information as AWS charges based on usage. However, storing your project &lt;strong&gt;can be exceptionally affordable&lt;/strong&gt;, and most services offer free tiers. This means you can store your projects for free if you stay within the limits of the free tier usage. This is the screen you encounter after providing your information for AWS. You can choose the best option for your needs—I am opting for the free version.👇&lt;br&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%2Fa49lhbomjtbuhqfjvnds.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%2Fa49lhbomjtbuhqfjvnds.png" alt="This is the screen you encounter after signing up for AWS. You have three options: starting for free, personal usage at $29 a month, or $100 a month for business purposes." width="701" height="748"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will also require a &lt;strong&gt;domain&lt;/strong&gt; because we need access to the DNS configurations to point it within AWS. However, this step is &lt;strong&gt;optional&lt;/strong&gt;, as AWS will generate a default URL for you to test.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The final requirement is a React project or any other front-end project, allowing us to generate the &lt;strong&gt;build&lt;/strong&gt; folder.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order for us to deploy our static front-end projects, all we need is to do is find a service that can store our files, and the file we will be using is the &lt;strong&gt;&lt;em&gt;Simple Storage Service&lt;/em&gt;&lt;/strong&gt; commonly now as &lt;strong&gt;S3&lt;/strong&gt;.&lt;br&gt;
Go to yout &lt;br&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%2Fbl8cne4atl82kruqv7h4.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%2Fbl8cne4atl82kruqv7h4.png" alt="Searching for Simple Storage Service in the AWS searching input" width="800" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Navigate to your S3 Service:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;First things first, head over to your AWS Console.&lt;/li&gt;
&lt;li&gt;Dive into the S3 service.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discover Your Buckets:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Look around, and you'll spot buckets.&lt;/li&gt;
&lt;li&gt;They're where you stash everything from your frontend project to cat GIFs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a Fresh Bucket:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Hit the "Create Bucket" button – this is your backstage pass to storage.&lt;/li&gt;
&lt;li&gt;Choose a name that is &lt;strong&gt;unique&lt;/strong&gt; across all AWS accounts!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose Your Storage Spot - Select Location:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time to pick a location for your bucket.&lt;/li&gt;
&lt;li&gt;Consider things like pricing and how speedy you want your files to be – it's a bit like choosing a vacation spot.&lt;/li&gt;
&lt;li&gt; I opted for US East (N. Virginia) as it seemed fitting for my storage requirements. However, feel free to select the location that aligns with your specific needs and preferences. 🌍&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proceed with Default Options:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;For the rest of the setup, I stuck to the defaults.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And there you have it – your bucket is ready to roll! 🚀&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%2Fckkiy4fydm60gcpy9bv0.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%2Fckkiy4fydm60gcpy9bv0.png" alt="Setting the buckest and location" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once created, simply click on the newly made bucket. Upload the files from your &lt;strong&gt;&lt;em&gt;build&lt;/em&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;em&gt;dist&lt;/em&gt;&lt;/strong&gt; directory in your React project into this bucket. Click on &lt;strong&gt;upload&lt;/strong&gt; and you're done with the S3 configuration!&lt;/p&gt;

&lt;h3&gt;
  
  
  CloudFront
&lt;/h3&gt;

&lt;p&gt;Now, how do we access these files? We'll utilize our famous &lt;strong&gt;Content Delivery Network (CDN)&lt;/strong&gt; This magic 🪄 spreads our project across different places. Even though our app lives in North Virginia, it keeps the delay super low for users all over the globe. And guess what? We're going to use AWS's CloudFront to make it happen!&lt;br&gt;
To do that go to the CloudFront service and create a new one, once you do that you will have to fill a fell inputs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The initial step involves configuring the &lt;strong&gt;Origin&lt;/strong&gt; settings. Begin by selecting our S3 project in the Origin domain section. Subsequently, choose the &lt;strong&gt;&lt;em&gt;Origin access&lt;/em&gt;&lt;/strong&gt;. For our setup, we will opt for &lt;strong&gt;&lt;em&gt;Origin access control settings (recommended)&lt;/em&gt;&lt;/strong&gt;. Upon selection, you'll need to designate your &lt;em&gt;Origin access control&lt;/em&gt;. If you haven't created one, use the &lt;strong&gt;default options&lt;/strong&gt; to set it up. Leave the remaining settings in this section at their default values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now, onto the &lt;strong&gt;&lt;em&gt;Default cache behavior&lt;/em&gt;&lt;/strong&gt; section. Most of these settings can stick to the defaults. However, let's change a couple of things. Under &lt;strong&gt;&lt;em&gt;Viewer protocol policy&lt;/em&gt;&lt;/strong&gt;, switch it to &lt;strong&gt;Redirect HTTP to HTTPS&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Web Application Firewall (WAF)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Web Application Firewall (WAF):&lt;/strong&gt;&lt;br&gt;
WAF has a fixed price, which can be quite costly. While it's a good consideration for APIs, since we're only handling static files, it's unnecessary. Therefore, I'll select the option &lt;strong&gt;&lt;em&gt;Do not enable security protections&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Settings:&lt;/strong&gt;&lt;br&gt;
In the settings, the first option you'll encounter is the &lt;strong&gt;Price class&lt;/strong&gt;. I'll opt for &lt;strong&gt;&lt;em&gt;Use all edge locations (best performance)&lt;/em&gt;&lt;/strong&gt;, which might come at a slightly higher cost. But, it's good to consider your own goals and the server's location. &lt;br&gt;
For the &lt;strong&gt;Custom SSL certificate&lt;/strong&gt;, if you don't have your own domain, you can leave it as is, and CloudFront will generate a domain for you. Additionally, in the &lt;strong&gt;Supported HTTP versions&lt;/strong&gt;, consider checking the HTTP/3 option.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, for the &lt;strong&gt;Default root object&lt;/strong&gt; field, this is where you define the name of the object (files) that will be served when a user requests the root URL. To achieve this, we'll input &lt;strong&gt;index.html&lt;/strong&gt;. &lt;br&gt;
Just keep the default settings for the rest and click &lt;strong&gt;Create Distribution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is a demo gif of all that process that we've done so far:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExYTZlOGEzYzhubDBtNjA4NHBnYzNpNzlhNGI2MWprY21wOHdzdGJwcyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/i9uavlpirJ1xIcppzl/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExYTZlOGEzYzhubDBtNjA4NHBnYzNpNzlhNGI2MWprY21wOHdzdGJwcyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/i9uavlpirJ1xIcppzl/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating, you'll likely land on a page that looks like this:&lt;br&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%2Femw18xhhrkf5w3q6zk2t.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%2Femw18xhhrkf5w3q6zk2t.png" alt="CloundFront Next page after creation" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All we need to do now is to click in the &lt;strong&gt;Copy Policy&lt;/strong&gt; button, and click in the link &lt;strong&gt;&lt;em&gt;Go to S3 bucket permissions&lt;/em&gt;&lt;/strong&gt; to update policy. Now click in Edit in the &lt;strong&gt;Bucket policy&lt;/strong&gt; Section and &lt;strong&gt;paste&lt;/strong&gt; your policies and save. Now we have allowed CloudFront to access our S3 Bucket 👏.&lt;/p&gt;

&lt;p&gt;Now, when you navigate to the general area of your CloudFront Distribution, you will find a &lt;strong&gt;Details&lt;/strong&gt; section with the title &lt;strong&gt;Distribution Domain Name&lt;/strong&gt;. This title is accompanied by a &lt;strong&gt;generic link&lt;/strong&gt; created by AWS, allowing you to access your live application. If you copy and paste this link into a web browser, you will likely see your project running under this domain 🚀.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changing to your own custom domain:
&lt;/h2&gt;

&lt;p&gt;The process may vary slightly depending on the provider with whom you created and purchased your personal domain. However, you should be able to access your domain and &lt;strong&gt;change your DNS servers&lt;/strong&gt;. To configure our DNS, we will use another AWS Service called** Route 53*&lt;em&gt;. In this service, choose the option **Create hosted zone&lt;/em&gt;* and fill in the necessary information.&lt;br&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%2F6wlhy02pzh912e75mdtm.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%2F6wlhy02pzh912e75mdtm.png" alt="Create hosted zone option selected" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enter your domain without the &lt;strong&gt;&lt;em&gt;www&lt;/em&gt;&lt;/strong&gt;, like this: &lt;strong&gt;&lt;em&gt;arturceschin.com&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The description is entirely optional and doesn't affect anything; it's just for your personal reference.&lt;/li&gt;
&lt;li&gt;Keep it set as &lt;strong&gt;Public hosted zone&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;CREATE!&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pay attention to your Name servers; these are the ones you'll need to configure in your DNS Server.** Make sure to use all four.**&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%2F985x3x9ifi29uo1x4w8p.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%2F985x3x9ifi29uo1x4w8p.png" alt="DNS Servers" width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simply copy and paste these Name servers into your other domain provider's settings and save. Keep in mind that this process may take up to 2 hours!&lt;/p&gt;

&lt;p&gt;Once that is set, navigate to your CloudFront settings. Click on 'Edit,' and go to the section labeled &lt;strong&gt;Alternate domain name (CNAME)&lt;/strong&gt;. Click &lt;strong&gt;Add item&lt;/strong&gt; and enter your domain twice: once with &lt;strong&gt;www&lt;/strong&gt; at the beginning and once without. 🌐&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%2Fgriqayov86opsr5ec6an.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%2Fgriqayov86opsr5ec6an.png" alt="Setting the domain" width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's set up our &lt;strong&gt;Custom SSL certificate&lt;/strong&gt; using another AWS service called &lt;strong&gt;Certificate Manager&lt;/strong&gt;—and it's free! Click on &lt;strong&gt;Request a public certificate&lt;/strong&gt; and then &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now, just follow the image below: set one domain like before and another with &lt;em&gt;.&lt;/em&gt; to make all subdomains valid. This is called a &lt;em&gt;wildcard&lt;/em&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%2Fgm6laypncve7jk6bz3gw.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%2Fgm6laypncve7jk6bz3gw.png" alt="Domain names examples" width="800" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose &lt;strong&gt;DNS validation&lt;/strong&gt; and keep the other options as they are. Click &lt;strong&gt;Request&lt;/strong&gt;. Your request will be pending validation. To resolve this, click your &lt;strong&gt;Certificate ID&lt;/strong&gt; and choose &lt;strong&gt;Create records in Route 53&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%2Fzytdfjiro4hfmvgnc624.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%2Fzytdfjiro4hfmvgnc624.png" alt="Create records in Route 53 Option" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In about five minutes, your status should change to &lt;strong&gt;Issued ✅&lt;/strong&gt; if you completed the previous step of copying your Name Servers to the DNS Servers in your domain provider and waited for about two hours for that process to complete.&lt;/p&gt;

&lt;p&gt;Now, go to your CloudFront settings once again, navigate to the &lt;strong&gt;Custom SSL certificate&lt;/strong&gt; section, and choose the certificate we just created. The &lt;em&gt;&lt;strong&gt;Custom SSL certificate&lt;/strong&gt;&lt;/em&gt; should suggest the certificate, similar to the image below.⬇️⬇️&lt;br&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%2F7zxsyx80uzftm6put0zw.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%2F7zxsyx80uzftm6put0zw.png" alt='Example of certificate being displayed and selected."' width="745" height="350"&gt;&lt;/a&gt;&lt;br&gt;
Go to &lt;strong&gt;Save Changes&lt;/strong&gt; and wait for a moment, while it is deploying.&lt;/p&gt;

&lt;p&gt;Now, what we need to do is set up the redirection so that when we access our domain, the request is directed to CloudFront. To achieve this, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;strong&gt;Route 53&lt;/strong&gt; service.&lt;/li&gt;
&lt;li&gt;Navigate to your &lt;strong&gt;hosted zone&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Create Record&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose the Alias option.&lt;/li&gt;
&lt;li&gt;Select Alias to CloudFront distribution.&lt;/li&gt;
&lt;li&gt;Choose the desired CloudFront distribution.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Create Record&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Just like to the image below:&lt;br&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%2Fbr3gtv574l79onbd1ahb.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%2Fbr3gtv574l79onbd1ahb.png" alt="Create Record first step" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we will repeat the same process, but set the &lt;strong&gt;Record name&lt;/strong&gt; to &lt;strong&gt;www&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After you've done all that, and your deploy is finished, you should see your project with your cool custom URL 🤩.&lt;/p&gt;

&lt;p&gt;But, heads up! When you access it and hit refresh, you might get smacked with an error saying your &lt;strong&gt;access is denied&lt;/strong&gt;. Just like in the image 👇.&lt;br&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%2Fincfewqds2wpjjaqpf1t.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%2Fincfewqds2wpjjaqpf1t.png" alt="Access Denied" width="761" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But to fix that, all we need to do is set it up so that if we encounter an error like "Access Denied," we automatically redirect to something like &lt;strong&gt;index.html&lt;/strong&gt;. Here's how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to your CloudFront Distribution.&lt;/li&gt;
&lt;li&gt;Navigate to the Error pages section.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Create custom error response&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose the &lt;strong&gt;HTTP error code&lt;/strong&gt; to be &lt;strong&gt;403 Forbidden&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Customize error response&lt;/strong&gt; and set it to &lt;strong&gt;Yes&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Response page path&lt;/strong&gt; to be &lt;strong&gt;/index.html&lt;/strong&gt; and click on &lt;strong&gt;Create custom error page&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Wait for a few minutes for the deployment to take effect.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Check out the image below for guidance.&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%2Fh5lyg0xl00h8tnnbgpny.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%2Fh5lyg0xl00h8tnnbgpny.png" alt="Customizing your error response" width="800" height="690"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With all that set, you should be able to see your application with no more errors, and the deployment of your Front-End project is done. 👏🚀&lt;/p&gt;

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

&lt;p&gt;Deploying your Front-End project on AWS offers numerous advantages, including scalable storage with Amazon S3, efficient content delivery through CloudFront's CDN, and seamless integration with Route 53 for DNS management and AWS Certificate Manager for your SSL Certificates. It's the winning combo for a seamless Front-End deployment. Ready to embrace the power of AWS to enhance your Front-End deployment experience? 🚀✨&lt;/p&gt;

</description>
      <category>aws</category>
      <category>tutorial</category>
      <category>react</category>
    </item>
    <item>
      <title>Stateful vs Stateless</title>
      <dc:creator>Artur Ceschin</dc:creator>
      <pubDate>Mon, 06 Nov 2023 03:27:08 +0000</pubDate>
      <link>https://dev.to/artur_ceschin/stateful-vs-stateless-g8k</link>
      <guid>https://dev.to/artur_ceschin/stateful-vs-stateless-g8k</guid>
      <description>&lt;p&gt;In this article, I will explain what stateful and stateless applications are, highlight their differences, and discuss considerations &lt;strong&gt;when choosing in a cloud context&lt;/strong&gt;. But before delving into these topics, let's begin with a brief explanation of what 'state' means in an application.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The state of an application (or anything else, really) is its condition or quality of being at a given moment in time—its state of being. &lt;strong&gt;Whether something is stateful or stateless depends on how long the state of interaction with it is being recorded and how that information needs to be stored.&lt;/strong&gt; &lt;br&gt;
&lt;a href="https://www.redhat.com/en/topics/cloud-native-apps/stateful-vs-stateless"&gt;Red-Hat Stateful vs Stateless&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a good overview of what we are going to see, but what exactly is &lt;strong&gt;'state'&lt;/strong&gt; in an application?&lt;/p&gt;

&lt;p&gt;The term 'state' can have various meanings in different contexts, &lt;strong&gt;but it typically refers to data or information that can be modified&lt;/strong&gt;, often associated with user interactions.&lt;/p&gt;

&lt;p&gt;What are the &lt;strong&gt;differences between&lt;/strong&gt; Stateful and Stateless?&lt;/p&gt;

&lt;h2&gt;
  
  
  Stateless
&lt;/h2&gt;

&lt;p&gt;By default, &lt;strong&gt;the web is designed to be stateless&lt;/strong&gt;. In a stateless architecture, each interaction between the user and the application is created from scratch every time. The application does not store the user's session or preferences locally. &lt;strong&gt;Examples of stateless applications include static content websites and search engines&lt;/strong&gt;. These stateless applications offer several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Easier to Develop&lt;/strong&gt;, Design, and Maintain: Stateless applications are simpler to create, design, and keep up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Highly Scalable:&lt;/strong&gt; They can easily distribute requests across multiple servers, making them suitable for high levels of traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible and High Availability&lt;/strong&gt;: Stateless applications can adapt to different scenarios, making them more resilient to failures and capable of handling numerous requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stateful
&lt;/h2&gt;

&lt;p&gt;Stateful applications are commonly used to provide a more &lt;strong&gt;personalized and consistent user experience&lt;/strong&gt;. For example, each user can have their own &lt;strong&gt;preferences&lt;/strong&gt; and &lt;strong&gt;customizations&lt;/strong&gt;. Examples of stateful applications include:&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;e-commerce&lt;/strong&gt; application, which can be stateful because it stores user profile configurations and shopping data.&lt;br&gt;
However, stateful applications have their downsides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local Data Storage&lt;/strong&gt;: User data is stored locally, which means that user sessions are maintained on the server. Once the communication is closed, the data is lost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complexity:&lt;/strong&gt; Managing state across multiple sessions and components can be challenging in terms of design and architecture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Distributing stateful components across multiple servers requires careful planning and infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stateless vs Stateful in the Cloud Context
&lt;/h2&gt;

&lt;p&gt;They are both good for their own specific circumstances, but technologies have advanced, and so the necessity of building &lt;strong&gt;scalable applications using microservices and containers and deploying them in the cloud&lt;/strong&gt;. For those cases, it is usually better for the application to be &lt;strong&gt;stateless&lt;/strong&gt;, but why?&lt;/p&gt;

&lt;p&gt;Let's start by creating a &lt;strong&gt;simple scenario&lt;/strong&gt; where we have a configured auto-scaling system, allowing our infrastructure to scale based on resource demand. In this setup, clients &lt;strong&gt;access our load balancer&lt;/strong&gt;, which then &lt;strong&gt;routes&lt;/strong&gt; them to different servers.&lt;/p&gt;

&lt;p&gt;To make this system work, it's crucial that &lt;strong&gt;&lt;em&gt;we avoid storing user data on individual servers like in a stateful application&lt;/em&gt;&lt;/strong&gt;. This is because, in another request, the load balancer may direct the client to a different server where the &lt;strong&gt;user's session data is not available&lt;/strong&gt;. The ideal approach is to ensure that &lt;strong&gt;all servers&lt;/strong&gt; have access to user details by storing session information in a centralized database. This way, regardless of which server handles the request, &lt;strong&gt;it can retrieve the user's information from the shared database&lt;/strong&gt;. This architecture follows a &lt;strong&gt;stateless&lt;/strong&gt; approach, where data is stored externally, allowing any server to access user details without relying on local storage.&lt;br&gt;
This image provides a better illustration of the example above. We store user data in a database like PostgreSQL, images in Amazon S3, and the contents of the e-commerce cart in a DynamoDB database. &lt;strong&gt;By doing this we can assure the all servers can acess different data when needed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5hbwyreZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/phsw9ga7952gnnth9aoa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5hbwyreZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/phsw9ga7952gnnth9aoa.png" alt="'A diagram of the situation above'" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Especially when developing APIs, it's preferable to use stateless applications. Both &lt;strong&gt;RESTful APIs and GraphQL APIs follow stateless principles by default.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While it is possible to develop and deploy stateful applications using containers in the cloud, the flexibility and simplicity of developing applications using stateless architecture make it &lt;strong&gt;preferable when creating highly scalable software.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;I hope you enjoyed this brief overview, feel free to interact in the chat, I see you in the next one 👋🏼!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
