<?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: Albiona</title>
    <description>The latest articles on DEV Community by Albiona (@albicodes).</description>
    <link>https://dev.to/albicodes</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%2F316035%2F5a0bab59-76e3-4a19-9c3b-993be4cafa7f.jpeg</url>
      <title>DEV Community: Albiona</title>
      <link>https://dev.to/albicodes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/albicodes"/>
    <language>en</language>
    <item>
      <title>The Complete Beginners Guide to AWS S3</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Mon, 25 Jan 2021 18:18:34 +0000</pubDate>
      <link>https://dev.to/webiny/get-started-with-aws-s3-3bod</link>
      <guid>https://dev.to/webiny/get-started-with-aws-s3-3bod</guid>
      <description>&lt;p&gt;When developing your web application, you must think of a place where to store your data, how to back up them, types of data you want to store, such as images, music, and videos, application hosting, data archiving, disaster recoveries. AWS Simple Storage Service (S3) provides you the solutions for these cases. S3 is one of the core services of AWS cloud infrastructure. It's object storage that acts like a regular file system on your personal computer. S3 scales infinitely, with no limit on the amount of data you store.&lt;/p&gt;

&lt;p&gt;In this tutorial, we'll get to learn how to use the AWS S3. First, learn what is S3, the core parts of S3 that are the Buckets, Access Point, and Objects. Then we'll get to the practice, by implementing the AWS SDK for Node.js 💻&lt;/p&gt;

&lt;p&gt;Finally, we'll provide a cheat sheet on AWS S3 CMD Commands.&lt;/p&gt;




&lt;p&gt;Amazon Web Services (AWS) provides multiple types of cloud computing services, one of them is the AWS Storage Service. There are different storage services, such as Simple Storage Service (S3), AWS Elastic File System (EFS), &amp;amp; Elastic Block Store (EBS). For this tutorial, we'll be focusing on the S3 service. S3 is one of the most favorite cloud computing services among all the other services, based on &lt;a href="https://twitter.com/acloudguru/status/1240722699493801987" rel="noopener noreferrer"&gt;this poll&lt;/a&gt; by &lt;a href="https://acloudguru.com/" rel="noopener noreferrer"&gt;acloud.guru&lt;/a&gt; on Twitter.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is S3?
&lt;/h2&gt;

&lt;p&gt;You can use S3 to host your static websites, delivering HTML, JavaScript, images, videos, and other files to your website visitors - that doesn't contain server-side code such as Node.js or PHP. Using S3, you can easily deploy your applications in just two to three clicks via the user interface. S3 provides a simple web services interface you can use to store and retrieve any amount of data from anywhere on the web.&lt;/p&gt;

&lt;p&gt;We'll now go through the core concepts of S3, such as &lt;strong&gt;buckets&lt;/strong&gt;, &lt;strong&gt;access points&lt;/strong&gt;, and &lt;strong&gt;objects&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Buckets
&lt;/h3&gt;

&lt;p&gt;To upload your data to S3, you must create an S3 bucket in one of the AWS Regions, within one bucket you can upload many objects to the bucket. For implementation, buckets and objects are resources, and S3 provides &lt;strong&gt;APIs&lt;/strong&gt; for you to manage them. There are different methods you can use to create buckets such as.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon S3 Console&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Follow the guides &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-bucket.html" rel="noopener noreferrer"&gt;here&lt;/a&gt; to create your first bucket with the S3 console.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REST API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To create buckets using REST API, you must authenticate your requests — follow the &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html" rel="noopener noreferrer"&gt;PUT Bucket&lt;/a&gt; in the S3 API reference. But it's recommended to use the AWS Management Console or AWS SDKs instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS SDK&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To create buckets with the SDK, you first have to create a client and then use the client to send a request to create a bucket. Note: When creating the client and the bucket, use the same region. Here is a dominant &lt;a href="https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-example-creating-buckets.html" rel="noopener noreferrer"&gt;source&lt;/a&gt; on creating and using AWS S3 Buckets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Access points
&lt;/h3&gt;

&lt;p&gt;To access the data that you store on S3, you need the S3 Access Point. These are endpoints that are attached to buckets that you used to perform S3 object operations.&lt;/p&gt;

&lt;p&gt;Each access point has distinct permissions and network controls S3 applies for any request that is made through the access point. Access points are used to perform operations on objects, but not on buckets. Go through this source to learn how to manage data access with S3 access points.&lt;/p&gt;

&lt;h3&gt;
  
  
  Objects
&lt;/h3&gt;

&lt;p&gt;We mentioned that AWS S3 is object storage. Each AWS S3 object has data, a key, and metadata. The object key (or key name) uniquely identifies the object in a bucket. Object metadata is a set of name-value pairs.&lt;/p&gt;

&lt;p&gt;You can store objects in one or more buckets, and each object can be up to 5 TB in size. For the real-world solutions, let's say you want to share an image or video stored in AWS S3 bucket on your website, that is possible only if you make the object public or use a pre-signed URL on your website. Follow this source on how to work with S3 objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hands-on S3 with AWS SDK
&lt;/h2&gt;

&lt;p&gt;We'll go with the AWS SDK and Node.js to &lt;strong&gt;create&lt;/strong&gt; S3 buckets, &lt;strong&gt;uploading&lt;/strong&gt; an object to a specified bucket and &lt;strong&gt;deleting&lt;/strong&gt; that bucket afterward; we'll provide a &lt;code&gt;How-To on the S3&lt;/code&gt; section where you can learn more about different use-cases commands to run on S3.&lt;/p&gt;

&lt;p&gt;In order to continue, you must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install Node.js, in case you don't have it, follow the &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js website&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up your user credentials, follow &lt;a href="https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-shared.html" rel="noopener noreferrer"&gt;here&lt;/a&gt; for more information.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuring the SDK
&lt;/h3&gt;

&lt;p&gt;To use the AWS SDK for JavaScript, we must first initiate a node module for our hands-on project.&lt;/p&gt;

&lt;p&gt;To do that, first, create a folder named &lt;code&gt;webiny-hands-on-s3&lt;/code&gt; and &lt;code&gt;cd&lt;/code&gt; into that folder.&lt;/p&gt;

&lt;p&gt;Run the command &lt;code&gt;npm init&lt;/code&gt; — this will ask you to provide the project's name and you can name it as you want, in this case, we'll leave it the same as the folder name with an entry point of the &lt;code&gt;index.js&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Inside our folder, we'll create a couple of files, such as.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;createBucket.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;upload.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;listObjects.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;deleteBucket.js&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before we continue to implement any code, we need to install the AWS SDK package by running this command: &lt;code&gt;npm install aws-sdk --save&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's dive in.&lt;/p&gt;




&lt;h3&gt;
  
  
  Creating an AWS S3 Bucket
&lt;/h3&gt;

&lt;p&gt;In order to use the SDK, we have to configure the SDK package by loading it into our file. Open the createBucket.js file, and start writing the below code in your own file. In the snippet we have comments to explain to you what we're doing:&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="c1"&gt;// Load the AWS SDK for Node.js&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Set the region&lt;/span&gt;
&lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Create S3 service object&lt;/span&gt;
&lt;span class="nx"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;S3&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2006-03-01&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Create the parameters for calling createBucket -- with this part we'll take the bucket name we'll create&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;bucketParams&lt;/span&gt; &lt;span class="o"&gt;=&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Call S3 to create the buckets&lt;/span&gt;
&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createBucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;err&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="s2"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&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="s2"&gt;Success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Location&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 create your S3 bucket, with this script, we must run it and give our bucket a name like so: &lt;code&gt;node createBucket.js webiny-s3-bucket-testing&lt;/code&gt;. If it's successful, it will console log the Success message together with the location, which will be the bucket name.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uploading a file to an AWS S3 Bucket
&lt;/h3&gt;

&lt;p&gt;Open the &lt;code&gt;upload.js&lt;/code&gt; file and let's dive in. I will repeat some parts of the snippets, such as the SDK configuration, and the AWS S3 service object as shown in the above snippet. The additional part is that we have two command-line arguments, the first one will be the bucket name where you'll upload your file, and the second argument will be the file itself.&lt;/p&gt;

&lt;p&gt;Let's dive into the 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="c1"&gt;// Load the AWS SDK for Node.js&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Set the region&lt;/span&gt;
&lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Create S3 service object&lt;/span&gt;
&lt;span class="nx"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;S3&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2006-03-01&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Call S3 to retrieve upload file to specified bucket&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;uploadParams&lt;/span&gt; &lt;span class="o"&gt;=&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&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="dl"&gt;""&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="dl"&gt;""&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&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;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Configure the file stream and obtain the upload parameters&lt;/span&gt;
&lt;span class="c1"&gt;// The node.js file system module allows you to work (read, create, update, delete, rename files)&lt;/span&gt;
&lt;span class="c1"&gt;// with the file system on your computer.&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;readingFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;readingFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&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="s2"&gt;File Error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;uploadParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;readingFile&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// The path module provides utilities for working with file and directory paths.&lt;/span&gt;
&lt;span class="c1"&gt;// We can access by using this:&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;uploadParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Call S3 to retrieve upload file to specified bucket&lt;/span&gt;
&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uploadParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;err&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="s2"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&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="s2"&gt;Upload Success!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Location&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, create an &lt;code&gt;index.txt&lt;/code&gt; file in your folder, and add some text to it.&lt;/p&gt;

&lt;p&gt;Then, run the script by providing two parameters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The S3 bucket we create in the first snippet webiny-s3-bucket-testing&lt;/li&gt;
&lt;li&gt;The local file you want to upload into that S3 bucket.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The full command &lt;code&gt;node upload.js webiny-s3-bucket-testing index.txt&lt;/code&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%2Fi%2Fdo4is70o5rtimu2b9ath.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%2Fi%2Fdo4is70o5rtimu2b9ath.png" alt="upload"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎉 You just uploaded a file into your S3 bucket! &lt;/p&gt;

&lt;h3&gt;
  
  
  Listing objects in an AWS S3 Bucket
&lt;/h3&gt;

&lt;p&gt;Now, open the &lt;code&gt;listObjects.js&lt;/code&gt; file where you'll list the content of this bucket. It's again a repetitive task of configuring the SDK and creating the AWS S3 service object. What this script will do, is that we'll provide the bucket name from which we want to read the objects and the result will be a list of objects (files) or a failure message.&lt;/p&gt;

&lt;p&gt;Let's dive into the 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="c1"&gt;// Load the AWS SDK for Node.js&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Set the region&lt;/span&gt;
&lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Create S3 service object&lt;/span&gt;
&lt;span class="nx"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;S3&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2006-03-01&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Create the parameters for calling listObjects method&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;bucketParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// in here we'll provide the bucket name we created earlier&lt;/span&gt;
  &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;webiny-s3-bucket-testing&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="c1"&gt;// Call S3 to obtain a list of the objects in the bucket&lt;/span&gt;

&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listObjects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;err&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="s2"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&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="s2"&gt;Success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's run the script by running this command: &lt;code&gt;node listObjects.js&lt;/code&gt; Check out the result 😄&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%2Fi%2Faonx8mrc3hn3i7nn5qvi.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%2Fi%2Faonx8mrc3hn3i7nn5qvi.png" alt="listObjects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deleting an AWS S3 Bucket
&lt;/h3&gt;

&lt;p&gt;Move to the &lt;code&gt;deleteBucket.js&lt;/code&gt; file, and configure the SDK and create the AWS S3 service object. What you'll use in this script, comparing with the above script, is the &lt;code&gt;deleteBucket&lt;/code&gt; method. But, this case is different, we previously added objects into our bucket, right? We can't delete the AWS S3 buckets if they're not empty. That means you need to delete the objects inside the bucket first, then delete the bucket.&lt;/p&gt;

&lt;p&gt;Let's dive in.&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="c1"&gt;// Load the AWS SDK for Node.js&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Set the region&lt;/span&gt;
&lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Create S3 service object&lt;/span&gt;
&lt;span class="nx"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;S3&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2006-03-01&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Create params for S3.deleteBucket&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;bucketParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// here you'll provide the name of the bucket you want to delete&lt;/span&gt;
  &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;webiny-s3-bucket-testing&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="c1"&gt;// We'll first empty the bucket&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;emptyS3Bucket&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;listParams&lt;/span&gt; &lt;span class="o"&gt;=&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="c1"&gt;// Prefix: dir,&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;listedObjects&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;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listObjectsV2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listParams&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listedObjects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Contents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deleteParams&lt;/span&gt; &lt;span class="o"&gt;=&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;Delete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Objects&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;span class="nx"&gt;listedObjects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Contents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;Key&lt;/span&gt; &lt;span class="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="nx"&gt;deleteParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Delete&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Objects&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;Key&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deleteObjects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deleteParams&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listedObjects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IsTruncated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;emptyS3Bucket&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="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;emptyS3Directory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketParams&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="c1"&gt;// Call S3 to delete the bucket&lt;/span&gt;
&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deleteBucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;err&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="s2"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&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="s2"&gt;Success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;How-to&lt;/code&gt; on S3 - Cheatsheet
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Download an entire AWS S3 bucket&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;1.1 Install the AWS Command Line Tools&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo easy_install awscli
// or
sudo pip install awscli
// or
brew install awscli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1.2 Run these commands:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws s3 sync s3://&amp;lt;source_bucket&amp;gt; &amp;lt;local_destination&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;aws s3 sync s3://mybucket&lt;/code&gt;. Will download all the objects in &lt;code&gt;mybucket&lt;/code&gt; to the current directory. And will output: &lt;code&gt;download: s3://mybucket/test.txt to test.txt&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Are AWS S3 buckets region-specific?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The user interface shows all your buckets, in all regions. But buckets exist in a specific region and you need to specify that region when you create a bucket.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How to Configure SSL for AWS S3 bucket?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example:&lt;code&gt;[https://s3.amazonaws.com/bucket_name/images/logo.gif](https://s3.amazonaws.com/bucket_name/images/logo.gif)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you use a custom domain for your bucket, you can use S3 and CloudFront together with your own SSL certificate (or generate a free one via Amazon Certificate Manager): &lt;a href="https://aws.amazon.com/cloudfront/custom-ssl-domains/" rel="noopener noreferrer"&gt;Amazon CloudFront Custom SSL&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Delete AWS S3 buckets&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;aws s3 rb s3://bucket-name&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;By default, the bucket must be empty for the operation to succeed. To remove a bucket that's not empty, you need to include the &lt;code&gt;--force&lt;/code&gt; option. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws s3 rb s3://bucket-name --force&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rename AWS S3 Bucket name&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is no rename bucket functionality for S3 because there are technically no folders in S3, so we have to handle every file within the bucket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws s3 mb s3://[new-bucket] // 1. Create a new bucket
aws s3 sync s3://[old-bucket] s3://[new-bucket] // 2. Copy files over
aws s3 rb --force s3://[old-bucket] // 3. Delete the old bucket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Quick way to list all files in AWS S3 bucket&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;aws s3 ls&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AWS S3 copy files and folders between two buckets&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;aws s3 sync s3://DOC-EXAMPLE-BUCKET-SOURCE s3://DOC-EXAMPLE-BUCKET-TARGET&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Is it better to have multiple s3 buckets or one bucket with sub folders?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By default, you can create up to 100 buckets in each of your AWS accounts. If you need additional buckets, you can increase your bucket limit by submitting a service limit increase. &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html" rel="noopener noreferrer"&gt;Source&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The total volume of data and the number of objects you can store are unlimited. &lt;a href="https://aws.amazon.com/s3/faqs/" rel="noopener noreferrer"&gt;Source&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;*Object Storage — Also known as object-based storage, is a strategy that manages and manipulates data storage as distinct units, called objects. There are three key components of an object — the content of the object (data stored in the object such as a file or directory), the unique object identifier (ID), and metadata. It stores the metadata as key-pair values and contains information such as name, size, date, security attributes, content type, and URL. Each object has an access control list (ACL) to configure who may access the object.&lt;/p&gt;




&lt;p&gt;Now that you've used AWS SDK for S3, you're able to code the solutions that the AWS S3 Console provides via a few clicks, which is faster but, using the SDK you'll be able to continue developing your applications using the AWS services directly by coding. This is a significant advantage for those interested in building applications using AWS services. In this tutorial, we used the AWS SDK to create buckets, upload data, listing data from the buckets, empty, and afterward deleting buckets via AWS SDK for JavaScript for Node.js.&lt;/p&gt;




&lt;p&gt;If you learned something new today and are interested to follow up on our blogs, &lt;a href="https://landing.mailerlite.com/webforms/landing/g9f1i1" rel="noopener noreferrer"&gt;subscribe&lt;/a&gt; to our newsletter and we'll provide you the best content of the serverless world!&lt;/p&gt;




&lt;p&gt;Thanks for reading! My name is Albiona and I work as a developer relations engineer at &lt;a href="https://www.webiny.com/?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-weekly-tech-blog-cross-promotion-jan-25&amp;amp;utm_content=webiny-get-started-with-aws-s3&amp;amp;utm_term=W00495" rel="noopener noreferrer"&gt;Webiny&lt;/a&gt;. I enjoy learning new tech and building communities around them = ) If you have questions or just want to say hi, reach out to me via &lt;a href="https://twitter.com/albionaitoh" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>beginners</category>
      <category>cloud</category>
      <category>node</category>
    </item>
    <item>
      <title>Get Started with Cloud Computing</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Tue, 19 Jan 2021 14:21:04 +0000</pubDate>
      <link>https://dev.to/webiny/get-started-with-cloud-computing-1668</link>
      <guid>https://dev.to/webiny/get-started-with-cloud-computing-1668</guid>
      <description>&lt;p&gt;Nowadays, when working on software systems, you have heard about Cloud Computing technology. Understanding cloud fundamentals is an essential part when getting started with Cloud Computing. Amazon Web Services (AWS) is one of the cloud providers that offer over 300 services. Before starting with AWS, understand cloud concepts such as what is cloud computing, the advantages of using cloud computing, cloud computing types, and cloud deployment models.&lt;/p&gt;

&lt;p&gt;In this article, we'll cover the concepts you need to build that solid foundation to implement Cloud Computing technologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Cloud Computing
&lt;/h2&gt;

&lt;p&gt;Cloud computing gives you the option to transform IT infrastructure into a utility - which means you can get into your IT infrastructure via the internet, using computing resources on the cloud. Without the need to install or maintain these resources on-premises.&lt;/p&gt;

&lt;p&gt;What is on-premise you might ask? Going with the on-premise way, you must manage your own servers, hire IT people, payor rent the real-estate for the servers.&lt;/p&gt;

&lt;p&gt;The opposite of on-premise is the cloud providers, who provide you these services via the internet. The cloud providers are companies who own the servers, hire IT people, pay and manage the real estate for the servers. Those companies give you the option to manage the configuration of the cloud services you use, and your code and they take care of the rest.&lt;/p&gt;

&lt;p&gt;Simply put, Cloud Computing offers you on-demand access, through the internet to cloud computing resources, applications, servers (physical and virtual servers), data storage, development tools, networking capabilities, and more — hosted at remote data centers that are managed by cloud service providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of Using Cloud Computing
&lt;/h2&gt;

&lt;p&gt;We learned what on-premise IT is, the traditional way of managing IT infrastructure. Based on the differences between on-premise and cloud computing provider solutions, there are some obvious benefits you get when using cloud computing resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lower total cost of ownership (TCO)
&lt;/h3&gt;

&lt;p&gt;For all the attributes of having your on-premise infrastructure that we mentioned such as managing your own servers, hiring the IT people, paying or renting the real-estate for the servers, those all come up with a price, and with the cloud computing technology, you eliminate the capital expenses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agility
&lt;/h3&gt;

&lt;p&gt;In just a few clicks you're able to get up and running the computing resources you need for your applications — As Webiny's CEO &lt;a href="https://twitter.com/SvenAlHamad"&gt;Sven&lt;/a&gt; noted on the &lt;a href="https://www.serverlesschats.com/"&gt;Serverless Chats podcast&lt;/a&gt; by answering &lt;a href="https://www.jeremydaly.com/"&gt;Jeremy&lt;/a&gt;'s question &lt;a href="https://www.youtube.com/watch?v=9TSmOcLBr0k&amp;amp;t=2039s"&gt;"What are the benefits of serverless for both small and big companies?"&lt;/a&gt; - "When using serverless, the cost of managing infrastructure will go way down, by releasing a big chunk of the budget or resources or working hours, that you can now focus on product iterations, so your product can grow faster. And if your product grows faster, you can out-innovate potential competitors, which can't afford that same level of innovation."&lt;/p&gt;

&lt;h3&gt;
  
  
  Scale and Performance
&lt;/h3&gt;

&lt;p&gt;The two most important benefits you get when switching to cloud computing technologies is when you want your customers to have an amazing user experience using your product, anywhere - that means in the lowest or highest spikes of your product's traffic. Cloud computing services run on a worldwide network, so they're able to provide you the ability to scale and deliver the resources when they're needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Cloud Computing Services
&lt;/h2&gt;

&lt;p&gt;The cloud computing services fall into four different categories: Infrastructure as a Service (&lt;strong&gt;IaaS&lt;/strong&gt;), Platform as a Service (&lt;strong&gt;PaaS&lt;/strong&gt;), Serverless, and Software as a Service (&lt;strong&gt;SaaS&lt;/strong&gt;). They are all built up on top of one another. We'll go through them to understand what they are and the differences between them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure as a Service (IaaS)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;IaaS&lt;/strong&gt; represent the building blocks for cloud IT by providing access to networking features, computers, and data storage space. You can use those resources to build your own products. These are offered by different cloud provider companies on a pay-as-you-go basis. Some examples of cloud providers are &lt;a href="https://aws.amazon.com/"&gt;Amazon Web Services (AWS)&lt;/a&gt;, &lt;a href="https://cloud.google.com/"&gt;Google Cloud Platform&lt;/a&gt;, and &lt;a href="https://azure.microsoft.com/en-us/"&gt;Microsoft Azure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;— Intended for Admins&lt;/p&gt;

&lt;h3&gt;
  
  
  Platform as a Service (PaaS)
&lt;/h3&gt;

&lt;p&gt;I'm assuming you are a software developer? Well, this cloud computing category is designed for you. &lt;strong&gt;PaaS&lt;/strong&gt; offers cloud computing services with an on-demand environment for development, testing, delivering, and managing software applications. This will make it easier for developers to create web or mobile applications, without worrying about the infrastructure, storage, network, and databases needed for development.&lt;/p&gt;

&lt;p&gt;Some examples of PaaS are the &lt;a href="https://aws.amazon.com/lambda/"&gt;AWS Lambda Service&lt;/a&gt;, &lt;a href="https://www.heroku.com/"&gt;Heroku&lt;/a&gt;, etc.&lt;/p&gt;

&lt;p&gt;— Intended for Developers&lt;/p&gt;

&lt;h3&gt;
  
  
  Serverless Computing
&lt;/h3&gt;

&lt;p&gt;I'll mention the definition of serverless computing based on Webiny's guide to serverless ⬇️&lt;/p&gt;

&lt;p&gt;"Serverless means there are no servers you have to operate to run a particular service or an app. Usually, in Serverless architectures, you rely on services that are managed for you. Be that function-as-a-service, storage-as-a-service, and others. Using managed services means all the maintenance and operational tasks are abstracted away. Yes, there are still servers there, but they are no longer your responsibility to manage."&lt;/p&gt;

&lt;p&gt;Some of the examples that offer serverless services are &lt;a href="https://aws.amazon.com/lambda/"&gt;AWS Lambda Service&lt;/a&gt;, &lt;a href="https://workers.cloudflare.com/"&gt;Cloudflare Workers&lt;/a&gt;, &lt;a href="https://cloud.google.com/functions/"&gt;Google Cloud Functions&lt;/a&gt;, &lt;a href="https://www.ibm.com/cloud/functions"&gt;IBM Cloud Functions&lt;/a&gt;, &lt;a href="https://cloud.google.com/knative/"&gt;Knative&lt;/a&gt;, &lt;a href="https://azure.microsoft.com/en-us/services/functions/"&gt;Microsoft Azure Functions&lt;/a&gt;, &lt;a href="https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions001.htm"&gt;Oracle Functions&lt;/a&gt;. When it comes to building serverless applications and APIs on top of these services, &lt;a href="https://www.webiny.com/"&gt;Webiny&lt;/a&gt; takes the lead! Webiny is a serverless framework — a complete plugin-based admin interface and a set of ready-made serverless applications. Learn more about &lt;a href="https://www.webiny.com/"&gt;Webiny&lt;/a&gt; features here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Software as a Service (SaaS)
&lt;/h3&gt;

&lt;p&gt;SaaS takes place when cloud providers offer complete software products. The infrastructure, product maintenance, security its managed by the cloud provider. Some examples of this cloud computing category are &lt;a href="https://www.salesforce.com/"&gt;Salesforce&lt;/a&gt;, &lt;a href="https://mail.google.com/"&gt;Gmail&lt;/a&gt;, &lt;a href="https://www.office.com/?ui=hy-AM&amp;amp;rs=ET"&gt;Office 336&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;— Intended for Customers&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud Deployment Models
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Public Cloud
&lt;/h3&gt;

&lt;p&gt;With this type of deployment model, you'll have access to anything the cloud provider offers, from &lt;strong&gt;SaaS&lt;/strong&gt; applications, virtual machines (&lt;strong&gt;VMs&lt;/strong&gt;), infrastructure, and development platforms — available to users via the public internet. Different cloud providers offer these services in different pricing models such as subscription-based, or pay-per-use.&lt;/p&gt;

&lt;p&gt;One of the known characteristics of the &lt;strong&gt;Cloud&lt;/strong&gt; is the multi-tenant* environment—the data centers infrastructure is shared by all public cloud customers. This leads to one or more disadvantages of the &lt;strong&gt;Cloud&lt;/strong&gt; such as &lt;strong&gt;limited resources&lt;/strong&gt; → Even though they have incredible computing power, they share their resources with multiple tenants.&lt;/p&gt;

&lt;p&gt;Some examples of companies using the cloud deployment models are &lt;a href="https://www.squarespace.com/website-design"&gt;Squarespace&lt;/a&gt;, &lt;a href="https://basecamp.com/"&gt;Basecamp&lt;/a&gt;, and &lt;a href="https://www.dropbox.com/"&gt;Dropbox&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Multi-tenant&lt;/strong&gt; → When a single instance of a software application serves multiple tenants (or user accounts).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tenant&lt;/strong&gt; → Can be an individual user, but more often is a group of users that share common access and privileges within that instance of a software application.&lt;/p&gt;

&lt;h3&gt;
  
  
  On-Premise || Private Cloud
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;on-premise&lt;/strong&gt; cloud refers to the cloud computing resources being used by one organization or customer → sometimes is called a private cloud. One reason is the security that the on-premise offers for sensitive data for customers such as Government, Hospitals, Enterprises with different regulations. The on-premise cloud is hosted in the customer's data center, but it has the option to combine the hosting on an independent cloud provider's infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hybrid Cloud
&lt;/h3&gt;

&lt;p&gt;A combination of the public cloud and on-premise → connecting an organization's on-premise cloud services and public clouds into a single infrastructure for all the organization's applications.&lt;/p&gt;

&lt;p&gt;The goal is to have an optimal solution for each of the organization's applications to do the workloads between the two — based on the current requirements.&lt;/p&gt;

&lt;p&gt;Using a &lt;strong&gt;Hybrid cloud&lt;/strong&gt; gives organizations the freedom to meet their business and technical objectives with benefits such as &lt;strong&gt;lower costs&lt;/strong&gt; and &lt;strong&gt;efficiency&lt;/strong&gt; rather than using just public or on-premise cloud.&lt;/p&gt;




&lt;p&gt;Now that you know the cloud computing concepts, I think you are ready to start with some examples of cloud computing services or you can follow the blog on &lt;a href="https://www.webiny.com/blog/5-aws-services-you-need-to-know-for-web-development"&gt;5 AWS services you need for web development&lt;/a&gt;!&lt;/p&gt;




&lt;p&gt;If you learned something new today and are interested to follow up on our blogs, &lt;a href="https://landing.mailerlite.com/webforms/landing/g9f1i1"&gt;subscribe to our newsletter&lt;/a&gt; and we'll provide you the best content of the serverless world!&lt;/p&gt;




&lt;p&gt;Thanks for reading! My name is Albiona and I work as a developer relations engineer at &lt;a href="https://www.webiny.com/"&gt;Webiny&lt;/a&gt;. I enjoy learning new tech and building communities around them = ) If you have questions or just want to say hi, reach out to me via &lt;a href="https://twitter.com/albionaitoh"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>beginners</category>
      <category>cloudskills</category>
    </item>
    <item>
      <title>5 AWS Services you need to know for Web Development</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Wed, 13 Jan 2021 13:41:49 +0000</pubDate>
      <link>https://dev.to/webiny/5-aws-services-you-need-to-know-for-web-development-1c58</link>
      <guid>https://dev.to/webiny/5-aws-services-you-need-to-know-for-web-development-1c58</guid>
      <description>&lt;p&gt;If you're getting started with AWS and you're interested to build your web applications using AWS services in a short amount of time, then you're in the right place. AWS offers more than 300 services, and to start developing applications with AWS without the right information might be a huge burden. As for today, we'll provide to you only 5 AWS services you need to know, to develop your web application.&lt;/p&gt;

&lt;p&gt;Without further ado, let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Amazon Web Services
&lt;/h2&gt;

&lt;p&gt;Our top 5 picks of AWS services are:&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS S3
&lt;/h3&gt;

&lt;h3&gt;
  
  
  AWS API Gateway
&lt;/h3&gt;

&lt;h3&gt;
  
  
  AWS Lambda
&lt;/h3&gt;

&lt;h3&gt;
  
  
  AWS DynamoDB
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  Extra AWS Service - AWS Cognito
&lt;/h3&gt;




&lt;p&gt;For each service, we will go through &lt;strong&gt;what is the service&lt;/strong&gt;, what are the &lt;strong&gt;benefits&lt;/strong&gt; of using one, &lt;strong&gt;the pricing&lt;/strong&gt;, and &lt;strong&gt;how to get started&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Follow the &lt;a href="https://www.webiny.com/blog/5-aws-services-you-need-to-know-for-web-development?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-weekly-blog-jan-11&amp;amp;utm_content=webiny-5-aws-services-you-need-for-web-development&amp;amp;utm_term=W00473"&gt;article here&lt;/a&gt; to get into the details of the services you need for web development!
&lt;/h3&gt;




&lt;p&gt;Now that you have the tools you need, building your web applications with AWS is an amazing experience considering the benefits it offers for developers. And if you want to go one step further, try &lt;a href="https://www.webiny.com/?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-weekly-blog-jan-11&amp;amp;utm_content=webiny-5-aws-services-you-need-for-web-development&amp;amp;utm_term=W00472"&gt;Webiny&lt;/a&gt; — &lt;a href="https://www.webiny.com/?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-weekly-blog-jan-11&amp;amp;utm_content=webiny-5-aws-services-you-need-for-web-development&amp;amp;utm_term=W00472"&gt;Webiny&lt;/a&gt; is an open-source serverless application framework that brings all those tools together. Start building your serverless applications using Webiny. today 🚀&lt;/p&gt;




&lt;p&gt;Thanks for reading! My name is Albiona and I work as a developer relations engineer at Webiny. I enjoy learning new tech and building communities around them = ) If you have questions or just want to say hi, reach out to me via &lt;a href="https://twitter.com/albionaitoh"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>AWS re:Invent - Webiny's Top 5 Picks on Serverless Announcements</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Mon, 21 Dec 2020 18:29:17 +0000</pubDate>
      <link>https://dev.to/webiny/aws-re-invent-webiny-s-top-5-picks-on-serverless-announcements-330m</link>
      <guid>https://dev.to/webiny/aws-re-invent-webiny-s-top-5-picks-on-serverless-announcements-330m</guid>
      <description>&lt;p&gt;Today we'll present to you &lt;a href="https://www.webiny.com/?utm_source=Dev-to&amp;amp;utm_medium=webiny-site&amp;amp;utm_campaign=webiny-cross-promotion-dec-21&amp;amp;utm_content=webiny-aws-top-5-serverless-announcements&amp;amp;utm_term=W00443"&gt;Webiny&lt;/a&gt;'s top 5 picks on serverless announcements. We've been active during the past three weeks on live announcements of AWS re:Invent, focusing on the serverless news that can affect the way we develop software solutions from the cost and performance perspective.&lt;/p&gt;

&lt;p&gt;Without further ado, let's go through the top 5 picks from our team @ &lt;a href="https://www.webiny.com/?utm_source=Dev-to&amp;amp;utm_medium=webiny-site&amp;amp;utm_campaign=webiny-cross-promotion-dec-21&amp;amp;utm_content=webiny-aws-top-5-serverless-announcements&amp;amp;utm_term=W00443"&gt;Webiny&lt;/a&gt; ⬇️&lt;/p&gt;

&lt;h2&gt;
  
  
  1. AWS Lambda
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1. Lambda changes billing to per ms
&lt;/h3&gt;

&lt;p&gt;Lambda now will bill your functions by the ms, as opposed to a round of 100ms.&lt;/p&gt;

&lt;p&gt;"For example, a function that runs in 30ms on average used to be billed for 100ms. Now, it will be billed for 30ms resulting in a 70% drop in its duration spend."&lt;/p&gt;

&lt;p&gt;For more details and information about pricing check out the article &lt;a href="https://aws.amazon.com/about-aws/whats-new/2020/12/aws-lambda-changes-duration-billing-granularity-from-100ms-to-1ms/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2. Lambda now supports 10 GB memory and 6 vCPU cores for Lambda Functions
&lt;/h3&gt;

&lt;p&gt;Lambda increased the memory limit by 3x compared to the previous limit, from 3,008 MB up to 10,240 MB (10 GB) 🚀&lt;/p&gt;

&lt;p&gt;This helps to perform memory-intensive operations at scale.&lt;/p&gt;

&lt;p&gt;Starting today you can configure between 128 MB and 10.140 MB of memory for new or existing Lambda functions.&lt;/p&gt;

&lt;p&gt;For more details check out the article &lt;a href="https://aws.amazon.com/about-aws/whats-new/2020/12/aws-lambda-supports-10gb-memory-6-vcpu-cores-lambda-functions/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3. Lambda supports container images as a packaging format
&lt;/h3&gt;

&lt;p&gt;Package the Lambda functions and deploy as a container image up to 10 GB. Now you have the chance to build and use Lambda based applications using container tooling, workflows, and dependencies.&lt;/p&gt;

&lt;p&gt;Some advantages of Lambda packaging:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Operational simplicity&lt;/li&gt;
&lt;li&gt;Automatic scaling&lt;/li&gt;
&lt;li&gt;High availability&lt;/li&gt;
&lt;li&gt;Native integrations with 140 AWS services&lt;/li&gt;
&lt;li&gt;"With this launch, AWS provides a set of base images for Lambda that are available on ECR Public and Docker Hub."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details check out the article &lt;a href="https://aws.amazon.com/about-aws/whats-new/2020/12/aws-lambda-now-supports-container-images-as-a-packaging-format/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.4. Lambda Runtime Logs API
&lt;/h3&gt;

&lt;p&gt;You can now subscribe to log streams directly from within the Lambda execution environment.&lt;/p&gt;

&lt;p&gt;"After receiving the subscription request, the Lambda service streams logs to the extension, and the extension can then process, filter, and send them to any preferred destination."&lt;/p&gt;

&lt;p&gt;This extension supersedes the CloudWatch Logs, making it easier for you to use your preferred extensions for diagnostics.&lt;/p&gt;

&lt;p&gt;For more details on how to get started with the extension, follow the article &lt;a href="https://aws.amazon.com/blogs/compute/using-aws-lambda-extensions-to-send-logs-to-custom-destinations/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. AWS Aurora Serverless v2
&lt;/h2&gt;

&lt;p&gt;Extending the features of Aurora Serverless, this is one of the biggest announcements on the first week of AWS re:Invent.&lt;/p&gt;

&lt;p&gt;One of the key features: "You pay only for the capacity your application consumes, and you can save up to 90% of your database cost compared to the cost of provisioning capacity for peak load."&lt;/p&gt;

&lt;p&gt;Amazon Aurora Serverless v2 also provides the full breadth of Amazon Aurora’s capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-AZ support,&lt;/li&gt;
&lt;li&gt;Global Database, and&lt;/li&gt;
&lt;li&gt;Read replicas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details, check out the in-house AWS article &lt;a href="https://aws.amazon.com/about-aws/whats-new/2020/12/introducing-the-next-version-of-amazon-aurora-serverless-in-preview/"&gt;here&lt;/a&gt;, or follow the &lt;a href="https://www.jeremydaly.com/"&gt;Jeremy Daly&lt;/a&gt;'s preview on &lt;a href="https://www.jeremydaly.com/aurora-serverless-v2-preview/"&gt;"Aurora Serverless v2: The Good, the Better, and the Possibly Amazing"&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. AWS Proton
&lt;/h2&gt;

&lt;p&gt;"Automated management for container and serverless deployments"&lt;/p&gt;

&lt;p&gt;AWS Proton is the first application to fully manage and deploy container and serverless applications.&lt;/p&gt;

&lt;p&gt;With AWS Proton, engineering teams can connect and coordinate all the different tools needed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure Provisioning,&lt;/li&gt;
&lt;li&gt;Code Deployments&lt;/li&gt;
&lt;li&gt;Monitoring, and&lt;/li&gt;
&lt;li&gt;Updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To learn more about what AWS Proton solves on the software systems complexities, check out the article &lt;a href="https://aws.amazon.com/proton/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. AWS S3
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1. S3 Replication adds support for multiple destinations
&lt;/h3&gt;

&lt;p&gt;You can replicate data from one source bucket to multiple destination buckets at the same or different AWS regions.&lt;/p&gt;

&lt;p&gt;This is intended for you if you're interested to maintain multiple copies of your data in one or more AWS Regions.&lt;/p&gt;

&lt;p&gt;"With S3 Replication (multi-destination), you can easily create a shared dataset by replicating data to multiple buckets in the same or different AWS Regions."&lt;/p&gt;

&lt;p&gt;For more details on S3 features and the pricing page, check out the article &lt;a href="https://aws.amazon.com/s3/pricing/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2. S3 adds read-after-write consistency automatically for applications
&lt;/h3&gt;

&lt;p&gt;S3 delivers strong read-after-write consistency for any storage request. With the strong consistency, S3 is removing the need to make changes to apps and reduces costs by removing the need for extra infrastructure which provided strong consistency.&lt;/p&gt;

&lt;p&gt;This &lt;a href="https://aws.amazon.com/blogs/aws/amazon-s3-update-strong-read-after-write-consistency/"&gt;blog post&lt;/a&gt; guides you on more details on react-after-write consistency.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3. S3 supports two-way replication for object metadata changes
&lt;/h3&gt;

&lt;p&gt;If you want to build shared datasets across multiple regions and keep all object and object metadata changes in sync then two-way replication is important.&lt;/p&gt;

&lt;p&gt;Learn more about the S3 Replication &lt;a href="https://aws.amazon.com/s3/features/replication/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. DynamoDB supports export to S3
&lt;/h2&gt;

&lt;p&gt;You can now export your Amazon DynamoDB table data to your data lake in AWS S3 where you can use different services such as Athena.&lt;/p&gt;

&lt;p&gt;Your DynamoDB data added in your AWS S3 data is easily discovered, encrypted at rest, and in transit.&lt;/p&gt;

&lt;p&gt;With just a few clicks in the AWS Management Console and a simple API call, you can export DynamoDB tables ranging from a few megabytes to hundreds of terabytes of data.&lt;/p&gt;

&lt;p&gt;Learn more about this announcement &lt;a href="https://aws.amazon.com/about-aws/whats-new/2020/11/now-you-can-export-your-amazon-dynamodb-table-data-to-your-data-lake-in-amazon-s3-to-perform-analytics-at-any-scale/"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;These were &lt;a href="https://www.webiny.com/?utm_source=Dev-to&amp;amp;utm_medium=webiny-site&amp;amp;utm_campaign=webiny-cross-promotion-dec-21&amp;amp;utm_content=webiny-aws-top-5-serverless-announcements&amp;amp;utm_term=W00443"&gt;Webiny&lt;/a&gt;'s top 5 picks on Serverless Announcements @ AWS re:Invent. If you're interested in our future blog posts,  &lt;strong&gt;&lt;a href="https://landing.mailerlite.com/webforms/landing/g9f1i1"&gt;subscribe&lt;/a&gt;&lt;/strong&gt; to our &lt;strong&gt;newsletter&lt;/strong&gt; and you'll be notified when we have interesting topics to share!&lt;/p&gt;




&lt;p&gt;Thanks for reading! My name is &lt;a href="https://twitter.com/albionaitoh"&gt;Albiona&lt;/a&gt; and I work as a developer relations engineer at &lt;a href="https://www.webiny.com/?utm_source=Dev-to&amp;amp;utm_medium=webiny-site&amp;amp;utm_campaign=webiny-cross-promotion-dec-21&amp;amp;utm_content=webiny-aws-top-5-serverless-announcements&amp;amp;utm_term=W00443"&gt;Webiny&lt;/a&gt;. I enjoy learning new tech and building communities around them = ) If you have questions or just want to say hi, reach out to me via &lt;a href="https://twitter.com/albionaitoh"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What is IDaaS and Why Use One?</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Tue, 15 Dec 2020 18:04:33 +0000</pubDate>
      <link>https://dev.to/webiny/what-is-idaas-and-why-use-one-4773</link>
      <guid>https://dev.to/webiny/what-is-idaas-and-why-use-one-4773</guid>
      <description>&lt;p&gt;If you're reading this article, you might be interested to learn how to implement user management for your application, understanding the complete picture of how identity management services work. That's what we'll do in this article. You'll learn what is Identity as a Service (IDaaS), why to use such a service, what is Single Sign-On (SSO), and IDaaS platforms.&lt;/p&gt;

&lt;p&gt;Let's dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an Identity Provider as a Service (IDaaS)?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Manual user identity management
&lt;/h3&gt;

&lt;p&gt;In order to get access to an application, back in the days, you would have to share your credentials such as your username and password with the application maintainers.&lt;/p&gt;

&lt;p&gt;For a developer, user identity management is a complex feature to build and manage, especially security-wise. You'd be responsible if someone would gain access (hack) into the users' identities and use those for their purposes.&lt;/p&gt;

&lt;p&gt;Let's go through a real-life scenario where your client has requested to implement the Login/Registration feature for the application you're building.&lt;/p&gt;

&lt;p&gt;Inspired by the &lt;a href="https://dev.to/"&gt;dev.to&lt;/a&gt; platform, as seen in the image below, your client wants to give the users an option to access the application using social accounts such as Twitter or GitHub.&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%2Fi%2Fd8j1u5p0nskmj5jfls60.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%2Fi%2Fd8j1u5p0nskmj5jfls60.png" alt="dev-to-login"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Follow the article &lt;a href="https://www.webiny.com/blog/what-is-idaas-and-why-use-one?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-cross-promotion-dec-15&amp;amp;utm_content=webiny-idaas-blog&amp;amp;utm_term=W00422" rel="noopener noreferrer"&gt;here&lt;/a&gt; to read the below titles 🚀
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Open Authentication and OpenID Connect protocols
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Identity as a Service provider (IDaaS)
&lt;/h4&gt;

&lt;h4&gt;
  
  
  How does IDaaS actually work?
&lt;/h4&gt;

&lt;h4&gt;
  
  
  What is SSO?
&lt;/h4&gt;

&lt;h4&gt;
  
  
  The key benefits of SSO Login
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Why should you use an IDaaS provider?
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Customer Benefits of Using an IDaaS
&lt;/h5&gt;

&lt;h5&gt;
  
  
  Business Benefits of Using an IDaaS
&lt;/h5&gt;

&lt;h4&gt;
  
  
  What are the most popular IDaaS providers?
&lt;/h4&gt;




&lt;p&gt;Now that you clearly understand Identity Providers and what they offer, you'll be able to decide if you want to use such a service and focus on building business value or continue using and maintaining a custom authentication solution. If you're interested in our future blog posts, &lt;a href="https://landing.mailerlite.com/webforms/landing/g9f1i1" rel="noopener noreferrer"&gt;subscribe&lt;/a&gt; to our &lt;strong&gt;newsletter&lt;/strong&gt; and you'll be notified when we have interesting topics to share!&lt;/p&gt;




&lt;p&gt;Thanks for reading! My name is &lt;strong&gt;Albiona&lt;/strong&gt; and I work as a developer relations engineer at &lt;a href="https://www.webiny.com/?utm_source=Dev-to&amp;amp;utm_medium=webiny-site&amp;amp;utm_campaign=webiny-cross-promotion-dec-15&amp;amp;utm_content=webiny-website-dev-to&amp;amp;utm_term=W00423" rel="noopener noreferrer"&gt;Webiny&lt;/a&gt;. I enjoy learning new tech and building communities around them = ) If you have questions or just want to say hi, reach out to me via &lt;a href="https://twitter.com/albionaitoh" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>security</category>
    </item>
    <item>
      <title>Build an E-commerce Website with Webiny Serverless Headless CMS, Next.js, and Stripe</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Mon, 16 Nov 2020 15:53:50 +0000</pubDate>
      <link>https://dev.to/webiny/build-an-e-commerce-website-with-webiny-serverless-headless-cms-next-js-and-stripe-22cd</link>
      <guid>https://dev.to/webiny/build-an-e-commerce-website-with-webiny-serverless-headless-cms-next-js-and-stripe-22cd</guid>
      <description>&lt;p&gt;In this tutorial, we will create a simple e-commerce website, where you can buy Swag from the best Open Source projects such as Webiny, Next.js, React, etc.&lt;/p&gt;

&lt;p&gt;Before we continue, let's go through what you'll learn about building this website.&lt;/p&gt;

&lt;p&gt;You will learn how to create the back-end using Webiny Headless CMS and set up two content models, the products, and the categories. Afterward, we'll fetch the data from the Headless CMS to the Next.js project using Apollo GraphQL. Last but not least, we'll integrate Stripe to implement a checkout experience.&lt;/p&gt;

&lt;p&gt;First, let's take a look at the diagram of what we'll build ⬇️&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%2Fi%2Fg3rc9tphwep6scswwrzt.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%2Fi%2Fg3rc9tphwep6scswwrzt.png" alt="diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial, you'll go through the sections below:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The e-commerce-starter
&lt;/h3&gt;

&lt;h3&gt;
  
  
  2. Webiny Headless CMS
&lt;/h3&gt;

&lt;h3&gt;
  
  
  3. Next.js + Apollo GraphQL to fetch data from the backend
&lt;/h3&gt;

&lt;h3&gt;
  
  
  4. Next.js + Stripe to create the payment intents
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Follow the tutorial &lt;a href="https://www.webiny.com/blog/tutorial-e-commerce-nextjs-stripe?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-cross-promotion-nov-16&amp;amp;utm_content=webiny-e-commerce-tutorial&amp;amp;utm_term=W00378" rel="noopener noreferrer"&gt;here&lt;/a&gt; 🚀
&lt;/h3&gt;




&lt;p&gt;Thanks for reading! My name is Albiona and I work as a developer relations engineer at Webiny. I enjoy learning new tech and building communities around them = ) If you have any questions, comments, or just wanna say hi, feel free to reach out to me via &lt;a href="https://twitter.com/albionaitoh" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>graphql</category>
      <category>beginners</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Build a Portfolio Website with React, Webiny, and Apollo</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Tue, 10 Nov 2020 14:54:52 +0000</pubDate>
      <link>https://dev.to/webiny/build-a-portfolio-website-with-react-webiny-and-apollo-3bka</link>
      <guid>https://dev.to/webiny/build-a-portfolio-website-with-react-webiny-and-apollo-3bka</guid>
      <description>&lt;p&gt;In this tutorial, you will set up a simple portfolio website to showcase your projects and your blogs using pure React, Webiny Headless CMS, and Apollo GraphQL. After setting up your portfolio website, you will be able to focus all of your creativity on the content for blogs and projects.&lt;/p&gt;

&lt;p&gt;These are the features of the Portfolio Website:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 Content types: Blogs, Projects&lt;/li&gt;
&lt;li&gt;6 Created blogs&lt;/li&gt;
&lt;li&gt;6 Created projects&lt;/li&gt;
&lt;li&gt;Apollo Client to fetch the content models data&lt;/li&gt;
&lt;li&gt;Responsive design using Material UI React Components&lt;/li&gt;
&lt;li&gt;Front-end deployment with Vercel&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Demo
&lt;/h1&gt;

&lt;p&gt;Here is what we'll build: &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%2Fi%2F6karok46ia8sdgz94jlk.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%2Fi%2F6karok46ia8sdgz94jlk.png" alt="blogs (1)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or, you can &lt;a href="http://docs.webiny.com/docs/tutorials/build-a-portfolio-website-with-react-webiny-apollo/#11-webiny-headless-cms-project?utm_source=Dev-to&amp;amp;utm_medium=webiny-docs&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-doc-headless-cms-react-portfolio&amp;amp;utm_term=W00363" rel="noopener noreferrer"&gt;Watch the live demo&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://docs.webiny.com/docs/get-started/quick-start/?utm_source=Dev-to&amp;amp;utm_medium=webiny-docs&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-doc-quick-start-page&amp;amp;utm_term=W00364" rel="noopener noreferrer"&gt;A Webiny Project&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First of all, make sure you follow the &lt;a href=""&gt;prerequisites&lt;/a&gt; to create a &lt;a href="https://docs.webiny.com/docs/get-started/quick-start/#prerequisites?utm_source=Dev-to&amp;amp;utm_medium=webiny-docs&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-doc-quick-start-page&amp;amp;utm_term=W00364" rel="noopener noreferrer"&gt;Webiny project&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Follow the tutorial &lt;a href="http://docs.webiny.com/docs/guides/serverless-applications/headless-cms/build-a-portfolio-website-with-react-webiny-apollo?utm_source=Dev-to&amp;amp;utm_medium=webiny-docs&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-doc-portfolio-website-react-headless-cms&amp;amp;utm_term=W00365" rel="noopener noreferrer"&gt;here&lt;/a&gt; 🚀
&lt;/h1&gt;




&lt;p&gt;Thanks for reading! My name is Albiona and I work as a developer relations engineer at Webiny. I enjoy learning new tech and building communities around them = ) If you have any questions, comments, or just wanna say hi, feel free to reach out to me via &lt;a href="https://twitter.com/albionaitoh" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>react</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Creating a blog with Webiny Headless CMS + Gatsby</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Tue, 10 Nov 2020 14:03:38 +0000</pubDate>
      <link>https://dev.to/webiny/creating-a-blog-with-headless-cms-gatsby-43ec</link>
      <guid>https://dev.to/webiny/creating-a-blog-with-headless-cms-gatsby-43ec</guid>
      <description>&lt;p&gt;In this tutorial we will learn how to use &lt;a href="https://www.gatsbyjs.com/" rel="noopener noreferrer"&gt;Gatsby&lt;/a&gt; with the &lt;a href="https://www.webiny.com/serverless-app/headless-cms?utm_source=Dev-to&amp;amp;utm_medium=webiny-docs&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-doc-blog-site-gatsby-headless-cms&amp;amp;utm_term=W00355" rel="noopener noreferrer"&gt;Webiny Headless CMS&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All of the code shown in this tutorial is also hosted in our &lt;a href="https://github.com/webiny/webiny-examples/tree/master/headlesscms-gatsby?utm_source=Dev-to&amp;amp;utm_medium=webiny-docs&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-doc-blog-site-gatsby-headless-cms-example&amp;amp;utm_term=W00356" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Gatsby-cli
&lt;/h2&gt;

&lt;p&gt;Install &lt;code&gt;gatsby-cli&lt;/code&gt; using the command below. We will use it to create our Gatsby Blog.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g gatsby-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. A Webiny Project
&lt;/h2&gt;

&lt;p&gt;Make sure you have a working &lt;a href="http://docs.webiny.com/docs/get-started/quick-start/?utm_source=Dev-to&amp;amp;utm_medium=webiny-docs&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-doc-quick-start-page&amp;amp;utm_term=W00357" rel="noopener noreferrer"&gt;Webiny project&lt;/a&gt; set up.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Content Delivery API URL
&lt;/h2&gt;

&lt;p&gt;The Headless CMS app exposes data via the Content Delivery API, which is a simple GraphQL API that dynamically updates its schema on content model changes that you make. Once you've deployed your API stack (using the &lt;code&gt;yarn webiny deploy api&lt;/code&gt; command), you should be able to find the Content Delivery API URL in the console output:&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%2Fi%2Fn7am5c612x9ad4dpmk3a.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%2Fi%2Fn7am5c612x9ad4dpmk3a.png" alt="res"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Content Delivery API Access Token
&lt;/h2&gt;

&lt;p&gt;In order to access the data via the Content Delivery API, we'll need a valid &lt;a href="http://docs.webiny.com/docs/webiny-apps/headless-cms/features/access-tokens/?utm_source=Dev-to&amp;amp;utm_medium=webiny-docs&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-doc-access-token&amp;amp;utm_term=W00358" rel="noopener noreferrer"&gt;Access Token&lt;/a&gt;. These can be created via the Access Tokens form, which you can reach via the main menu:&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%2Fi%2Fa8k539jly8nkpk0i6eqo.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%2Fi%2Fa8k539jly8nkpk0i6eqo.png" alt="accesstoken"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a new token and make sure to copy the actual token string. We'll need it soon.&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%2Fi%2F3qx1gt1oejnt0vectynh.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%2Fi%2F3qx1gt1oejnt0vectynh.png" alt="env"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating our first content model
&lt;/h1&gt;

&lt;p&gt;Now that we have all of the prerequisites out of the way, it's time to create our first &lt;a href="http://docs.webiny.com/docs/webiny-apps/headless-cms/features/content-modeling?utm_source=Dev-to&amp;amp;utm_medium=webiny-docs&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-doc-headless-cms-content-modeling&amp;amp;utm_term=W00359" rel="noopener noreferrer"&gt;content model&lt;/a&gt;. Let's open the Models section of the Headless CMS app.&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%2Fi%2Fb9vk8qedqztox2q1a65f.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%2Fi%2Fb9vk8qedqztox2q1a65f.png" alt="content modelling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's create a new content model named &lt;code&gt;Blog Post&lt;/code&gt;. Click on the "plus" icon in the lower right corner of the screen and in the dialog that's about to be shown, enter the following:&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%2Fi%2Fk8bc6s8l6gma5ofx2ttb.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%2Fi%2Fk8bc6s8l6gma5ofx2ttb.png" alt="new-content-model-dialog"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the content model group, we'll use the &lt;code&gt;Ungrouped&lt;/code&gt;, which is the default group that comes out of the box with every Headless CMS app installation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Content model groups give you a way to organize the content models inside the main menu, allowing you to build logical sections for your content editors. You can &lt;a href="http://docs.webiny.com/docs/webiny-apps/headless-cms/features/content-modeling-groups/?utm_source=Dev-to&amp;amp;utm_medium=webiny-docs&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-doc-content-modeling-groups&amp;amp;utm_term=W00360" rel="noopener noreferrer"&gt;click here&lt;/a&gt; to learn more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once we've submitted the form in the dialog, we should be redirected to the Content Model Editor. Let's add two fields: &lt;code&gt;title&lt;/code&gt; as a &lt;code&gt;Text&lt;/code&gt;, and &lt;code&gt;body&lt;/code&gt; as a &lt;code&gt;Rich Text&lt;/code&gt; field.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;INFO: Rich Text field returns a slate object, which is not a valid React element. So, you need to parse that data to render it. You can implement your own parser or use a package created by one of our community members: &lt;a href="https://www.npmjs.com/package/webiny-richtext-serializer" rel="noopener noreferrer"&gt;webiny-richtext-serializer&lt;/a&gt;. For usage example, please see this &lt;a href="https://codesandbox.io/s/cold-frog-vfu5j?file=/src/App.js" rel="noopener noreferrer"&gt;sandbox&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They will match every blog post's title and body (content), respectively.&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%2Fi%2Fhbv4x1vm8udmo9l92cgk.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%2Fi%2Fhbv4x1vm8udmo9l92cgk.png" alt="editor-blog-post-model"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Save the changes by clicking on the &lt;code&gt;Save&lt;/code&gt; button in the top right corner of the screen.&lt;/p&gt;

&lt;p&gt;Now it's time to create the actual content. Proceed by clicking on the View content button, located on the left side of the Save button.&lt;/p&gt;

&lt;p&gt;You can also reach the content area by clicking on the newly added Blog Post item in the main menu: &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%2Fi%2Fbfn6xot9iui6eyb1cttc.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%2Fi%2Fbfn6xot9iui6eyb1cttc.png" alt="blog-post-in-menu"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Managing Content
&lt;/h1&gt;

&lt;p&gt;As mentioned, navigate to &lt;strong&gt;Headless CMS &amp;gt; Ungrouped &amp;gt; Blog Post&lt;/strong&gt; and create a blog post or two. Feel free to unleash your creativity. 😉&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%2Fi%2F1fvollu1xvsjwgvt2eng.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%2Fi%2F1fvollu1xvsjwgvt2eng.png" alt="blog-post-form (2)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you feel happy with the blog post, you can save the changes by clicking the Save button, located at the bottom of the form.&lt;/p&gt;

&lt;p&gt;The next and final step is to publish the blog post, which will make it actually visible in the Content Delivery API. To do that, click on the Publish icon, found at the right side in the form header.&lt;/p&gt;

&lt;p&gt;Now that we've covered the basics of creating content models and managing content, we can move on to the Gatsby part of this tutorial.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating a Gatsby Blog
&lt;/h1&gt;

&lt;p&gt;We can create a &lt;a href="https://www.gatsbyjs.com/docs/quick-start/" rel="noopener noreferrer"&gt;new Gatsby app&lt;/a&gt; by running &lt;code&gt;gatsby new myBlog&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;This will generate a new folder in your working directory.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ideally, you should create your Gatsby project in a folder outside of the Webiny project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we have a new Gatsby app ready to go, let's see what it takes to make a simple page that renders a list of all blog posts that we have just created.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pulling GraphQL data (Blog Posts) into Gatsby
&lt;/h1&gt;

&lt;p&gt;We will navigate to our &lt;code&gt;myBlog&lt;/code&gt; folder created earlier and install NPM package &lt;code&gt;gatsby-source-graphql&lt;/code&gt;. This will allow us to fetch the Blog Posts into our Gatsby app.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add gatsby-source-graphql&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We will add this plugin in the plugins array found in &lt;code&gt;gatsby-config.js&lt;/code&gt; (located in the root of our Gatsby project) and configure its options like below. Most importantly, we will replace &lt;code&gt;CONTENT_DELIVERY_API_URL&lt;/code&gt; with our API's URL and &lt;code&gt;&amp;lt;CONTENT_DELIVERY_TOKEN&amp;gt;&lt;/code&gt; with the token you created earlier &lt;code&gt;(eg: d3b45980479...)&lt;/code&gt;...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-source-graphql`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;typeName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;someTypeName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;fieldName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;webinyHeadlessCms&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;CONTENT_DELIVERY_API_URL&amp;gt;/cms/read/production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;CONTENT_DELIVERY&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are using the &lt;code&gt;read&lt;/code&gt; API in order to pull Blog Post data and the &lt;code&gt;production&lt;/code&gt; alias which points to the &lt;code&gt;production&lt;/code&gt; environment because that is where we published our content earlier.&lt;/p&gt;

&lt;p&gt;Once we have these ready, we can jump to the code. The following snippet shows the code located in the &lt;code&gt;pages/index.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;react&lt;/span&gt;&lt;span class="dl"&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;graphql&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;gatsby&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&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;../components/layout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;// Implement a custom parser or use one from the community: `webiny-richtext-serializer`&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;parseRichTextDataAsHTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// The IndexPage component that renders our blog posts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;IndexPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// GraphQL queried data is automatically inserted into the `data` parameter used below&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blogPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webinyHeadlessCms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listBlogPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;

  &lt;span class="c1"&gt;// We render a nice list of blog posts&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BlogPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;blogPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`post-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;
        &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="na"&gt;whiteSpace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pre-wrap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
        &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;parseRichTextDataAsHTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* We use Gatsby's Layout to make our Blog look nice */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Layout&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;BlogPosts&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Layout&lt;/span&gt;&lt;span class="err"&gt;&amp;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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;IndexPage&lt;/span&gt;

&lt;span class="c1"&gt;// A GraphQL query that fetches our blogs' data&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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`{
  webinyHeadlessCms {
    listBlogPosts {
      data {
        id
        createdOn
        title
        body
      }
    }
  }
}`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Previewing the page
&lt;/h1&gt;

&lt;p&gt;Let's run &lt;code&gt;yarn dev&lt;/code&gt; in our Gatsby project directory so we can see our page in action:&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%2Fi%2Fwswi51lmqrw5spgajgl5.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%2Fi%2Fwswi51lmqrw5spgajgl5.png" alt="gatsby-blog"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: In order to fetch the latest CMS data and update your content you will need to stop your Gatsby app and run &lt;code&gt;gatsby develop&lt;/code&gt; again. If you are in production mode, you need to run &lt;code&gt;gatsby build&lt;/code&gt; as well as &lt;code&gt;gatsby serve&lt;/code&gt;. &lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Congratulations! 🎉&lt;/p&gt;

&lt;p&gt;We have successfully created a simple page that displays a list of all created blog posts, all powered by Webiny Headless CMS and Gatsby.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The same can also be achieved with other popular tools, like Next.js. To learn more, &lt;a href="http://docs.webiny.com/docs/guides/headless-nextjs-tutorial/?utm_source=Dev-to&amp;amp;utm_medium=webiny-docs&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-doc-headless-cms-nextjs&amp;amp;utm_term=W00361" rel="noopener noreferrer"&gt;click here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;FYI: The blog was originally written and published by &lt;a href="https://twitter.com/BhardwajAshu96" rel="noopener noreferrer"&gt;Ashutosh&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>headlesscms</category>
      <category>javascript</category>
      <category>gatsby</category>
      <category>graphql</category>
    </item>
    <item>
      <title>Lighting fast search with Elasticsearch</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Mon, 09 Nov 2020 17:53:33 +0000</pubDate>
      <link>https://dev.to/webiny/lighting-fast-search-with-elasticsearch-n82</link>
      <guid>https://dev.to/webiny/lighting-fast-search-with-elasticsearch-n82</guid>
      <description>&lt;p&gt;If you're reading this blog chances are you really interested in Elasticsearch and the solutions that it provides. This blog will introduce you to Elasticsearch and explain how to get started with implementing a fast search for your app in less than 10 minutes. Of course, we're not going to code up a full-blown production-ready search solution here. But, the below-mentioned concepts will help you get up to speed quickly. So, without further ado, let's start!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Elasticsearch?
&lt;/h2&gt;

&lt;p&gt;Elasticsearch is a distributed search and analytics engine. It provides near real-time search and analytics for all types of data. Whether you have structured or unstructured text, numerical data, or geospatial data. One of the key specialties of Elasticsearch is that it can efficiently store and index it in a way that supports fast searches. You can go far beyond simple data retrieval and aggregate information to discover trends and patterns in your data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do you need it?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Elasticsearch is fast&lt;/strong&gt;. Because Elasticsearch is built on top of &lt;a href="https://lucene.apache.org/"&gt;Lucene&lt;/a&gt;, it excels at full-text search. Elasticsearch is also a near real-time search platform, meaning the latency from the time a document is indexed until it becomes searchable is very short — typically one second. As a result, Elasticsearch is well suited for time-sensitive use cases such as security analytics and infrastructure monitoring.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Elasticsearch is distributed by nature.&lt;/strong&gt; The documents stored in Elasticsearch are distributed across different containers known as shards, which are duplicated to provide redundant copies of the data in case of hardware failure. The distributed nature of Elasticsearch allows it to scale out to hundreds (or even thousands) of servers and handle petabytes of data.&lt;/p&gt;

&lt;p&gt;The speed and scalability of Elasticsearch and its ability to index many types of content mean that it can be used for a number of use cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Application search&lt;/li&gt;
&lt;li&gt;Website search&lt;/li&gt;
&lt;li&gt;Enterprise search&lt;/li&gt;
&lt;li&gt;Logging and log analytics
And many more...&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We at &lt;a href="https://www.webiny.com/?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-blog-lighting-fast-search-with-elasticsearch&amp;amp;utm_term=W00348"&gt;Webiny&lt;/a&gt; are building a feature for the upcoming v5 release where we'll use Elasticsearch to perform a super-fast search in our core apps like Page builder, File manager, and Headless CMS. Please check out our &lt;a href="https://github.com/webiny/webiny-js?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-blog-lighting-fast-search-with-elasticsearch&amp;amp;utm_term=W00349"&gt;Github repo&lt;/a&gt; to learn more about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started with Elasticsearch
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setup Elasticsearch cluster
&lt;/h3&gt;

&lt;p&gt;You can create a hosted deployment or set up an Elasticsearch cluster on your local machine. For the purpose of this blog, we'll assume that we have an Elasticsearch cluster running at localhost:9200. If you want to go with a local setup please check out this &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started-install.html#run-elasticsearch-local"&gt;guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup Elasticsearch Node.js client
&lt;/h3&gt;

&lt;p&gt;We'll be going to use the official Node.js client for Elasticsearch. You can create a new Node.js project or use this &lt;a href="https://github.com/Ashu96/Elasticsearch-example-nodejs"&gt;example project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To install the latest version of the client, run 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 install @elastic/elasticsearch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the client is straightforward, it supports all the public APIs of Elasticsearch, and every method exposes the same signature.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure the client
&lt;/h3&gt;

&lt;p&gt;The client is designed to be easily configured for your needs. In the example mentioned below, you can see how easy it is to configure it with basic options.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@elastic/elasticsearch&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// The Elasticsearch endpoint to use.&lt;/span&gt;
  &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:9200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// Max number of retries for each request.&lt;/span&gt;
  &lt;span class="na"&gt;maxRetries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// Max request timeout in milliseconds for each request.&lt;/span&gt;
  &lt;span class="na"&gt;requestTimeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&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;blockquote&gt;
&lt;p&gt;NOTE: As we previously mentioned we're assuming that we have an Elasticsearch cluster running locally on &lt;code&gt;localhost:9200&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Elasticsearch in action
&lt;/h2&gt;

&lt;p&gt;Before jumping into the core topic of this blog i.e search, we'll need to create the index and add few documents to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create an index
&lt;/h3&gt;

&lt;p&gt;Let's create an index inside our Elasticsearch cluster.&lt;/p&gt;

&lt;p&gt;You can use the &lt;code&gt;create&lt;/code&gt; index API to add a new index to an Elasticsearch cluster. When creating an index, you can specify the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Settings for the index (optional)&lt;/li&gt;
&lt;li&gt;Mappings for fields in the index (optional)&lt;/li&gt;
&lt;li&gt;Index aliases (optional)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// Name of the index you wish to create.&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll be using a dynamic mapping that's why didn't add the settings and mappings in the body here. But, if needed we could have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// Name of the index you wish to create.&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// If you want to add "settings" &amp;amp; "mappings"&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;number_of_shards&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;mappings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;field1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Index documents
&lt;/h3&gt;

&lt;p&gt;Now that we have created the &lt;code&gt;product&lt;/code&gt; index, let's add a few documents so that we can perform a search on those later. There are basically two ways you can do this depending upon the use case.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Index a single document.&lt;/li&gt;
&lt;li&gt;Index multiple documents in bulk.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We'll cover both of these use cases in a moment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Index a single document
&lt;/h3&gt;

&lt;p&gt;Here we're going to use the &lt;code&gt;create&lt;/code&gt; method on the client that we created earlier. Let's take a look at the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// Unique identifier for the document.&lt;/span&gt;
  &lt;span class="c1"&gt;// To automatically generate a document ID omit this parameter.&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// The name of the index.&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&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="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="mi"&gt;1&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="s2"&gt;iPhone 12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;699&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Blast past fast&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can index a new &lt;code&gt;JSON&lt;/code&gt; document with the &lt;code&gt;_doc&lt;/code&gt; or &lt;code&gt;_create&lt;/code&gt; resource. Using &lt;code&gt;_create&lt;/code&gt; guarantees that the document is only indexed if it does not already exist. To update an existing document, you must use the &lt;code&gt;_doc&lt;/code&gt; resource.&lt;/p&gt;

&lt;h3&gt;
  
  
  Index multiple documents at once
&lt;/h3&gt;

&lt;p&gt;This is all good. But, sometimes we want to index multiple documents at once. For example, in our case wouldn't it be better if we can index all brand new iPhones at once? Right? We can use the &lt;code&gt;bulk&lt;/code&gt; method for this exact use case. Let's take a look at the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataset&lt;/span&gt; &lt;span class="o"&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="mi"&gt;2&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="s2"&gt;iPhone 12 mini&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Blast past fast.&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;599&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="mi"&gt;3&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="s2"&gt;iPhone 12 Pro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;It's a leap year.&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;999&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="mi"&gt;4&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="s2"&gt;iPhone 12 Pro max&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;It's a leap year.&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1199&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&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;doc&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="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bulkResponse&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bulk&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bulkResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&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;erroredDocuments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="c1"&gt;// The items array has the same order of the dataset we just indexed.&lt;/span&gt;
  &lt;span class="c1"&gt;// The presence of the `error` key indicates that the operation&lt;/span&gt;
  &lt;span class="c1"&gt;// that we did for the document has failed.&lt;/span&gt;
  &lt;span class="nx"&gt;bulkResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;erroredDocuments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="c1"&gt;// If the status is 429 it means that you can retry the document,&lt;/span&gt;
        &lt;span class="c1"&gt;// otherwise it's very likely a mapping error, and you should&lt;/span&gt;
        &lt;span class="c1"&gt;// fix the document before to try it again.&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;operation&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;document&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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;span class="c1"&gt;// Do something useful with it.&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;erroredDocuments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;bulk&lt;/code&gt; method provides a way to perform multiple &lt;code&gt;indexes&lt;/code&gt;, &lt;code&gt;create&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt;, and &lt;code&gt;update&lt;/code&gt; actions in a single request. Here we are using the &lt;code&gt;index&lt;/code&gt; action but you can use the other actions as per your needs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TIP: &lt;code&gt;bulk&lt;/code&gt; performs multiple indexing or delete operations in a single API call. This reduces overhead and can greatly increase indexing speed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Update an existing document
&lt;/h3&gt;

&lt;p&gt;We often need to update an existing document. We'll use the &lt;code&gt;update&lt;/code&gt; method for the same.&lt;/p&gt;

&lt;p&gt;It enables you to script document updates. The script can update, delete, or skip modifying the document. To increment the &lt;code&gt;price&lt;/code&gt;, you can call the &lt;code&gt;update&lt;/code&gt; method with the following script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// The name of the index.&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// Document ID.&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ctx._source.price += params.price_diff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;price_diff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;99&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;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;update&lt;/code&gt; API also supports passing a partial document, which is merged into the existing document. Let's use it to update the &lt;code&gt;description&lt;/code&gt; of the product with &lt;code&gt;id = -1&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// The name of the index.&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// Document ID.&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Fast enough!&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Delete an existing document
&lt;/h3&gt;

&lt;p&gt;It's a no-brainer that we also need to remove existing documents at some point.&lt;/p&gt;

&lt;p&gt;We'll use the &lt;code&gt;delete&lt;/code&gt; method to remove a document from an index. For that, we must specify the index name and document ID. Let's take a look at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await client.delete({
  // The name of the index.
  index: "products",
  // Document ID.
  id: -1,
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Search
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;search&lt;/code&gt; API allows us to execute a search query and get back search hits that match the query.&lt;/p&gt;

&lt;p&gt;Let's start with a simple query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Let's search!&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// The name of the index.&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Defines the search definition using the Query DSL.&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;blast&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query will return all the documents whose &lt;code&gt;description&lt;/code&gt; field matches with &lt;code&gt;"blast"&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;INFO: Learn more about Query DSL &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.x/query-dsl.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nice and simple right. But, that's not all! We can go for even more specific queries. Let's look at some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search for exact text like the name of a product
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Let's search for products with the name "iPhone 12 Pro" !&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;// The name of the index.&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Defines the search definition using the Query DSL.&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;term&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;keyword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;iPhone 12 Pro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Search for a range of values like products between a price range
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Let's search for products ranging between 500 and 1000!&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// The name of the index.&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Defines the search definition using the Query DSL.&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;gte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;lte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&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;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;ul&gt;
&lt;li&gt;Search using multiple conditions
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Let's search for products that are either ranging between 500 and 1000&lt;/span&gt;
&lt;span class="c1"&gt;// or description matching "stunning"&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// The name of the index.&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Defines the search definition using the Query DSL.&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Return result for which this nested condition is TRUE.&lt;/span&gt;
      &lt;span class="na"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Acts like an OR operator.&lt;/span&gt;
        &lt;span class="c1"&gt;// Returns TRUE even if one of these conditions is met&lt;/span&gt;
        &lt;span class="na"&gt;should&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;range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;gte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;lte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&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;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;stunning&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="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;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need a search query where all the conditions must be matched then you should use the must operator inside the bool It acts like an AND operator and returns TRUE only if all the conditions met. Inside bool, there are also other operators must_not and should_not that you can use as per your needs.&lt;/p&gt;

&lt;p&gt;These are just a few examples of search queries, you can perform even more specific and power search queries.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;INFO: Learn more about search using Query DSL &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.x/query-dsl.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Sort search results
&lt;/h3&gt;

&lt;p&gt;Elasticsearch allows us to add one or more sorts of specific fields. Each sort can be reversed as well. The sort is defined on a per-field level, with a special field name for &lt;code&gt;_score&lt;/code&gt; to sort by score, and &lt;code&gt;_doc&lt;/code&gt; to sort by index order.&lt;/p&gt;

&lt;p&gt;The order defaults to "desc" when sorting on the &lt;code&gt;_score&lt;/code&gt; and defaults to &lt;code&gt;"asc"&lt;/code&gt; when sorting on anything else.&lt;/p&gt;

&lt;p&gt;Let's take a look at the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Let's sort the search results!&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// The name of the index.&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Defines the search definition using the Query DSL.&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Acts like an AND operator.&lt;/span&gt;
        &lt;span class="c1"&gt;// Returns TRUE only if all of these conditions are met.&lt;/span&gt;
        &lt;span class="na"&gt;must&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;range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;gte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;lte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1100&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;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&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="s2"&gt;iPhone&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// Sort the search result by "price"&lt;/span&gt;
    &lt;span class="na"&gt;sort&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;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;asc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;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;Here we've sorted the search result by &lt;code&gt;price&lt;/code&gt; in &lt;code&gt;"asc"&lt;/code&gt; order.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paginate search results
&lt;/h2&gt;

&lt;p&gt;Pagination is a must-have feature for every decent real-world app. And Elasticsearch helps us with this as well. Let's see how? 🙂&lt;/p&gt;

&lt;p&gt;By default, the &lt;code&gt;search&lt;/code&gt; method returns the top 10 matching documents.&lt;/p&gt;

&lt;p&gt;To paginate through a larger set of results, you can use the search API’s &lt;code&gt;size&lt;/code&gt; and &lt;code&gt;from&lt;/code&gt; parameters. The &lt;code&gt;size&lt;/code&gt; parameter is the number of matching documents to return. The &lt;code&gt;from&lt;/code&gt; parameter is a zero-indexed offset from the beginning of the complete result set that indicates the document you want to start with.&lt;/p&gt;

&lt;p&gt;For example, the following &lt;code&gt;search&lt;/code&gt; method call sets the &lt;code&gt;from&lt;/code&gt; offset to &lt;code&gt;15&lt;/code&gt;, meaning the request offsets, or skips, the first fifteen matching documents.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;size&lt;/code&gt; parameter is &lt;code&gt;15&lt;/code&gt;, meaning the request can return up to 15 documents, starting at the offset.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Let's paginate the search results!&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// The name of the index.&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Starting offset (default: 0)&lt;/span&gt;
    &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// Number of hits to return (default: 10)&lt;/span&gt;
    &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// Defines the search definition using the Query DSL.&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;blast&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;If you're looking to implement a fast search mechanism for your app or website. I would recommend you to consider Elasticsearch as a solution to that.&lt;/p&gt;

&lt;p&gt;And if you're interested in building full-stack serverless web applications I would highly recommend you try out &lt;a href="https://www.webiny.com/?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-blog-lighting-fast-search-with-elasticsearch&amp;amp;utm_term=W00350"&gt;Webiny&lt;/a&gt; The Easiest Way To Adopt Serverless. We've Elasticsearch along with DynamoDB baked-in for super-fast search in our core apps like Page builder, File manager, and Headless CMS.&lt;/p&gt;

&lt;p&gt;I hope this blog will help you in your web development journey, but, of course, if you have any further questions, concerns, or ideas, feel free to ping me 💬 over &lt;a href="https://twitter.com/webinyplatform"&gt;Twitter&lt;/a&gt; or even directly via our &lt;a href="https://www.webiny.com/slack%20?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-cross-promotion-nov-09&amp;amp;utm_content=webiny-slack-community&amp;amp;utm_term=W00351"&gt;community Slack&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Thanks for reading this blog! My name is Ashutosh, and I work as a full-stack developer at Webiny. If you have any questions, comments, or just wanna say hi, feel free to reach out to me via &lt;a href="https://twitter.com/BhardwajAshu96"&gt;Twitter&lt;/a&gt;. You can also subscribe 🍿 to our &lt;a href="https://www.youtube.com/channel/UCI5TBif-unrpn5htTRxXPQw"&gt;YouTube channel&lt;/a&gt; where we post knowledge sharing every week.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;FYI: The blog was originally written and published by &lt;a href="https://twitter.com/BhardwajAshu96"&gt;Ashutosh&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>elasticsearch</category>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What is Commercial Open Source Software</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Fri, 06 Nov 2020 10:24:32 +0000</pubDate>
      <link>https://dev.to/webiny/what-is-commercial-open-source-software-2njc</link>
      <guid>https://dev.to/webiny/what-is-commercial-open-source-software-2njc</guid>
      <description>&lt;h2&gt;
  
  
  Open source evolution
&lt;/h2&gt;

&lt;p&gt;Open source is the backbone of almost all digital technologies today. Without open-source, most of the modern tech companies that you rely on in your day to day life wouldn't be able to operate or more precisely, wouldn't become what they are in the first place.&lt;/p&gt;

&lt;p&gt;What started as a selection of smaller projects back in the 70s created by programming enthusiasts to oppose the unfair profits of closed-source software, has evolved to become the main industry driver of software development in the past decade.&lt;/p&gt;

&lt;p&gt;This "recent" acceleration in the number of open-source companies being launched, frequently called The Open Source Renaissance, has been fueled by various circumstances on the software industry market. But one of the main reasons behind this has been the significant innovation around various business models that allowed the open-source companies to commercialize their products while keeping the open-source approach to software development.&lt;/p&gt;

&lt;p&gt;Open source has always been, and still is, the best possible way to create new software as it can gather whole communities of motivated, like-minded software developers that can through their contribution not just help speed up the development process, but also help steer it in a direction that would be the most beneficial to the global developer community.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Commercial Open Source Software?
&lt;/h2&gt;

&lt;p&gt;The elephant in the (meeting) room of the majority of the open-source project founders has been one common, basic question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How can we build a business around a product that we are committed to giving away to the community for free?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What started with Red Hat and their paid support and services model over 20 years ago has opened the door for open source communities to start exploring the various ways to monetize their products - which created a new wave of companies that we can group under the name of &lt;strong&gt;Commercial Open Source Software&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This commercialization has not only allowed these companies to become sustainable but has also created this perfect symbiosis between the open-source and its proprietary license counterpart that has become a credible new way of funding further technology development and innovation.&lt;/p&gt;

&lt;h2&gt;
  
  
  COSS business models
&lt;/h2&gt;

&lt;p&gt;The majority of COSS companies have built their business model in a way that allows them to capture part of the value that is delivered by their open-source core product, by offering commercial versions of their products, alternative license options, or add-on proprietary software. While their success still fundamentally depends on their open-source core technology.&lt;/p&gt;

&lt;p&gt;The opportunity to commercialize open-source software has increased the appeal of OSS to investors, who in this modern-day also play a fundamental role in the development stage of open source start-ups by providing the crucial funding needed to form a dedicated full-time team to manage the project more effectively, grow the project up to a higher scale, and achieving the product-market fit.&lt;/p&gt;

&lt;p&gt;There are numerous different ways the open-source companies have successfully approached the commercialization of their products, but we can group them under five main groups:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Support services&lt;/li&gt;
&lt;li&gt;Hosting&lt;/li&gt;
&lt;li&gt;Restrictive licensing&lt;/li&gt;
&lt;li&gt;Open core&lt;/li&gt;
&lt;li&gt;Hybrid licensing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All five of these groups provide a different set of benefits and challenges that fit different types of open source products, and all have found their purpose amongst the COSS companies. But in the past ten years, one of these groups has really been standing out vs. others. The approach referred to as the Open Core model has proven to be the most frequent business model used by highly successful open source companies, that have managed to grow their business to the 100+ million dollar levels.*&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%2Fi%2Fa0fvhg59gze9k4o31knq.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%2Fi%2Fa0fvhg59gze9k4o31knq.png" alt="coss"&gt;&lt;/a&gt;COSS company index&lt;/p&gt;

&lt;p&gt;The concept of the open core business model is that the majority of the code base is open source - the core - while the smaller part, usually aimed at enterprise clients, is made proprietary - the crust. This allows the COSS company to stay true to the open-source movement and support the developer community while being able to capture a small portion of the delivered value that will fuel the whole project and unlock scale and longevity. The most important task of the company that decides to take the open core approach is to find the right balance between the core and the crust. One that will not restrict the value and performance of the open-source part, while still providing enough incremental value to its paid users that will justify their investment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Webiny approach to COSS
&lt;/h2&gt;

&lt;p&gt;At Webiny, we have made a deep analysis of all the available and potential business models and have also found the open core to be the best way forward for our product. And we have put a massive focus on making sure we find the perfect balance point between the two parts.&lt;/p&gt;

&lt;p&gt;Our commitment to our community is that we will always keep access to our Webiny open-source framework and apps completely free of charge. And rather than separating a part of the code and turning it into proprietary software, we have decided to build a completely separate product that will perfectly complement our Webiny OS by providing additional features that will further improve the Webiny OS usage for larger teams and multi-project circumstances. And most importantly, not taking any value away from our open-source users.&lt;/p&gt;

&lt;p&gt;This new product has recently been announced on our product roadmap under the name of the Webiny Control Panel. You can find more details about it here: &lt;a href="https://www.webiny.com/roadmap/?utm_source=Dev-to&amp;amp;utm_medium=webiny-website&amp;amp;utm_campaign=webiny-cross-promotion-nov-2&amp;amp;utm_content=webiny-roadmap&amp;amp;utm_term=W00336" rel="noopener noreferrer"&gt;Webiny product roadmap&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future
&lt;/h2&gt;

&lt;p&gt;The software has completely changed the world as we know it and is part of almost every aspect of modern life. It is hard to predict what the world will look like in the future and how technology will further develop it, but it is absolutely safe to say that software innovation will be one of the main drivers of that evolution.&lt;/p&gt;

&lt;p&gt;The constant and rapid software innovation is unlocking new levels of what is possible every day. And to circle back to what I mentioned at the very beginning - there is no better way to develop new software than by joining the strengths of the global community of developers around an open-source project. Especially when these projects can be turned into credible businesses by implementing modern COSS business models.&lt;/p&gt;




&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.google.com/spreadsheets/d/17nKMpi_Dh5slCqzLSFBoWMxNvWiwt2R-t4e_l7LPLhU/edit#gid=0" rel="noopener noreferrer"&gt;COSS company index&lt;/a&gt;, by COSS Media&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://a16z.com/2019/10/04/commercializing-open-source/" rel="noopener noreferrer"&gt;Open Source: From Community to Commercialization&lt;/a&gt;, by Peter Levine &amp;amp; Jennifer Li / Andreessen Horowitz&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;FYI: The blog was originally written and published by &lt;a href="https://twitter.com/mislavstreicher" rel="noopener noreferrer"&gt;Mislav Streicher&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>serverless</category>
      <category>commercial</category>
      <category>opensource</category>
      <category>headlesscms</category>
    </item>
    <item>
      <title>Local Development Is Dying 💀 - And It's for the Better</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Thu, 05 Nov 2020 17:01:11 +0000</pubDate>
      <link>https://dev.to/webiny/local-development-is-dying-and-it-s-for-the-better-2838</link>
      <guid>https://dev.to/webiny/local-development-is-dying-and-it-s-for-the-better-2838</guid>
      <description>&lt;p&gt;Serverless infrastructure is changing the way we architect applications and it’s also changing the way we code and work as developers. The development is moving away from our laptop and into the cloud. It’s the start of cloud-native development.&lt;/p&gt;

&lt;p&gt;We at Webiny have been practicing cloud-native development for over a year now, and we believe this is the future. In this article, I will explain why.&lt;/p&gt;




&lt;p&gt;A &lt;strong&gt;local development environment&lt;/strong&gt; (LDE) is a way of configuring services on our laptop/desktop to run a website or a web application. This entails installing a web server, a database, and some sort of a language as Node.js, Python, PHP, and others.&lt;/p&gt;

&lt;p&gt;This combination we call a &lt;strong&gt;stack&lt;/strong&gt;. Some of the popular stacks are LAMP (linux-apache-mysql-php), MEAN (mongodb-express-angular-node) and others. Today you find these stacks preconfigured as Docker containers. This way you don’t “pollute” your machine with services as they run inside a container.&lt;/p&gt;




&lt;h2&gt;
  
  
  Advantages and Disadvantages of a Local Development Environment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Advantage: work offline
&lt;/h3&gt;

&lt;p&gt;For years installing these stacks was the first thing a developer would do before checking out some code from git and running it. A local stack has several advantages. One of the main ones is that you can &lt;strong&gt;work offline&lt;/strong&gt;. This is possible because all the services run locally on your machine, there is no need to fetch any data from “outside” the network.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantage: simplicity of debugging
&lt;/h3&gt;

&lt;p&gt;Another meaningful advantage is the &lt;strong&gt;simplicity of debugging&lt;/strong&gt;. If your code, database, or network is not working, you access those components directly and try and find the problem. You attach debuggers, inspectors, and profilers along the way to gain additional insight.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantage: no need to upload files
&lt;/h3&gt;

&lt;p&gt;Lastly, with a local development environment, each time you change a file there is &lt;strong&gt;no need to upload it to a remote server&lt;/strong&gt;. The moment you save the code it gets compiled locally and you instantly see the result. It provides a faster turnaround time.&lt;/p&gt;

&lt;p&gt;Let’s review some of the &lt;strong&gt;disadvantages&lt;/strong&gt; because it’s not all ideal when it comes to having an LDE.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disadvantage: can be complex to setup
&lt;/h3&gt;

&lt;p&gt;When working in a larger organization the LDE can be &lt;strong&gt;large and complex&lt;/strong&gt;. These environments take a lot of time to get them up and running. When they break, you often need to run the whole setup from the ground up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disadvantage: resource-intensive
&lt;/h3&gt;

&lt;p&gt;You are also &lt;strong&gt;limited to a fixed number of containers&lt;/strong&gt; and services you are able to run locally. This is because of the constraints to your CPU and memory. Try having 10 or more Docker containers running in parallel, it will significantly impede the performance of other apps, like your IDE for example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disadvantage: "Works on my pc"
&lt;/h3&gt;

&lt;p&gt;Because not everyone has an identical setup, there are differences in how things work. This causes inconsistencies in testing, security, and performance. Those can later cause serious problems. When using an LDE with a team, you need to ensure everyone has the same stack, version and is always updating it with the latest releases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disadvantage: reinventing the wheel
&lt;/h3&gt;

&lt;p&gt;Another limitation is you &lt;strong&gt;can’t use a closed source or 3rd party services&lt;/strong&gt;. This is because, in most cases, they don’t provide a way of running their service locally. To keep an LDE, with all the previously mentioned advantages, you might decide not to use a 3rd party service but develop something internally you own. Over time you’ll make several of such decisions that end up wasting a big chunk of your time maintaining them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This last one is the key reason why a local development environment is dying.&lt;/strong&gt; — Let me explain.&lt;/p&gt;




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

&lt;p&gt;Development is complex. Over time some of those complexities were solved and solutions were created as new products. Products that all other developers can now use and integrate into their applications. By using those products and services, instead of reinventing the wheel, developers save a lot of time and money and create more resilient and secure solutions.&lt;/p&gt;

&lt;p&gt;Let’s take a search engine for an eCommerce website as an example. Coding one is a daunting challenge. You might not have the right expertise in data storage and know the most optimal languages to code such a feature. Luckily services such as &lt;a href="https://www.algolia.com/"&gt;Algolia&lt;/a&gt; have been created. By leveraging a ready-made service you are certain that it will work, that there are no bugs, and that it can handle the load from your users (in most cases at least).&lt;/p&gt;

&lt;p&gt;When you test for resiliency and scale even simple tasks, such as file storage, can pose a challenge to code from the ground up. Try and achieve the 99.999999999% uptime that &lt;strong&gt;AWS S3&lt;/strong&gt; provides.&lt;/p&gt;

&lt;p&gt;Many such examples are available, but the main takeaway is those services are not available inside an LDE. Serverless services in the majority of cases can only be consumed via an API contacting the service in the cloud.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The question is now — would you sacrifice having an LDE over a proven, performant, and secure service with SLAs?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many developers and businesses have answered NO. This is what’s driving the adoption of building solutions in a serverless way.&lt;/p&gt;

&lt;p&gt;With serverless, there are servers behind those services, but you don’t care about them. The infrastructure is managed for you, including all the security patches and backups.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cloud-Native Development
&lt;/h2&gt;

&lt;p&gt;Developing applications in the serverless way changes how we configure our LDE. We can no longer work offline and run services from our laptop.&lt;/p&gt;

&lt;p&gt;Even if we get a part of the services running locally, it’s not a solution. LDE can’t emulate the network of a cloud setup, not to talk about API limits and performance.&lt;/p&gt;

&lt;p&gt;Because the LDE is no longer reliable, in my view, the only way forward is to embrace cloud-native development. Our code needs to run in the cloud and the cloud is now part of our development environment and not just the production. &lt;strong&gt;The only remaining thing which is running “locally” will be our editor.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s clear that LDE is dying, and we won’t miss it. As a tradeoff, we get to create performant, scalable, resilient, reliable, and secure applications in less time. The industry is moving in that direction. There is still a way to go to make it a pleasant experience but &lt;strong&gt;it is certainly coming.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;FYI: The blog was originally written and published by &lt;a href="https://twitter.com/SvenAlHamad"&gt;Sven Al Hamad&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>serverless</category>
      <category>aws</category>
      <category>cloud</category>
      <category>webdev</category>
    </item>
    <item>
      <title>5 Tips to Make Your Lambda Functions Run Faster (and Cheaper)</title>
      <dc:creator>Albiona</dc:creator>
      <pubDate>Tue, 20 Oct 2020 10:42:35 +0000</pubDate>
      <link>https://dev.to/webiny/5-tips-to-make-your-lambda-functions-run-faster-and-cheaper-1lpa</link>
      <guid>https://dev.to/webiny/5-tips-to-make-your-lambda-functions-run-faster-and-cheaper-1lpa</guid>
      <description>&lt;p&gt;The AWS Lambda service allows us to easily deploy and run our own code, without worrying too much about the underlying infrastructure (when compared to non-serverless technologies). It essentially scales infinitely (with great power comes great responsibility), and can be connected with a bunch of other services, like API Gateway, S3, AppSync, DynamoDB, etc.&lt;/p&gt;

&lt;p&gt;And usually, the thing people first start creating with the service are good-old HTTP APIs, like for example REST or even GraphQL. In those situations, since the actual users (potential customers) are the ones who will be invoking your Lambda functions, it's important that they are responding as fast as possible - meaning, we want to have function cold starts as short as possible, and afterward, make our code execute necessary logic in the most efficient way.&lt;/p&gt;

&lt;p&gt;How to ensure that is the case? Well, that is the topic of this article, in which we'll cover five tips that can help you in that regard. So, without further ado, let's take a look!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. More RAM = faster execution = same price
&lt;/h2&gt;

&lt;p&gt;Allocating more RAM to a function means faster execution. That's true. But it also means you pay more, right? Well, it depends. Sometimes that's actually not true.&lt;/p&gt;

&lt;p&gt;Consider these two &lt;a href="https://user-images.githubusercontent.com/5121148/96137718-427dfd80-0efd-11eb-98b0-ba882d8a466b.png"&gt;512MB RAM&lt;/a&gt; and &lt;a href="https://user-images.githubusercontent.com/5121148/96137705-3eea7680-0efd-11eb-8ddb-a02e7f99158a.png"&gt;1024MB RAM&lt;/a&gt; Lambda function CloudWatch logs. The billed durations from the logs are also shown in the following chart:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C_sQ_JK7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pch8ph1xyv7qt6vsoved.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C_sQ_JK7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pch8ph1xyv7qt6vsoved.png" alt="Comparing function invocation duration - 512MB RAM vs 1024MB RAM." width="880" height="535"&gt;&lt;/a&gt;&lt;/p&gt;
Comparing function invocation duration - 512MB RAM vs 1024MB RAM.



&lt;p&gt;So, what we can see here is that with the 512MB of RAM Lambda function (blue), the billed duration is most of the times 200ms. But, with 1024MB of RAM (red), which is 2x more, the billed duration gets reduced to 100ms, which is 2x less. Even the initial invocation's duration (the cold start one's) got reduced from 1400ms to 700ms.&lt;/p&gt;

&lt;p&gt;Effectively, this means we're getting faster functions, for the same price!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fmOBcLLb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d8zp6383vw1nawktjccw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fmOBcLLb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d8zp6383vw1nawktjccw.gif" alt="gif" width="348" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But do note, the results may vary depending on the task the function is performing. For example, in some cases, you might not achieve the reduction big enough for the price reduction to happen. In other words, if you manage to reduce the invocation duration from 140ms to 105ms, this is good, but still, doesn't change the price, since the billed duration on both invocations is 200ms.&lt;/p&gt;

&lt;p&gt;Before bumping up RAM, do test your function with different payloads, and then based on the results, determine if there are any actions worth taking.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Watch out for function size to reduce the cold start durations
&lt;/h2&gt;

&lt;p&gt;The larger the function in size, the longer the cold start. There is a &lt;a href="https://mikhail.io/serverless/coldstarts/aws/"&gt;very nice article&lt;/a&gt; written by &lt;a href="https://twitter.com/MikhailShilkov"&gt; Mikhail Shilkov&lt;/a&gt;, that talks about various factors that impact the duration of cold starts, one of which is the package size. Definitely give it a read if you really want to get into the nitty-gritty.&lt;/p&gt;

&lt;p&gt;Based on that fact, the advice I wanted to give here is - watch out for function size. Try to use as few external packages as possible. Be aware that every package you include in your function can also bring additional dependencies with it, making it even worse.&lt;/p&gt;

&lt;p&gt;With that, also be careful about how you actually import packages. If there is a way to import just a specific functionality, do that, instead of importing the entire package.&lt;/p&gt;

&lt;p&gt;For example, when using the &lt;a href="https://aws.amazon.com/sdk-for-node-js/"&gt;AWS SDK&lt;/a&gt;, which we often need to communicate with various AWS services, only import the actual clients you'll be using.&lt;/p&gt;

&lt;p&gt;Do not import the whole AWS SDK like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;CloudFront&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Lambda&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;aws-sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, do it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;CloudFront&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;aws-sdk/clients/cloudfront&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;Lambda&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;aws-sdk/clients/lambda&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach can significantly affect the final bundle size, so again, watch out!&lt;/p&gt;

&lt;h4&gt;
  
  
  A couple of useful tools
&lt;/h4&gt;

&lt;p&gt;There are a couple of useful tools I like to use in order to inspect what the 3rd party package is bringing to the table (or should I say - removing from the table).&lt;/p&gt;

&lt;p&gt;One of the tools is the (&lt;a href="https://bundlephobia.com"&gt;bundlephobia&lt;/a&gt;), which will give you an overview of the package size, with all of its dependencies. Definitely useful, especially when comparing similar packages functionality-wise, and deciding which to use.&lt;/p&gt;

&lt;p&gt;The other one is the &lt;a href="https://chrisbateman.github.io/webpack-visualizer/"&gt;Webpack Visualizer&lt;/a&gt;, which gives you an awesome overview of all the packages that are included in your final production Webpack bundle. For example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1SUfSyd2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7wk6ulk9jp6xh9kflci7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1SUfSyd2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7wk6ulk9jp6xh9kflci7.png" alt="Alt Text" width="743" height="743"&gt;&lt;/a&gt;&lt;/p&gt;
3rd party dependencies (node_modules) adding 2MB to the overall function size!


 

&lt;p&gt;Wait, Webpack bundle?&lt;/p&gt;

&lt;p&gt;Yes! Bundling your functions with Webpack is also recommended, since not only that'll make your function a single file, but will also make sure only the code that's actually utilized gets into the build, which naturally reduces the final file size.&lt;/p&gt;

&lt;p&gt;Configuring Webpack could be a bit daunting task, but it's definitely worth it at the end of the day. Luckily, with every &lt;a href="https://docs.webiny.com/docs/get-started/quick-start?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-hygiene-blog-oct-19&amp;amp;utm_content=webiny-5-tips-lambda-functions-run-faster-cheaper&amp;amp;utm_term=W00246"&gt;new Webiny project&lt;/a&gt;, the bundling process is pre-configured for you, so you can immediately jump to your new project! 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Split complex processes into separate functions to save money and gain speed
&lt;/h2&gt;

&lt;p&gt;Some of you might already know that calling another Lambda function within a Lambda function is often considered as an anti-pattern, and yes, this is definitely true in certain cases. The main reason is that, while the other function is processing the invocation payload, the first function is idle and just waiting for the response, meaning you're effectively paying for nothing.&lt;/p&gt;

&lt;p&gt;Yes, you can also invoke functions asynchronously, without waiting for the invocation to complete (using the &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html"&gt;InvocationType: "Event"&lt;/a&gt; option), but, here we're talking more about synchronous function invocation, which is definitely needed in case we're interested in the actual response that the invoked function is returning.&lt;/p&gt;

&lt;p&gt;Let's consider the following example, where I believe calling another Lambda function from the first one (and waiting for the response) can be considered as a good approach.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TNmcLFdd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kl002lot7x2e3wktd9og.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TNmcLFdd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kl002lot7x2e3wktd9og.png" alt='To reduce overall cost, use separate 2GB RAM "SSR Lambda".' width="800" height="551"&gt;&lt;/a&gt;&lt;/p&gt;
To reduce overall cost, use separate 2GB RAM "SSR Lambda" for intensive SSR generation.


 

&lt;p&gt;The diagram above is showing the SSR implementation we did at Webiny, which consists of a couple of AWS resources: CloudFront, API Gateway, S3, two Lambda functions, and a database.&lt;/p&gt;

&lt;p&gt;I won't go too much into the details here (feel free to check the &lt;a href="https://www.webiny.com/blog/serverless-side-rendering-e1c0924b8da1?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-hygiene-blog-oct-19&amp;amp;utm_content=webiny-ssrendering-blog&amp;amp;utm_term=W00247"&gt;Serverless Side Rendering — The Ultimate Guide&lt;/a&gt; article for that, but, what we are doing with the two Lambda functions is essentially splitting work and optimizing for cost. The &lt;strong&gt;Web Server Lambda&lt;/strong&gt; is configured with minimal system resources (256MB RAM), because its only task is to return cached SSR HTML, stored in the database.&lt;/p&gt;

&lt;p&gt;But, if there is no SSR HTML in the database, we need to generate it, which is actually an intensive process, and executing it with 256MB of RAM simply won't cut it. So, instead of just bumping the &lt;strong&gt;Web Server Lambda&lt;/strong&gt;'s RAM, we are invoking the &lt;strong&gt;SSR Lambda&lt;/strong&gt; function, which contains a lot more system resources (for example - 2 GB RAM), and we're only paying for that when we actually need it. It would simply be a waste of money to have the &lt;strong&gt;Web Server Lambda&lt;/strong&gt; configured with the same amount of resources, just to pull some data out of the database, most of the time. This way we can save a significant amount of money in the long run.&lt;/p&gt;

&lt;p&gt;You can also do this if you have a Lambda function that's heavy in size, just because of a 3rd dependency that needs to be there, but still, isn't utilized that often.&lt;/p&gt;

&lt;p&gt;For example, one of the apps that Webiny offers out of the box, the &lt;a href="https://www.webiny.com/serverless-app/page-builder/?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-hygiene-blog-oct-19&amp;amp;utm_content=webiny-page-builder-serverless-page&amp;amp;utm_term=W00248"&gt;Page Builder app&lt;/a&gt;, has its own installation process, in which we basically download initial sample pages and images, and respectively, insert them into the database, and save them to user's S3 bucket. This process requires a couple of NPM packages for dealing with files, which can easily add a couple of hundreds of KBs to the overall function size.&lt;/p&gt;

&lt;p&gt;Since that's the case, we decided to extract the installation functionality completely from the main &lt;strong&gt;Page Builder API&lt;/strong&gt; function, and place it into a separate &lt;strong&gt;Page Builder installation&lt;/strong&gt; function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8PhhKpBl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yyxep6obqs9emth9h7dx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8PhhKpBl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yyxep6obqs9emth9h7dx.png" alt="Extract dependency-heavy and rarely-triggered logic into a separate function." width="880" height="385"&gt;&lt;/a&gt;Extract dependency-heavy and rarely-triggered logic into a separate function.&lt;/p&gt;

&lt;p&gt;With this organization, we are not burdening the main &lt;strong&gt;Page Builder API&lt;/strong&gt; function with redundant packages, which helps in reducing its size, and naturally, affects the duration of cold starts.&lt;/p&gt;

&lt;p&gt;To conclude, whenever you have an intensive process, that either needs more system resources or requires additional packages that increase the overall function size, try to extract it into a separate function, especially if the process is rarely triggered.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. When possible, execute code in parallel
&lt;/h2&gt;

&lt;p&gt;The following tip is a short one, yet effective one, and can be applied not only when talking about Lambda functions, but coding in general.&lt;/p&gt;

&lt;p&gt;If possible, execute code in parallel, not in series. For example, if we needed to do five 100ms operations, doing it in series means it would take a total of 500ms to complete.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;operations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;operations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;await&lt;/span&gt; &lt;span class="nx"&gt;operations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]();&lt;/span&gt; &lt;span class="c1"&gt;// 100ms operation.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of doing it in series, try doing it in parallel, using the &lt;code&gt;Promise.all&lt;/code&gt; method, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;operations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&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;promises&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="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;operations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;promises&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;operations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 100ms operation.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doing this will decrease the function invocation duration and naturally, reduce the overall cost!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mEyP-Z-K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i1co3m6sw8zbi7i8vnfq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mEyP-Z-K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i1co3m6sw8zbi7i8vnfq.jpg" alt="Nice trick!🙂" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;
Nice trick!🙂



&lt;h2&gt;
  
  
  5. Reusing connections with Keep-Alive
&lt;/h2&gt;

&lt;p&gt;Last but not least, if you're making HTTP requests within your Lambda function's code, it's useful to &lt;a href="https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/node-reusing-connections.html"&gt;enable the "keep-alive"&lt;/a&gt; option on the default Node.js HTTP/HTTPS agent, because that avoids establishing the TCP connection on every request, and enables us to always reuse the existing one:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;By default, the default Node.js HTTP/HTTPS agent creates a new TCP connection for every new request. To avoid the cost of establishing a new connection, you can reuse an existing connection.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This can be especially handy for clients like DynamoDB, where we really need the HTTP request latencies to be as low as possible.&lt;/p&gt;

&lt;p&gt;A good article on the actual performance boost that this option introduces was already written by the great &lt;a href="https://twitter.com/theburningmonk"&gt;Yan Cui&lt;/a&gt;, in his article - &lt;a href="https://medium.com/predict/lambda-optimization-tip-enable-http-keep-alive-ef7aa7880554"&gt;Lambda optimization tip - enable HTTP keep-alive&lt;/a&gt;. As we can learn, without HTTP keep-alive, the duration of DynamoDB operations averaged around 33ms, while with the option enabled, the average duration dropped to 10ms!&lt;/p&gt;

&lt;p&gt;The somehow shocking fact about establishing new TCP connections is that the actual establishment takes more time than the actual client operation we're trying to execute! So when you think about it, deciding whether this option should be enabled or not is almost a no-brainer.&lt;/p&gt;

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

&lt;p&gt;By almost completely abstracting the infrastructure concerns from us and with that, reducing the overall development and maintenance cost, the AWS Lambda (and serverless technologies in general) truly does make our developer lives easier. But as we've seen, there are still a couple of tricks that are useful to know and which can help us in optimizing our workflows even further.&lt;/p&gt;

&lt;p&gt;I hope the five tips we've shown here will help you in your serverless journey, but, of course, if you have any further questions, concerns, or ideas, feel free to ping me over &lt;a href="https://www.twitter.com/doitadrian"&gt;Twitter&lt;/a&gt; or even directly via our &lt;a href="http://webiny.com/slack?utm_source=Dev-to&amp;amp;utm_medium=webiny-blog&amp;amp;utm_campaign=webiny-hygiene-blog-oct-19&amp;amp;utm_content=webiny-slack-community&amp;amp;utm_term=W00249"&gt;community Slack&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;FYI: The blog was originally written and published by &lt;a href="https://www.twitter.com/doitadrian"&gt;Adrian Smijulj&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>serverless</category>
      <category>aws</category>
      <category>javascript</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
