<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ lambda - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ lambda - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 30 May 2026 14:17:36 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/lambda/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Run a Docker Container in AWS Lambda ]]>
                </title>
                <description>
                    <![CDATA[ While containers are quite lightweight and provide various benefits, it can be challenging to decide how best to deploy them. There are a number of ways to deploy and run Docker containers. But some are best for orchestrating and managing containers,... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-run-a-docker-container-in-aws-lambda/</link>
                <guid isPermaLink="false">694c7990b7478745bce04604</guid>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ serverless ]]>
                    </category>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Docker ]]>
                    </category>
                
                    <category>
                        <![CDATA[ containerization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ecr ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Agnes Olorundare ]]>
                </dc:creator>
                <pubDate>Wed, 24 Dec 2025 23:38:56 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1766599506861/86c07e37-7838-4186-971e-29722ccec785.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>While containers are quite lightweight and provide various benefits, it can be challenging to decide how best to deploy them. There are a number of ways to deploy and run Docker containers. But some are best for orchestrating and managing containers, and may not suit a simple use case of running just one container.</p>
<p>In this article, I’ll teach you how you can deploy a single Docker container using a serverless service on AWS called Lambda.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisite-requirements">Prerequisite/ Requirements</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-serverless-with-aws-lambda">Serverless with AWS Lambda</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-run-and-test-a-container-locally">How to Build, Run, and Test a Container Locally</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-push-your-image-to-amazon-elastic-container-registry-ecr">How to Push Your Image to Amazon Elastic Container Registry (ECR)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-deploy-your-docker-image-to-lambda">How to Deploy Your Docker Image to Lambda</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-cleanup">Cleanup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisite-requirements">Prerequisite/ Requirements</h2>
<p>The following tools and skills are necessary for following along with this tutorial:</p>
<ul>
<li><p>Knowledge of Docker, and have Docker installed locally.</p>
</li>
<li><p>An AWS account with credentials with administrative privilege for making API calls via the CLI. Best practice would be to limit the privilege to exactly what needs to be done.</p>
</li>
<li><p>AWS CLI installed locally</p>
</li>
<li><p>Python virtual environment managers <a target="_blank" href="https://github.com/astral-sh/uv">such as uv</a> (optional)</p>
</li>
</ul>
<h2 id="heading-serverless-with-aws-lambda">Serverless with AWS Lambda</h2>
<p>Containers provide a lightweight, consistent, and resource-friendly way of running applications. Serverless takes away the overhead of managing the underlying infrastructures on which the container runs. So as you can probably start to see, combining these tools helps you deploy applications in a way that lets you focus on business logic, performance, and what gives your product a competitive edge/ advantage.</p>
<p>One AWS tool that enables you to go serverless is Lambda. With Lambda, you’re only billed for the number of times the code in the function runs, the memory you selected at the time of provisioning the service, and the duration of each invocation of the function.</p>
<p>In addition to removing operational overhead, Lambda can also help you save money since you won’t have to deal with idle resources. The function only comes alive when triggered by a request sent to it.</p>
<h2 id="heading-how-to-build-run-and-test-a-container-locally">How to Build, Run, and Test a Container Locally</h2>
<p>Docker is a tool that helps you package applications or software into portable, standardized and shareable units that have everything the applications need such as libraries, runtime, system tools, application code, in order to run. These units are called containers.</p>
<p>In this section, I’ll walk you through building the Docker image, running the container, and testing it after it’s running.</p>
<p>You can find the project that you’ll be using here in this <a target="_blank" href="https://github.com/Agnes4Him/freecodecamp-lambda-docker">GitHub repository</a>.</p>
<h3 id="heading-build-the-docker-image">Build the Docker Image</h3>
<p>To run a Docker container, you first need to build an image. The image becomes the template or <code>class</code> from which you create the container or <code>instance of the class</code>.</p>
<p>You can find the code to build an image in <code>lambda_function.py</code>.</p>
<pre><code class="lang-python"><span class="hljs-comment"># lambda_function.py</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">lambda_handler</span>(<span class="hljs-params">event, context</span>):</span>
    name = event[<span class="hljs-string">"name"</span>]
    message = <span class="hljs-string">f"Hello, <span class="hljs-subst">{name}</span>!"</span>

    <span class="hljs-keyword">try</span>:
        <span class="hljs-keyword">return</span> {
            <span class="hljs-string">"statusCode"</span>: <span class="hljs-number">200</span>,
            <span class="hljs-string">"body"</span>: message
        }
    <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
        <span class="hljs-keyword">return</span> {
            <span class="hljs-string">"statusCode"</span>: <span class="hljs-number">400</span>,
            <span class="hljs-string">"body"</span>: {<span class="hljs-string">"error"</span>: str(e)}
        }
</code></pre>
<p>As you can see from the code above, this is a very basic Python application that expects a <code>POST</code> HTTP request, with a JSON payload that contains the key – <code>name</code> – and a corresponding value. The code then returns a greeting containing the name it has received. The application has just a single function, which also serves as the entry point to it.</p>
<p>To build a Docker image, you’ll need a Dockerfile to provide the blueprint for the image. For this specific case, the Dockerfile you’ll use is also very basic. Each line in a Dockerfile is called a <code>Directive</code>, and this provides the instruction Docker should follow when creating an image. So building a Docker image means creating a template for a container by following the instructions or directives in the Dockerfile.</p>
<pre><code class="lang-plaintext"># Dockerfile

FROM public.ecr.aws/lambda/python:3.12

# Copy function code... LAMBDA_TASK_ROOT is /var/task, the working directory set in the base image
COPY lambda_function.py ${LAMBDA_TASK_ROOT}    

# Set the CMD to your handler - lambda_handler
CMD ["lambda_function.lambda_handler"]
</code></pre>
<p>A Dockerfile usually starts with a base image. To deploy an application as a Docker container in AWS Lambda, the base image has to be of a specific kind, depending on the application run-time. For this case, you’ll need the Python run-time, so the base image is <code>public.ecr.aws/lambda/python:3.12</code>. It’s okay to use a different Python version.</p>
<p>The next directive in the Dockerfile is copying the <code>lambda_function.py</code> file to a specific path in the base image. That path is referenced using an environment variable that has already been defined in the base image and points to <code>/var/task</code>. This is the directory your code will be running from.</p>
<p>The last directive is simply a command to start the application when the container runs.</p>
<p>Now, you can run the build command from the project’s root directory:</p>
<pre><code class="lang-bash">docker build -t &lt;IMAGE_NAME&gt;:&lt;iIMAGE_TAG&gt; .
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766415846066/f128b7fc-f3a0-4770-b361-3f27c36a6ec4.png" alt="Running docker build command on the terminal" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766415895836/d4653144-51b2-437d-8d73-4aaa42651206.png" alt="Output of docker images command showing a list of all existing images" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-run-the-docker-container">Run the Docker Container</h3>
<p>Next, let’s create a running container from this image.</p>
<pre><code class="lang-bash">docker run -it --rm -p 8080:8080  lambda_docker:1.0.0
</code></pre>
<p>The command above will create a container and run it in interactive mode just so you can see the logs generated by the application in the container. Port 8080 is also exposed on the host where the container is running and mapped to the container port, which is also 8080 (defined by AWS). The container gets automatically removed once you kill the running process with CTRL + C.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766416250857/62584a3c-bf5e-4cd9-b8d5-fc6734c50075.png" alt="Showing docker run command in interactive mode" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-test-the-running-container">Test the Running Container</h3>
<p>Now confirm that the application running within the container can receive and process requests. To do this, use the code in the <code>test.py</code> file:</p>
<pre><code class="lang-python"><span class="hljs-comment"># test.py</span>

<span class="hljs-keyword">import</span> requests

url = <span class="hljs-string">"http://localhost:8080/2015-03-31/functions/function/invocations"</span>

data = {
    <span class="hljs-string">"name"</span>: <span class="hljs-string">"Janet"</span>
}

response = requests.post(url, json=data)

print(<span class="hljs-string">"Status Code:"</span>, response.status_code)
print(<span class="hljs-string">"Response Body:"</span>, response.json())
</code></pre>
<p>You can use the Python <code>requests</code> library to make this call. Install the library by using a virtual environment to isolate the application from your overall system. This helps prevent issues with conflicts in the versions of libraries you install for an application to use.</p>
<p>If you’re using uv to manage your virtual environment, simply run the command:</p>
<pre><code class="lang-python">uv add requests
</code></pre>
<p>Then run the code in <code>test.py</code> from within the virtual environment:</p>
<pre><code class="lang-python">uv run python3 test.py
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766419713310/1ebc3435-3826-46fb-93f3-4218c367e280.png" alt="Testing that the running docker container is working by running test.py file" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You should see the desired response on the terminal.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766419866358/8f0c2867-64c6-4b16-a5a7-5a0eedf9470f.png" alt="Docker container logs in real time" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-push-your-image-to-amazon-elastic-container-registry-ecr">How to Push Your Image to Amazon Elastic Container Registry (ECR)</h2>
<p>Now that you have a working Docker image to deploy to Lambda, the next step is to push the image to a Docker registry. For this use case, your image has to be pushed to Amazon ECR, a container registry for storing Docker images.</p>
<p>To push your Docker image, you first need to tag the image, which simply means naming the image in a specific way.</p>
<p>Currently, this image tag is <code>lambda-docker:1.0.0</code>. To tag it the AWS way, first create an ECR repository. Let’s use the AWS CLI for this (this requires you to configure the AWS credentials locally by running the <code>aws configure</code> command and providing your credentials).</p>
<h3 id="heading-setup-environment-variables">Setup Environment Variables</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Set AWS profile</span>
<span class="hljs-built_in">export</span> AWS_PROFILE=&lt;PROFILE_NAME&gt;
</code></pre>
<pre><code class="lang-bash"><span class="hljs-comment"># Set other variables</span>

AWS_REGION=&lt;AWS_REGION&gt;
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REPO_NAME=lambda-docker
TAG=1.0.0
</code></pre>
<p>The above commands set the <code>AWS_PROFILE</code> for the CLI to target the right AWS account for API calls. The other variables specify the region, account ID, and the ECR repository name and tag.</p>
<h3 id="heading-create-ecr-repository-and-authenticate">Create ECR Repository and Authenticate</h3>
<p>Now, create the ECR repository:</p>
<pre><code class="lang-bash">aws ecr create-repository \
  --repository-name <span class="hljs-string">"<span class="hljs-variable">$REPO_NAME</span>"</span> \
  --region <span class="hljs-string">"<span class="hljs-variable">$AWS_REGION</span>"</span>
</code></pre>
<p>Authenticate to Amazon ECR:</p>
<pre><code class="lang-bash">aws ecr get-login-password --region <span class="hljs-string">"<span class="hljs-variable">$AWS_REGION</span>"</span> \
  | docker login \
  --username AWS \
  --password-stdin <span class="hljs-string">"<span class="hljs-variable">$ACCOUNT_ID</span>.dkr.ecr.<span class="hljs-variable">$AWS_REGION</span>.amazonaws.com"</span>
</code></pre>
<h3 id="heading-tag-and-push-the-docker-image">Tag and Push the Docker Image</h3>
<p>Now, tag the Docker image:</p>
<pre><code class="lang-bash">docker tag <span class="hljs-variable">$REPO_NAME</span>:<span class="hljs-variable">$TAG</span> \
  <span class="hljs-variable">$ACCOUNT_ID</span>.dkr.ecr.<span class="hljs-variable">$AWS_REGION</span>.amazonaws.com/<span class="hljs-variable">$REPO_NAME</span>:<span class="hljs-variable">$TAG</span>
</code></pre>
<p>Push the image to the ECR repository you created:</p>
<pre><code class="lang-bash">docker push <span class="hljs-variable">$ACCOUNT_ID</span>.dkr.ecr.<span class="hljs-variable">$AWS_REGION</span>.amazonaws.com/<span class="hljs-variable">$REPO_NAME</span>:<span class="hljs-variable">$TAG</span>
</code></pre>
<p>And that’s it! Your image is now in ECR.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766420761622/5a18e41b-be41-4660-8d6c-59b12aebb4de.jpeg" alt="Image of Amazon ECR showing the repository created earlier" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766420810814/9f65af4b-a509-45e3-be8f-0bed08cfe6b2.png" alt="Image of the docker image pushed to the existing ECR repository" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-deploy-your-docker-image-to-lambda">How to Deploy Your Docker Image to Lambda</h2>
<p>With your image now in ECR, you can create a Lambda function. Navigate to the Lambda console, and click <code>Create a Function</code>.</p>
<h3 id="heading-create-lambda-function">Create Lambda Function</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766421062231/19bae74d-a6d5-4e73-8cca-102be40be214.png" alt="AWS Lambda Console" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Select <code>Container Image</code> and go ahead to search for the ECR repository you created.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766421207358/25ae6eb2-1b1b-43c7-86dc-6dcd512ddc81.jpeg" alt="Select ECR repository to create a Lambda function" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Next, select the image:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766421335963/ab7d9103-0ea6-4e25-be8c-139344acb5c5.png" alt="Select the existing Docker image from ECR" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Leave other configurations as default and click create.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766421506518/2f6e631a-a0c7-4f20-966f-2ef87f91bfb7.jpeg" alt="Hit the Create button to create a Lambda function" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Navigate to the function after creating.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766421673261/71c60ac4-35e7-4458-b4a7-1be2440b9e16.jpeg" alt="The newly created Lambda function dashboard/ overview" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-test-deployment">Test Deployment</h3>
<p>Now, let’s test the deployment. For this, simply use the existing Lambda <code>Test</code> tab. Provide all the details needed, including the payload for your <code>POST</code> request.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766421769909/008473e4-bb28-4fdd-8c5b-7e1f3489a3a0.png" alt="Create a new test instance to test the Lambda function" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766421889043/86f6dbe6-be94-4dca-973e-9e7b68064ff3.png" alt="The output of testing Lambda function" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>And that’s it. You’ve successfully deployed a Docker container on AWS by leveraging ECR and Lambda. You can go a step forward by integrating API Gateway and making the function accessible from the internet.</p>
<h2 id="heading-cleanup">Cleanup</h2>
<p>Remember to delete the services you’ve created on your AWS ECR repository and Lambda to avoid extra charges.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Deploying your Docker container on AWS Lambda is an efficient way to get your application running quickly without being bothered by managing servers or platforms.</p>
<p>Thanks for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Lambda Sorted in Python – How to Lambda Sort a List ]]>
                </title>
                <description>
                    <![CDATA[ The sort() method and the sorted() function let you sort iterable data like lists and tuples in ascending or descending order.  They take parameters with which you can modify how they perform the sorting. And one of those parameters could be a functi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/lambda-sort-list-in-python/</link>
                <guid isPermaLink="false">66adf19e6778e7bd69427c0d</guid>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Thu, 16 Mar 2023 19:37:09 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/lambdaSort.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The <code>sort()</code> method and the <code>sorted()</code> function let you sort iterable data like lists and tuples in ascending or descending order. </p>
<p>They take parameters with which you can modify how they perform the sorting. And one of those parameters could be a function or even a lambda function.</p>
<p>In this article, you’ll learn how to sort a list with the lambda function.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><a class="post-section-overview" href="#heading-how-to-sort-a-list-in-python">How to Sort a List in Python</a></li>
<li><a class="post-section-overview" href="#heading-what-is-a-lambda-function">What is a Lambda Function?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-sort-a-list-with-the-lambda-function">How to Sort a List with the Lambda Function</a><ul>
<li><a class="post-section-overview" href="#heading-how-to-lambdasort-with-the-sort-method">How to Lambdasort with the <code>sort()</code> Method</a></li>
<li><a class="post-section-overview" href="#heading-how-to-lambdasort-with-the-sorted-function">How to Lambdasort with the <code>sorted()</code> Function</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-how-to-sort-a-list-in-python">How to Sort a List in Python</h2>
<p>You can sort a list with the <code>sort()</code> method and <code>sorted()</code> function. </p>
<p>The <code>sort()</code> method takes two parameters – <code>key</code> and <code>reverse</code>. You can use a function as the key, but the reverse parameter can only take a Boolean. </p>
<p>If you specify the value of the reverse parameter as <code>True</code>, the <code>sort()</code> method will perform the sorting in descending order. And if you specify <code>false</code> as the value of the <code>reverse</code>, the sorting will be in ascending order. You don’t even need to specify false as the value because it’s the default.</p>
<p>But both parameters are optional, so the method still works fine without them:</p>
<pre><code class="lang-py">name_list = [<span class="hljs-string">'Zen Jack'</span>, <span class="hljs-string">'Luigi Austin'</span>, <span class="hljs-string">'Ben Benson'</span>, <span class="hljs-string">'John Ann'</span>]
print(<span class="hljs-string">"Original names:"</span>, name_list) <span class="hljs-comment"># Original names: ['Zen Jack', 'Luigi Austin', 'Ben Benson', 'John Ann']</span>


name_list.sort()
print(<span class="hljs-string">"Sorted names:"</span>, name_list) <span class="hljs-comment"># Sorted names: ['Ben Benson', 'John Ann', 'Luigi Austin', 'Zen Jack']</span>


num_list = [<span class="hljs-number">34</span>, <span class="hljs-number">11</span>, <span class="hljs-number">35</span>, <span class="hljs-number">89</span>, <span class="hljs-number">37</span>]
print(<span class="hljs-string">"Original numbers:"</span>, num_list) <span class="hljs-comment"># Original numbers: [34, 11, 35, 89, 37]</span>


num_list.sort()
print(<span class="hljs-string">"Sorted numbers:"</span>, num_list) <span class="hljs-comment"># Sorted numbers: [11, 34, 35, 37, 89]</span>
</code></pre>
<p>The <code>sorted()</code> function, on the other hand, also works like <code>sort()</code>. It takes the optional <code>key</code> and <code>reverse</code> parameters too, but it takes a compulsory parameter of the iterable you want to sort – making it ideal for sorting other iterables apart from a list.</p>
<p>Here’s how the <code>sorted()</code> function works:</p>
<pre><code class="lang-py">name_list = [<span class="hljs-string">'Zen Jack'</span>, <span class="hljs-string">'Luigi Austin'</span>, <span class="hljs-string">'Ben Benson'</span>, <span class="hljs-string">'John Ann'</span>]
print(<span class="hljs-string">"Original names:"</span>, name_list) <span class="hljs-comment"># Original names: ['Zen Jack', 'Luigi Austin', 'Ben Benson', 'John Ann']</span>


sorted(name_list)
print(<span class="hljs-string">"Sorted names:"</span>, name_list) <span class="hljs-comment"># Sorted names: ['Ben Benson', 'John Ann', 'Luigi Austin', 'Zen Jack']</span>


num_list = [<span class="hljs-number">34</span>, <span class="hljs-number">11</span>, <span class="hljs-number">35</span>, <span class="hljs-number">89</span>, <span class="hljs-number">37</span>]
print(<span class="hljs-string">"Original numbers:"</span>, num_list) <span class="hljs-comment"># Original numbers: [34, 11, 35, 89, 37]</span>


sorted(num_list)
print(<span class="hljs-string">"Sorted numbers:"</span>, num_list) <span class="hljs-comment"># Sorted numbers: [11, 34, 35, 37, 89]</span>
</code></pre>
<p>As I pointed out earlier, you can also sort other iterables with the <code>sorted()</code> function. This is how I sorted a tuple with the <code>sorted()</code> function:</p>
<pre><code class="lang-py">name_tuple = (<span class="hljs-string">'Zen Jack'</span>, <span class="hljs-string">'Luigi Austin'</span>, <span class="hljs-string">'Ben Benson'</span>, <span class="hljs-string">'John Ann'</span>)
print(<span class="hljs-string">"Original tuple:"</span>, name_tuple) <span class="hljs-comment"># Original tuple: ('Zen Jack', 'Luigi Austin', 'Ben Benson', 'John Ann')</span>


sorted(name_tuple)
print(<span class="hljs-string">"Sorted tuple:"</span>, name_tuple) <span class="hljs-comment"># Sorted tuple: ('Zen Jack', 'Luigi Austin', 'Ben Benson', 'John Ann')</span>
</code></pre>
<p>Remember I also pointed out you can pass a function as the value for the key parameter of the <code>sort()</code> method and <code>sorted()</code> function. This function can help you be more decisive with the way you want to sort the iterable list or tuple.</p>
<p>For example, the <code>sorted()</code> function and <code>sort()</code> method would only sort by the first part of the string or number. But you can also sort by the second part by passing in a function as the key parameter. It is with this function that you will decide how you want to sort the list or other iterables.</p>
<p>A lambda function would be ideal to do this because it takes one expression. But before we dive into sorting with a lambda function, let me remind you what the lambda function is.</p>
<h2 id="heading-what-is-a-lambda-function">What is a Lambda Function?</h2>
<p>A lambda function is an anonymous function – a function you don’t write with the <code>def</code> keyword. A lambda function can take many arguments, but it can only have one expression.</p>
<p>Since you don’t define a lambda function with the <code>def</code> keyword, how do you call it? You can assign a lambda function to a variable, then call it by the name of that variable.</p>
<p>In the example below, the <code>addNum</code> lambda function has 3 arguments and adds them together:</p>
<pre><code class="lang-py">addNums = <span class="hljs-keyword">lambda</span> a, b, c : a + b + c


res = addNums(<span class="hljs-number">4</span>, <span class="hljs-number">12</span>, <span class="hljs-number">4</span>)
print(res) <span class="hljs-comment">#20</span>
</code></pre>
<h2 id="heading-how-to-sort-a-list-with-the-lambda-function">How to Sort a List with the Lambda Function</h2>
<p>You can “lambda sort” a list with both the <code>sort()</code> method and the <code>sorted()</code> function. Let’s look at how to lambda sort with the <code>sort()</code> method first.</p>
<h3 id="heading-how-to-lambdasort-with-the-sort-method">How to Lambdasort with the <code>sort()</code> Method</h3>
<p>Let’s take the names we sorted before and sort them by the second name. This lambda function would be ideal in sorting by the second name:</p>
<pre><code class="lang-py"><span class="hljs-keyword">lambda</span> name: name.split()[<span class="hljs-number">1</span>]
</code></pre>
<p>The lambda function splits a name and takes the second part of the name – the second name. The first part is the first name and it would be <code>[0]</code>.</p>
<p>You can pass in this lambda function as the key parameter – sorting the names by the second names:</p>
<pre><code class="lang-py">name_list = [<span class="hljs-string">'Zen Jack'</span>, <span class="hljs-string">'Luigi Austin'</span>, <span class="hljs-string">'Ben Benson'</span>, <span class="hljs-string">'John Ann'</span>]
print(<span class="hljs-string">"Original list"</span>, name_list) <span class="hljs-comment"># Original list ['Zen Jack', 'Luigi Austin', 'Ben Benson', 'John Ann']</span>


name_list.sort(key=<span class="hljs-keyword">lambda</span> name: name.split()[<span class="hljs-number">1</span>])
print(<span class="hljs-string">"Sorted name list"</span>, name_list) <span class="hljs-comment"># Sorted name list ['John Ann', 'Luigi Austin', 'Ben Benson', 'Zen Jack']</span>
</code></pre>
<p>You can see the names got sorted by the alphabetical order of the second names. <code>John Ann</code> came first, and <code>Zen Jack</code> came last. Ann starts with A and Jack starts with J.</p>
<p>If you want, you can even pass in a function directly. What you need to do is to not call the function. You have to pass it in as an object.</p>
<pre><code class="lang-py">name_list = [<span class="hljs-string">'Zen Jack'</span>, <span class="hljs-string">'Luigi Austin'</span>, <span class="hljs-string">'Ben Benson'</span>, <span class="hljs-string">'John Ann'</span>]
print(<span class="hljs-string">"Original list"</span>, name_list) <span class="hljs-comment"># Original list ['Zen Jack', 'Luigi Austin', 'Ben Benson', 'John Ann']</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sort_by_second_name</span>(<span class="hljs-params">name</span>):</span>
    <span class="hljs-keyword">return</span> name.split()[<span class="hljs-number">1</span>]


name_list.sort(key=sort_by_second_name)
print(<span class="hljs-string">"Sorted name list"</span>, name_list) <span class="hljs-comment"># Sorted name list ['John Ann', 'Luigi Austin', 'Ben Benson', 'Zen Jack']</span>
</code></pre>
<p>Now, let’s sort the numbers based on their last digits. In case you don’t know, if you use the remainder (<code>%</code>) operator on two numbers, it divides the two numbers and returns the remainder: </p>
<pre><code class="lang-py">print(<span class="hljs-number">4</span> % <span class="hljs-number">2</span>) <span class="hljs-comment"># returns 0</span>
print(<span class="hljs-number">44</span> % <span class="hljs-number">11</span>) <span class="hljs-comment"># returns 0</span>
print(<span class="hljs-number">104</span> % <span class="hljs-number">60</span>) <span class="hljs-comment"># returns 44</span>
print(<span class="hljs-number">21</span> % <span class="hljs-number">2</span>) <span class="hljs-comment"># returns 1</span>
</code></pre>
<p>But if you “mod” a number with multiple digits with 10, it returns the last digit of the number:</p>
<pre><code class="lang-py"><span class="hljs-keyword">print</span> (<span class="hljs-number">44</span> % <span class="hljs-number">10</span>) <span class="hljs-comment"># returns 4</span>
<span class="hljs-keyword">print</span> (<span class="hljs-number">402</span> % <span class="hljs-number">10</span>) <span class="hljs-comment"># returns 2</span>
<span class="hljs-keyword">print</span> (<span class="hljs-number">152</span> % <span class="hljs-number">10</span>) <span class="hljs-comment"># returns 2</span>
<span class="hljs-keyword">print</span> (<span class="hljs-number">1596</span> % <span class="hljs-number">10</span>) <span class="hljs-comment"># returns 6</span>
</code></pre>
<p>That’s how you can get the second number and sort the numbers based on it.</p>
<p>Here’s how I sorted the numbers from the previous examples with a lambda function:</p>
<pre><code class="lang-py">num_list = [<span class="hljs-number">22</span>, <span class="hljs-number">34</span>, <span class="hljs-number">11</span>, <span class="hljs-number">35</span>, <span class="hljs-number">89</span>, <span class="hljs-number">37</span>, <span class="hljs-number">93</span>, <span class="hljs-number">56</span>, <span class="hljs-number">108</span>]
print(<span class="hljs-string">'Original Number:'</span>, num_list) <span class="hljs-comment"># Original Number: [22, 34, 11, 35, 89, 37, 93, 56, 108]</span>


num_list.sort(key=<span class="hljs-keyword">lambda</span> num: num % <span class="hljs-number">10</span>)
print(<span class="hljs-string">'Lambda sorted number:'</span>, num_list) <span class="hljs-comment"># Lambda sorted number: [11, 22, 93, 34, 35, 56, 37, 108, 89]</span>
</code></pre>
<p>As you can see, this lambda function, <code>lambda num: num % 10</code> is responsible for sorting the numbers based on each of the second digits. I passed in the number to the lambda function and got the last digit with <code>% 10</code>. This lambda function runs through each of the numbers and gets their last digits.</p>
<p>If you want, you can even pass in a function directly as the key:</p>
<pre><code class="lang-py">num_list = [<span class="hljs-number">22</span>, <span class="hljs-number">34</span>, <span class="hljs-number">11</span>, <span class="hljs-number">35</span>, <span class="hljs-number">89</span>, <span class="hljs-number">37</span>, <span class="hljs-number">93</span>, <span class="hljs-number">56</span>, <span class="hljs-number">108</span>]
print(<span class="hljs-string">'Original Number:'</span>, num_list) <span class="hljs-comment"># Original Number: [22, 34, 11, 35, 89, 37, 93, 56, 108]</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sort_by_second_num</span>(<span class="hljs-params">num</span>):</span>
    <span class="hljs-keyword">return</span> num % <span class="hljs-number">10</span>


num_list.sort(key=sort_by_second_num)
print(<span class="hljs-string">'Lambda sorted number:'</span>, num_list) <span class="hljs-comment"># Lambda sorted number: [11, 22, 93, 34, 35, 56, 37, 108, 89]</span>
</code></pre>
<h3 id="heading-how-to-lambdasort-with-the-sorted-function">How to Lambdasort with the <code>sorted()</code> Function</h3>
<p>In this example, we are going to sort a list of tuples using the jersey numbers of some footballers.</p>
<p>The only difference between the <code>sort()</code> and <code>sorted()</code> method is that <code>sorted()</code> takes a compulsory iterable and <code>sort()</code> does not.</p>
<p>So, to lambda sort with the <code>sorted()</code> function, all you need to do is pass in the list as the iterable and your lambda function as the key:</p>
<pre><code class="lang-py"> footballers_and_nums = [(<span class="hljs-string">"Fabregas"</span>, <span class="hljs-number">4</span>),(<span class="hljs-string">"Beckham"</span> ,<span class="hljs-number">10</span>),(<span class="hljs-string">"Yak"</span>, <span class="hljs-number">9</span>), (<span class="hljs-string">"Lampard"</span>, <span class="hljs-number">8</span>), (<span class="hljs-string">"Ronaldo"</span>, <span class="hljs-number">7</span>), (<span class="hljs-string">"Terry"</span>, <span class="hljs-number">26</span>), (<span class="hljs-string">"Van der Saar"</span>, <span class="hljs-number">1</span>), (<span class="hljs-string">"Yobo"</span>, <span class="hljs-number">2</span>)]


sorted_footballers_and_nums = sorted(footballers_and_nums, key=<span class="hljs-keyword">lambda</span> index : index[<span class="hljs-number">1</span>])


print(<span class="hljs-string">"Original footballers and jersey numbers"</span>, footballers_and_nums) <span class="hljs-comment"># Original footballers and jersey numbers [('Fabregas', 4), ('Beckham', 10), ('Yak', 9), ('Lampard', 8), ('Ronaldo', 7), ('Terry', 26), ('Van der Saar', 1), ('Yobo', 2)]</span>


print(<span class="hljs-string">"Sorted footballers by jersey numbers:"</span>, sorted_footballers_and_nums) <span class="hljs-comment"># Sorted footballers by jersey numbers: [('Van der Saar', 1), ('Yobo', 2), ('Fabregas', 4), ('Ronaldo', 7), ('Lampard', 8), ('Yak', 9), ('Beckham', 10), ('Terry', 26)]</span>
</code></pre>
<p>The lambda function that performed the sorting is this <code>lambda index : index[1])</code>. The lambda went through all the tuples in the list, took the second index (<code>[1]</code>), and used those to do the sorting.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This article showed you how to sort a list with the <code>sort()</code> method and <code>sorted()</code> function using a lambda function.</p>
<p>But that was not all. We looked at how both the <code>sort()</code> method and <code>sorted()</code> function work on their own without a lambda function. I also reminded you of what the lambda function is, so you could understand how I did the sorting with a lambda function.</p>
<p>Thank you for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python Lambda Functions – How to Use Anonymous Functions with Examples ]]>
                </title>
                <description>
                    <![CDATA[ Lambda functions, also known as anonymous functions, are small, one-time-use functions in Python.  You can define them using the lambda keyword followed by the function's inputs, a colon, and the function's expression. The output of a lambda function... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/python-lambda-functions/</link>
                <guid isPermaLink="false">66ba0eaf7282cc17abcf0c4f</guid>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh Krishna ]]>
                </dc:creator>
                <pubDate>Fri, 24 Feb 2023 17:25:28 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/02/lambda-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Lambda functions, also known as anonymous functions, are small, one-time-use functions in Python. </p>
<p>You can define them using the <code>lambda</code> keyword followed by the function's inputs, a colon, and the function's expression. The output of a lambda function is returned as the result of the expression, rather than a return statement.</p>
<p>The main purpose of lambda functions is to allow for the creation of small, throw-away functions that you can use in other parts of a program. This can be useful when you need to pass a simple function as an argument to another function, for example.</p>
<h3 id="heading-syntax-for-creating-lambda-functions">Syntax for creating lambda functions</h3>
<p>Here is the syntax for creating a lambda function in Python:</p>
<pre><code class="lang-python"><span class="hljs-keyword">lambda</span> arguments: expression
</code></pre>
<h2 id="heading-lambda-functions-vs-named-functions-defined-using-the-def-keyword">Lambda Functions vs Named Functions Defined Using the <code>def</code> Keyword</h2>
<p>When compared to named functions defined using the <code>def</code> keyword, lambda functions have some key differences. </p>
<p>Named functions can have multiple expressions and they use return statements. Lambda functions can only have one expression and the value of that expression is returned automatically. </p>
<p>Named functions can also be reused throughout a program, while lambda functions are used only once.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">greet</span>(<span class="hljs-params">name</span>):</span>
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello "</span> + name
print(greet(<span class="hljs-string">"John"</span>)) 

<span class="hljs-comment"># Output: "Hello John"</span>
</code></pre>
<p>As you can see, the named function is defined using the <code>def</code> keyword, followed by the function name and its inputs in parentheses. The function body is indented, and the return statement is used to return the result of the expression. </p>
<p>Named functions can be called multiple times, making them more flexible than lambda functions for complex operations.</p>
<p>Here's the equivalent code using a named function defined with the <code>lambda</code> keyword:</p>
<pre><code class="lang-python">greet = <span class="hljs-keyword">lambda</span> name: <span class="hljs-string">"Hello "</span> + name
print(greet(<span class="hljs-string">"John"</span>)) 

<span class="hljs-comment"># Output: "Hello John"</span>
</code></pre>
<h2 id="heading-how-to-use-lambda-functions"><strong>How to Use Lambda Functions</strong></h2>
<p>This section covers the basics of how to create and use lambda functions, including their syntax and how to use them as arguments in higher-order functions such as map, filter, and reduce. </p>
<p>Additionally, this section explores how you can use lambda functions in sorting and in list comprehensions. By the end, you should have a foundational understanding of the basic uses of lambda functions.</p>
<h3 id="heading-how-to-use-lambda-functions-as-arguments-in-higher-order-functions-map-filter-reduce">How to use lambda functions as arguments in higher-order functions (<code>map</code>, <code>filter</code>, <code>reduce</code>)</h3>
<p>Lambda functions are often used as arguments in higher-order functions such as <code>map</code>, <code>filter</code>, and <code>reduce</code>. These functions allow you to apply a given operation to every element of a list or other iterable.</p>
<p>Here's an example of using a lambda function with the <code>map</code> function:</p>
<pre><code class="lang-python">numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]
squared_numbers = list(map(<span class="hljs-keyword">lambda</span> x: x**<span class="hljs-number">2</span>, numbers))
print(squared_numbers) 

<span class="hljs-comment"># Output: [1, 4, 9, 16, 25]</span>
</code></pre>
<p>In this example, the lambda function takes one input <code>x</code> and returns the square of that value. The <code>map</code> function applies this operation to every element of the <code>numbers</code> list and returns a new list with the results.</p>
<p>Here's another example using the <code>filter</code> function:</p>
<pre><code class="lang-python">numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]
even_numbers = list(filter(<span class="hljs-keyword">lambda</span> x: x % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>, numbers))
print(even_numbers) 

<span class="hljs-comment"># Output: [2, 4]</span>
</code></pre>
<p>In this example, the lambda function takes one input <code>x</code> and returns <code>True</code> if <code>x</code> is even, and <code>False</code> otherwise. The <code>filter</code> function applies this operation to every element of the <code>numbers</code> list and returns a new list with only the elements that returned <code>True</code>.</p>
<h3 id="heading-how-to-use-lambda-functions-to-return-functions-as-values">How to use lambda functions to return functions as values</h3>
<p>You can also use lambda functions to return functions as values. For example:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">make_adder</span>(<span class="hljs-params">x</span>):</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">lambda</span> y: x + y
add5 = make_adder(<span class="hljs-number">5</span>)
print(add5(<span class="hljs-number">3</span>)) 

<span class="hljs-comment"># Output: 8</span>
</code></pre>
<p>In this example, the <code>make_adder</code> function takes one input <code>x</code> and returns a lambda function that takes one input <code>y</code> and returns the sum of <code>x</code> and <code>y</code>. The <code>add5</code> variable is assigned the result of calling <code>make_adder(5)</code>, meaning it now references a lambda function that adds 5 to its input.</p>
<h3 id="heading-how-to-use-lambda-functions-in-sorting">How to use lambda functions in sorting</h3>
<p>You can also use lambda functions in sorting operations to specify custom sort orders. For example:</p>
<pre><code class="lang-python">numbers = [<span class="hljs-number">3</span>, <span class="hljs-number">1</span>, <span class="hljs-number">4</span>, <span class="hljs-number">1</span>, <span class="hljs-number">5</span>, <span class="hljs-number">9</span>, <span class="hljs-number">2</span>, <span class="hljs-number">6</span>, <span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>]
sorted_numbers = sorted(numbers, key=<span class="hljs-keyword">lambda</span> x: -x)
print(sorted_numbers) 

<span class="hljs-comment"># Output: [9, 6, 5, 5, 5, 4, 3, 3, 2, 1, 1]</span>
</code></pre>
<p>In this example, the lambda function takes one input <code>x</code> and returns <code>-x</code>, meaning that the sort order will be in descending order. The <code>sorted</code> function sorts the <code>numbers</code> list based on the values returned by the lambda function.</p>
<h2 id="heading-limitations-of-lambda-functions">Limitations of Lambda Functions</h2>
<p>While lambda functions are a convenient way to write short and simple functions, they have some limitations. </p>
<p>One of the main limitations is that lambda functions are limited to a single expression, meaning that they cannot contain multiple statements or complex control flow. </p>
<p>In addition, lambda functions cannot be referenced by name and can only be invoked when they are defined, which makes them less flexible than named functions.</p>
<p>Another limitation is that lambda functions do not have a name, which can make debugging more difficult and make it harder to understand the code. </p>
<p>In general, it's a good idea to use named functions for complex operations and only use lambda functions for short and simple operations.</p>
<h2 id="heading-advanced-uses-of-lambda-functions"><strong>Advanced Uses of Lambda Functions</strong></h2>
<p>This section covers how to use lambda functions with advanced functions such as reduce, filter, sorted, and key arguments. Additionally, this section provides information on using lambda functions to create anonymous functions for event handlers.</p>
<h3 id="heading-how-to-use-lambda-functions-with-reduce">How to use lambda functions with <code>reduce</code></h3>
<p>The <code>reduce</code> function is a higher-order function that takes a binary function (a function that takes two arguments) and a list. It returns a single value that is the result of applying the binary function to the elements of the list in a cumulative way. </p>
<p>For example, to calculate the product of all elements in a list, you could use the following code:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> reduce
numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]
product = reduce(<span class="hljs-keyword">lambda</span> x, y: x*y, numbers)
print(product) 

<span class="hljs-comment"># Output: 120</span>
</code></pre>
<p>In this example, the lambda function <code>lambda x, y: x*y</code> is used as the binary function in the <code>reduce</code> function. The <code>reduce</code> function starts by applying the binary function to the first two elements of the list, and then applies the result to the next element, and so on until it has processed all elements of the list.</p>
<h3 id="heading-how-to-use-lambda-functions-with-filter">How to use lambda functions with <code>filter</code></h3>
<p>The <code>filter</code> function is another higher-order function that takes a function and a list, and returns a new list that contains only the elements of the original list for which the function returns <code>True</code>. </p>
<p>For example, to filter out even numbers from a list, you could use the following code:</p>
<pre><code class="lang-python">numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]
even_numbers = list(filter(<span class="hljs-keyword">lambda</span> x: x % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>, numbers))
print(even_numbers) 

<span class="hljs-comment"># Output: [2, 4]</span>
</code></pre>
<p>In this example, the lambda function <code>lambda x: x % 2 == 0</code> is used as the function argument in the <code>filter</code> function. The <code>filter</code> function invokes this lambda function for each element in the <code>numbers</code> list and includes the element in the result list only if the lambda function returns <code>True</code>.</p>
<h3 id="heading-how-to-use-lambda-functions-with-the-sorted-function">How to use lambda functions with the <code>sorted</code> function</h3>
<p>The <code>sorted</code> function is a built-in function that sorts a list of elements. The <code>sorted</code> function can take an optional <code>key</code> argument, which is a function that takes an element of the list and returns a value that is used as the sort key. </p>
<p>For example, to sort a list of dictionaries by a specific key, you could use the following code:</p>
<pre><code class="lang-python">employees = [{<span class="hljs-string">"name"</span>: <span class="hljs-string">"John"</span>, <span class="hljs-string">"age"</span>: <span class="hljs-number">32</span>},              {<span class="hljs-string">"name"</span>: <span class="hljs-string">"Jane"</span>, <span class="hljs-string">"age"</span>: <span class="hljs-number">27</span>},              {<span class="hljs-string">"name"</span>: <span class="hljs-string">"Jim"</span>, <span class="hljs-string">"age"</span>: <span class="hljs-number">40</span>}]
sorted_employees = sorted(employees, key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-string">"age"</span>])
print(sorted_employees)

<span class="hljs-comment"># Output: [{"name": "Jane", "age": 27}, </span>
<span class="hljs-comment">#          {"name": "John", "age": 32}, </span>
<span class="hljs-comment">#          {"name": "Jim", "age": 40}]</span>
</code></pre>
<p>In this example, the lambda function <code>lambda x: x["age"]</code> is used as the <code>key</code> argument in the <code>sorted</code> function. The <code>sorted</code> function uses this lambda function to extract the "age" value for each dictionary in the <code>employees</code> list and uses these values as the sort keys.</p>
<h3 id="heading-how-to-use-lambda-functions-in-the-key-argument-of-various-functions">How to use lambda functions in the <code>key</code> argument of various functions</h3>
<p>In addition to the <code>sorted</code> function, many other functions in Python can take a <code>key</code> argument, including the <code>max</code>, <code>min</code>, and <code>sorted</code> functions. </p>
<p>The <code>key</code> argument is a function that takes an element of the list and returns a value that is used as the sort key, as well as for comparison purposes in the case of the <code>max</code> and <code>min</code> functions.</p>
<p>For example, to find the employee with the highest salary in a list of employees, you could use the following code:</p>
<pre><code class="lang-python">employees = [{<span class="hljs-string">"name"</span>: <span class="hljs-string">"John"</span>, <span class="hljs-string">"salary"</span>: <span class="hljs-number">50000</span>}, {<span class="hljs-string">"name"</span>: <span class="hljs-string">"Jane"</span>, <span class="hljs-string">"salary"</span>: <span class="hljs-number">55000</span>}, {<span class="hljs-string">"name"</span>: <span class="hljs-string">"Jim"</span>, <span class="hljs-string">"salary"</span>: <span class="hljs-number">60000</span>}]
highest_salary_employee = max(employees, key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-string">"salary"</span>])
print(highest_salary_employee) 

<span class="hljs-comment"># Output: {"name": "Jim", "salary": 60000}</span>
</code></pre>
<p>In this example, the lambda function <code>lambda x: x["salary"]</code> is used as the <code>key</code> argument in the <code>max</code> function. The <code>max</code> function uses this lambda function to extract the "salary" value for each employee in the <code>employees</code> list and uses these values to compare the employees and find the one with the highest salary.</p>
<h3 id="heading-how-to-use-lambda-functions-to-create-anonymous-functions-for-event-handlers">How to use lambda functions to create anonymous functions for event handlers</h3>
<p>You can also use lambda functions to create anonymous functions for event handlers in GUI programming or for other similar purposes. </p>
<p>For example, in the following code, a button click event is handled using a lambda function in Tkinter (a GUI programming toolkit for Python):</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> tkinter <span class="hljs-keyword">as</span> tk

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">on_button_click</span>():</span>
    print(<span class="hljs-string">"Button clicked!"</span>)

root = tk.Tk()
button = tk.Button(root, text=<span class="hljs-string">"Click Me!"</span>, command=<span class="hljs-keyword">lambda</span>: print(<span class="hljs-string">"Button clicked!"</span>))
button.pack()
root.mainloop()
</code></pre>
<p>In this example, we use the lambda function <code>lambda: print("Button clicked!")</code> as the <code>command</code> argument of the <code>Button</code> widget in Tkinter. When the button is clicked, the lambda function is executed and the message "Button clicked!" is printed to the console.</p>
<p>This demonstrates the versatility and flexibility of lambda functions. You can use them in a variety of contexts where anonymous functions are required.</p>
<h2 id="heading-best-practices-for-using-lambda-functions"><strong>Best Practices for Using Lambda Functions</strong></h2>
<p>This section covers a range of best practices, including keeping lambda functions simple and easy to understand, avoiding complex expressions and statements, choosing the appropriate type of function for the task, and documenting lambda functions for better code readability. </p>
<p>We'll also highlight the importance of using descriptive variable names in lambda functions to improve the readability of your code.</p>
<h3 id="heading-keep-lambda-functions-simple-and-easy-to-understand">Keep lambda functions simple and easy to understand</h3>
<p>One of the best practices for using lambda functions is to keep them simple and easy to understand. </p>
<p>Lambda functions are intended to be small, anonymous, single-expression functions, and complex or multi-statement functions are better suited to be defined using the <code>def</code> keyword.</p>
<p>For example, the following lambda function is simple, easy to understand, and does exactly what it is intended to do:</p>
<pre><code class="lang-python">square = <span class="hljs-keyword">lambda</span> x: x * x
print(square(<span class="hljs-number">5</span>)) 

<span class="hljs-comment"># Output: 25</span>
</code></pre>
<h3 id="heading-avoid-complex-expressions-and-statements-in-lambda-functions">Avoid complex expressions and statements in lambda functions</h3>
<p>In addition to keeping lambda functions simple, it is also important to avoid complex expressions and statements in lambda functions. </p>
<p>Complex expressions and statements make the code harder to understand and maintain, and can lead to bugs.</p>
<p>For example, the following lambda function is too complex and difficult to understand:</p>
<pre><code class="lang-python">calculate = <span class="hljs-keyword">lambda</span> x, y: x + y <span class="hljs-keyword">if</span> x &gt; y <span class="hljs-keyword">else</span> x - y
print(calculate(<span class="hljs-number">5</span>, <span class="hljs-number">10</span>)) 

<span class="hljs-comment"># Output: -5</span>
</code></pre>
<p>In such cases, it is better to define a named function using the <code>def</code> keyword and provide a meaningful name for the function. This makes the code more readable and easier to maintain:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">calculate</span>(<span class="hljs-params">x, y</span>):</span>
    <span class="hljs-keyword">if</span> x &gt; y:
        <span class="hljs-keyword">return</span> x + y
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> x - y

print(calculate(<span class="hljs-number">5</span>, <span class="hljs-number">10</span>)) 

<span class="hljs-comment"># Output: -5</span>
</code></pre>
<h3 id="heading-when-to-use-lambda-functions-and-when-to-use-named-functions">When to use lambda functions and when to use named functions</h3>
<p>Lambda functions are best used in situations where you need a small, anonymous, single-expression function. They are not well suited for complex functions with multiple expressions and statements.</p>
<p>For example, a good use case for a lambda function is as an argument to a higher-order function such as <code>map</code>, <code>filter</code>, or <code>reduce</code>. A bad use case for a lambda function is a complex function with multiple expressions and statements.</p>
<p>In general, it is better to use named functions defined using the <code>def</code> keyword for functions that are complex, multi-statement, or are used multiple times in your code.</p>
<h3 id="heading-document-lambda-functions-for-better-code-readability">Document lambda functions for better code readability</h3>
<p>Another best practice for using lambda functions is to document them for better code readability. </p>
<p>While lambda functions are often intended to be simple and easy to understand, it can still be helpful to provide a brief explanation of what the function does in the form of a docstring or a comment.</p>
<p>For example, the following lambda function is documented for better code readability:</p>
<pre><code class="lang-python"><span class="hljs-comment"># This lambda function returns the square of its input</span>
square = <span class="hljs-keyword">lambda</span> x: x * x
print(square(<span class="hljs-number">5</span>)) 

<span class="hljs-comment"># Output: 25</span>
</code></pre>
<h3 id="heading-use-descriptive-variable-names-in-lambda-functions">Use descriptive variable names in lambda functions</h3>
<p>Finally, it is important to use descriptive variable names in lambda functions, just as you would in any other function. Descriptive variable names make the code easier to understand and maintain.</p>
<p>For example, the following lambda function uses descriptive variable names:</p>
<pre><code class="lang-python"><span class="hljs-comment"># This lambda function returns the sum of its inputs</span>
sum = <span class="hljs-keyword">lambda</span> x, y: x + y
print(sum(<span class="hljs-number">5</span>, <span class="hljs-number">10</span>)) 

<span class="hljs-comment"># Output: 15</span>
</code></pre>
<p>By following these best practices, you can ensure that your lambda functions are clear, concise, and easy to understand, making your code more readable, maintainable, and error-free.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>In this guide, we covered the basics of lambda functions in Python, including their definition and purpose, syntax, and basic and advanced usage in various applications. </p>
<p>We also discussed some best practices for using lambda functions, including keeping them simple and easy to understand, avoiding complex expressions and statements, choosing the appropriate type of function for the task, and documenting them for better code readability.</p>
<p>Lambda functions can be a powerful tool for writing concise, readable, and efficient code. But they have some limitations, such as being restricted to a single expression and having limited functionality compared to named functions. It's important to consider these limitations and choose the appropriate type of function for the task at hand.</p>
<p>In conclusion, this guide has provided an overview of lambda functions and their uses in Python, and I hope that it has been helpful in your journey to learn more about this topic. For further learning, you may want to explore the official Python documentation and practice using lambda functions in your own projects.</p>
<hr>
<p>Visit my <a target="_blank" href="https://blog.ashutoshkrris.in">blog</a> to read more articles like this. You may also choose to follow me on <a target="_blank" href="https://twitter.com/ashutoshkrris">Twitter</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python Anonymous Function – How to Use Lambda Functions ]]>
                </title>
                <description>
                    <![CDATA[ You can use functions in programming to store a piece of code that can be invoked when needed. This prevents you from retyping the same logic every time you need that code. In this article, you'll learn how to create and use anonymous functions in Py... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-lambda-functions-in-python/</link>
                <guid isPermaLink="false">66b0a2ed7cd8dca6718a2248</guid>
                
                    <category>
                        <![CDATA[ functions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ihechikara Abba ]]>
                </dc:creator>
                <pubDate>Wed, 15 Feb 2023 17:17:35 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/02/lambda-functions-in-python.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You can use functions in programming to store a piece of code that can be invoked when needed. This prevents you from retyping the same logic every time you need that code.</p>
<p>In this article, you'll learn how to create and use anonymous functions in Python. They are also called lambda functions.</p>
<p>We'll begin with a quick overview of how regular functions are created in Python. Then you'll learn the syntax and practical applications of anonymous functions in Python. </p>
<p>You'll also see some of the differences between lambda and regular functions in Python, and when to use lambda functions.</p>
<h2 id="heading-how-to-use-functions-in-python">How to Use Functions in Python</h2>
<p>Functions prevent you from reinventing the wheel when certain logic is required multiple times.</p>
<p>Consider the code below:</p>
<pre><code class="lang-python">first_addition = <span class="hljs-number">2</span>+<span class="hljs-number">3</span> 
print(first_addition) <span class="hljs-comment"># 5 </span>

second_addition = <span class="hljs-number">3</span>+<span class="hljs-number">5</span> 
print(second_addition) <span class="hljs-comment"># 8</span>
</code></pre>
<p>We had to recreate the logic for addition multiple times in different variables. Imagine if you had to do this a hundred times.</p>
<p>With a function, you can create the logic once and reuse it as much as you want to. Here's an example in Python:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_numbers</span>(<span class="hljs-params">a,b</span>):</span> <span class="hljs-keyword">return</span> a + b 

print(add_numbers(<span class="hljs-number">2</span>,<span class="hljs-number">3</span>)) <span class="hljs-comment"># 5 </span>
print(add_numbers(<span class="hljs-number">3</span>,<span class="hljs-number">5</span>)) <span class="hljs-comment"># 8 </span>
print(add_numbers(<span class="hljs-number">5</span>,<span class="hljs-number">7</span>)) <span class="hljs-comment"># 12</span>
</code></pre>
<p>Using the <code>def</code> keyword, we created a function called <code>add_numbers(a,b)</code>. It takes two parameters – <code>a</code> and <code>b</code>. The function returns the sum of <code>a</code> and <code>b</code>.</p>
<p>So to use the logic multiple times, we just had to call the function and pass in different parameters for different operations:</p>
<pre><code class="lang-python">print(add_numbers(<span class="hljs-number">2</span>,<span class="hljs-number">3</span>)) <span class="hljs-comment"># 5 </span>
print(add_numbers(<span class="hljs-number">3</span>,<span class="hljs-number">5</span>)) <span class="hljs-comment"># 8 </span>
print(add_numbers(<span class="hljs-number">5</span>,<span class="hljs-number">7</span>)) <span class="hljs-comment"># 12</span>
</code></pre>
<p>Now let's take a look at anonymous/lambda functions in Python.</p>
<h2 id="heading-how-to-use-lambda-functions-in-python">How to Use Lambda Functions in Python</h2>
<p>An anonymous function in Python is a function without a name. It can be immediately invoked or stored in a variable.</p>
<p>Anonymous functions in Python are also known as lambda functions.</p>
<p>Here's the syntax for creating a lambda function in Python:</p>
<pre><code class="lang-python"><span class="hljs-keyword">lambda</span> parameter(s) : expression
</code></pre>
<p>There are three values that define a lambda function as seen in the syntax above:</p>
<ul>
<li>A lambda function is created using the <code>lambda</code> keyword.</li>
<li>The keyword is followed by one or many parameters.</li>
<li>Lastly, an expression is provided for the function. This is the part of the code that gets executed/returned. </li>
</ul>
<p>The parameter(s) and expression are separated by a colon.</p>
<p>Here's an example:</p>
<pre><code class="lang-python">add_numbers = <span class="hljs-keyword">lambda</span> a,b : a + b 

print(add_numbers(<span class="hljs-number">2</span>,<span class="hljs-number">3</span>)) <span class="hljs-comment"># 5</span>
</code></pre>
<p>In the code above, we created a lambda function with two parameters – <code>a</code> and <code>b</code>. The function returns the sum of the parameters.</p>
<p>That is: <code>lambda a,b : a + b</code> </p>
<p>Note that the function has no name. We assigned the lambda function to a variable called <code>add_numbers</code> so that we can easily invoke the function through the variable. </p>
<p>Without assigning a lambda function to a variable, you'd have something like this:</p>
<pre><code class="lang-python">print(<span class="hljs-keyword">lambda</span> a,b : a + b)
<span class="hljs-comment"># &lt;function &lt;lambda&gt; at 0x7f757922fb00&gt;</span>
</code></pre>
<p>The code above simply returns a lambda object in the console. </p>
<p>You can immediately call a lambda function using parenthesis:</p>
<pre><code class="lang-python">(<span class="hljs-keyword">lambda</span> a,b : a + b)(<span class="hljs-number">2</span>,<span class="hljs-number">3</span>)
</code></pre>
<p>When the code above is printed, you'll get 5 returned.</p>
<h2 id="heading-what-is-the-difference-between-lambda-and-regular-functions-in-python">What Is the Difference Between Lambda and Regular Functions in Python?</h2>
<p>Here are some differences between lambda functions and regular functions in Python:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Lambda functions</td><td>Regular functions</td></tr>
</thead>
<tbody>
<tr>
<td>Defined using the lambda keyword</td><td>Defined using the def keyword</td></tr>
<tr>
<td>Can be written in one line</td><td>Requires more than one line of code</td></tr>
<tr>
<td>No return statement required</td><td>Return statement must be defined when returning values</td></tr>
<tr>
<td>Can be used anonymously</td><td>Regular functions must be given a name</td></tr>
</tbody>
</table>
</div><h2 id="heading-when-to-use-a-lambda-function-in-python">When to Use a Lambda Function in Python</h2>
<p>Although you can use both regular functions and lambda functions to achieve the same results, here are some of the reasons why you might pick a lambda function:</p>
<p>First of all, you can use a lambda function when you need a function that'll be used just once. This is especially useful when working with functions like <code>map</code>, <code>reduce</code>, <code>filter</code>. Consider the code below:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">double_number</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">return</span> n + n

numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">7</span>, <span class="hljs-number">9</span>]

double_result = map(double_number, numbers)

print(list(double_result))
<span class="hljs-comment"># [2, 6, 10, 14, 18]</span>
</code></pre>
<p>In the code above, we created a regular function called <code>double_number</code> which doubles the value of a number. </p>
<p>Although the function was passed in as a parameter to the <code>map</code> function — <code>map(double_number, numbers)</code>, we had to write the logic before using it. </p>
<p>With lambda functions, you can do this: </p>
<pre><code class="lang-python">numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">7</span>, <span class="hljs-number">9</span>]

double_result = map(<span class="hljs-keyword">lambda</span> x : x+x, numbers)

print(list(double_result))
<span class="hljs-comment"># [2, 6, 10, 14, 18]</span>
</code></pre>
<p>As you can see above, we just passed a lambda function — <code>lambda x : x+x</code> — as a parameter to the <code>map</code> function: <code>map(lambda x : x+x, numbers)</code>.</p>
<p>We were able to achieve the same result with fewer lines of code. There was no need for defining a function first before use. </p>
<p>You can also use a lambda function when you need a function that should be invoked immediately. As you can see in the example in the previous point, we first defined the regular function before using it. Lambda functions can be invoked immediately after creating them.</p>
<p>Finally, lambdas are useful when you want to use a function inside a function. Or when you want to create a function that returns a function.</p>
<h2 id="heading-summary">Summary</h2>
<p>In this article, we talked about lambda functions in Python. There are functions without a name and can be executed with a single line of code. </p>
<p>We saw how to use regular functions in Python with some examples. </p>
<p>We then saw the syntax and a practical example of using lambda functions. </p>
<p>Lastly, we talked about the differences between lambda functions and regular functions in Python, and when to use lambda functions.</p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Hide API Keys in Frontend Apps using Netlify Functions ]]>
                </title>
                <description>
                    <![CDATA[ Netlify is a popular web development platform that makes it easier to build, deploy, and manage websites. You can use Netlify to host websites, and it helps you update and release new changes. It also provides additional features such as security, us... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/hide-api-keys-in-frontend-apps-using-netlify-functions/</link>
                <guid isPermaLink="false">66d45edbd1ffc3d3eb89ddd7</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Netlify ]]>
                    </category>
                
                    <category>
                        <![CDATA[ netlify-functions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ serverless ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Franklin Ohaegbulam ]]>
                </dc:creator>
                <pubDate>Tue, 07 Feb 2023 23:46:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/02/FCC-hide-API-keys-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Netlify is a popular web development platform that makes it easier to build, deploy, and manage websites.</p>
<p>You can use Netlify to host websites, and it helps you update and release new changes. It also provides additional features such as security, user authentication and authorization services, and more.</p>
<p>This guide focuses on showing you how to set up a Netlify serverless function to hide Application Programming Interface (API) keys in a client-side application.</p>
<p>For this lesson, you will create a stock photo search engine web application, deploy it on Netlify, and make an API call to the Pixabay API using Netlify serverless functions.</p>
<p>This is the same process for front-end applications built with ReactJS, NextJS, VueJS, Angular, or other JavaScript frameworks.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>To follow along with this tutorial, you should have the following:</p>
<ul>
<li><p>Netlify account (you can sign up <a target="_blank" href="http://netlify.com">here</a>)</p>
</li>
<li><p>Basic understanding of RESTful APIs, Lambda functions, and async/await concepts.</p>
</li>
</ul>
<p>The final demo app lives in the main branch on GitHub: <code>https://netlify-func-demo.netlify.app</code></p>
<h2 id="heading-what-is-a-netlify-function">What is a Netlify function?</h2>
<p>Netlify functions are serverless or lambda functions provided by Netlify. You use them to deploy server-side code or backend logic without the need for a dedicated server.</p>
<p>The purpose of this Netlify function is to manage serverless event-driven code and send HTTP requests that return a JSON response.</p>
<blockquote>
<p>"Serverless functions, branded as Netlify Functions when running on Netlify, are a way to deploy server-side code as API endpoints" - Netlify Docs</p>
</blockquote>
<p>It securely accesses environment variables behind the scenes via the Amazon Web Services (AWS) lambda function.</p>
<p>Secret credentials such as access tokens or API keys, hidden solely using environment variables, are less secure. This is because they can be easily retrieved from the Developer Tools through the API fetch request in the browser.</p>
<p>The API keys, if hijacked, can be misused by malicious actors, which might affect your app build threshold or cost you more if it's a paid API service.</p>
<p>Other serverless functions used for running code without having to manage servers include AWS Lambda functions, Azure functions, and Google cloud functions.</p>
<h2 id="heading-how-to-set-up-a-client-side-application">How to Set Up a Client-side Application</h2>
<h3 id="heading-how-to-clone-the-demo-app">How to Clone the Demo App</h3>
<p>To get started with this tutorial, you can clone the <strong>stock photo search engine app</strong> <a target="_blank" href="https://github.com/frankiefab100/netlify-serverless-functions-demo/tree/main">GitHub repository</a>. See the live preview on Netlify at <a target="_blank" href="https://netlify-func-demo.netlify.app">https://netlify-func-demo.netlify.app</a>.</p>
<p>The first step is to clone the repository:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/frankiefab100/netlify-serverless-functions-demo.git
</code></pre>
<p>Next, change to the <strong>netlify-serverless-functions-demo</strong> directory.</p>
<pre><code class="lang-bash"> <span class="hljs-built_in">cd</span> netlify-serverless-functions-demo
</code></pre>
<p>Then you'll need to install dependencies.</p>
<pre><code class="lang-bash">npm install
<span class="hljs-comment">#OR </span>
yarn add
</code></pre>
<p>Now run the development server. Run the following command to start the app on the server:</p>
<pre><code class="lang-bash">netlify dev
</code></pre>
<p>The app will be ready on <code>https://localhost:8888</code>.</p>
<p>Alternatively, you can skip the above steps if you wish to follow along by building the app from scratch. In the next step, you will build a stock photo search engine JavaScript application.</p>
<h3 id="heading-how-to-build-the-demo-app-using-javascript">How to Build the Demo App using JavaScript</h3>
<p>The first step is to set up a front-end app. Open your favorite code editor, such as VS Code.</p>
<p>Then, create a <strong>dist</strong> directory and inside it create an <strong>index.html</strong> file. Populate it with the following code:</p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"style.css"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Stock Photos Search Engine<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Search For Stock Photos<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"search-section"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
            <span class="hljs-attr">name</span>=<span class="hljs-string">"search"</span>
            <span class="hljs-attr">class</span>=<span class="hljs-string">"search"</span>
            <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter a keyword"</span>
          /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">"searchBtn"</span>
            <span class="hljs-attr">class</span>=<span class="hljs-string">"search-btn"</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">"Search"</span>
          /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"photo-wrapper"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">""</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"photo"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./script.js"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>In the same <code>dist</code> directory, add the following styling to style.css:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* dist/style.css */</span>
* {
  <span class="hljs-attribute">box-sizing</span>: border-box;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
}

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#222</span>;
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">"Roboto"</span>, sans-serif;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1rem</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100vw</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
}

<span class="hljs-selector-class">.container</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-direction</span>: column;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">min-height</span>: <span class="hljs-number">100vh</span>;
  <span class="hljs-attribute">min-width</span>: <span class="hljs-number">100vw</span>;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100%</span>;
}

<span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">padding-bottom</span>: <span class="hljs-number">20px</span>;
}

<span class="hljs-selector-class">.search-section</span> {
  <span class="hljs-attribute">display</span>: inline;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">min-width</span>: <span class="hljs-number">310px</span>;
}

<span class="hljs-selector-class">.search</span>,
<span class="hljs-selector-class">.search-btn</span> {
  <span class="hljs-attribute">border</span>: none;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1rem</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">15px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">50px</span>;
}

<span class="hljs-selector-class">.search</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#d1f3bf</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#222</span>;
  <span class="hljs-attribute">min-width</span>: <span class="hljs-number">225px</span>;
}

<span class="hljs-selector-class">.search-btn</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#04ab04</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#f6f6f6</span>;
  <span class="hljs-attribute">cursor</span>: pointer;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">min-width</span>: <span class="hljs-number">80px</span>;
  <span class="hljs-attribute">transition</span>: all <span class="hljs-number">0.3s</span> ease-in-out;
}

<span class="hljs-selector-class">.search-btn</span><span class="hljs-selector-pseudo">:hover</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#2dc22d</span>;
}

<span class="hljs-selector-class">.photo-wrapper</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">15px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">30px</span>;
}

<span class="hljs-selector-class">.photo-wrapper</span> <span class="hljs-selector-tag">img</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">200px</span>;
}
</code></pre>
<h2 id="heading-sign-up-for-a-free-account-on-pixabay">Sign Up for a Free Account on Pixabay</h2>
<p>The first step to using the <a target="_blank" href="https://pixabay.com/api/docs/">Pixabay API</a> is to sign up for an account with your email.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Pixabay-API-Documentation.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Pixabay API key section</em></p>
<p>As shown in the image above, your API key can be found below the <strong>parameters</strong> section in the <a target="_blank" href="https://pixabay.com/api/docs/">Pixabay API Docs website</a>.</p>
<h3 id="heading-create-an-environment-variable">Create an environment variable</h3>
<p>Environment variables (commonly known as "env") are combinations of key/value pairs that can affect the behavior and processes of an operating system or application.</p>
<p>Using environment variables is recommended to configure third-party services and their credentials during development.</p>
<h3 id="heading-install-dotenv">Install dotenv</h3>
<p>Once you complete the account creation on Pixabay, open your terminal and install <strong>dotenv</strong> as a package. This will enable your app to read environment variables saved in the <strong>.env</strong> file.</p>
<pre><code class="lang-javascript">npm install dotenv
#OR
yarn add -D dotenv
</code></pre>
<p>In the next step, you will save the API key in a <strong>.env</strong> file.</p>
<h3 id="heading-create-the-env-file">Create the .env file</h3>
<p>In the root directory of your app, create a <strong>.env</strong> file and store the API keys copied from your Pixabay Profile.</p>
<pre><code class="lang-plaintext">PIXABAY_API_KEY=123456-7890
</code></pre>
<p>Where <code>PIXABAY_API_KEY=123456-7890</code> represents the API key value.</p>
<p><strong>Note:</strong> Replace this key/value pair with the appropriate value.</p>
<h3 id="heading-create-a-gitignore-file">Create a .gitignore file</h3>
<p>To avoid committing sensitive files and values such as <code>node_modules</code> and <code>secret keys</code> to a public repository, create a <strong>.gitignore</strong> file in the same project root directory and add the following to it:</p>
<pre><code class="lang-plaintext">node_modules
.env
.netlify
</code></pre>
<p>The <strong>.netlify</strong> folder which contains compiled serverless functions together with other files listed will be excluded when the project is pushed to GitHub or any other version control system.</p>
<h3 id="heading-create-a-get-request-function">Create a get request function</h3>
<p>Now, you should add the fetch request logic in the <strong>script.js</strong>. You will adjust the API logic later using Netlify functions.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">/* dist/script.js */</span>
<span class="hljs-keyword">const</span> dotenv = <span class="hljs-built_in">require</span>(<span class="hljs-string">"dotenv"</span>).config();

<span class="hljs-keyword">const</span> searchbar = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".search"</span>);
<span class="hljs-keyword">const</span> submitBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".search-btn"</span>);
<span class="hljs-keyword">const</span> photoWrapper = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".photo-wrapper"</span>);

submitBtn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
  getPhoto(searchbar.value);
  searchbar.value = <span class="hljs-string">""</span>;
});

<span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"keydown"</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (e.keyCode === <span class="hljs-number">13</span>) {
    getPhoto(searchbar.value);
    searchbar.value = <span class="hljs-string">""</span>;
  }
});

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getPhoto</span>(<span class="hljs-params">keyword</span>) </span>{
  <span class="hljs-keyword">const</span> apiKey = PIXABAY_API_KEY;
  <span class="hljs-keyword">let</span> apiURL = <span class="hljs-string">`https://pixabay.com/api/?key=<span class="hljs-subst">${apiKey}</span>&amp;q=<span class="hljs-subst">${keyword}</span>&amp;image_type=photo&amp;safesearch=true&amp;per_page=3`</span>;

  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(apiURL, {
      <span class="hljs-attr">method</span>: <span class="hljs-string">"GET"</span>,
      <span class="hljs-attr">headers</span>: { <span class="hljs-attr">accept</span>: <span class="hljs-string">"application/json"</span> },
    });
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();

    <span class="hljs-keyword">let</span> imageURL = data.hits;

    imageURL.forEach(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
      <span class="hljs-keyword">let</span> imageElement = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"img"</span>);
      imageElement.setAttribute(<span class="hljs-string">"src"</span>, <span class="hljs-string">`<span class="hljs-subst">${result.webformatURL}</span>`</span>);
      photoWrapper.appendChild(imageElement);
    });
  } <span class="hljs-keyword">catch</span> (error) {
    alert(error);
  }
}
</code></pre>
<p><strong>Note:</strong> As mentioned earlier, if the codebase of this app is published on GitHub. The API key will still be accessible from the client side on a browser, although the <code>.env</code> file that contains the secret key was excluded.</p>
<p>To illustrate this, select the <a target="_blank" href="https://github.com/frankiefab100/netlify-serverless-functions-demo/tree/testing"><code>testing</code> branch</a> of this app repository. The <a target="_blank" href="https://testing--netlify-func-demo.netlify.app/">Live site preview</a> will display the following Reference Errors in your browser console:</p>
<pre><code class="lang-bash">Uncaught ReferenceError: require is not defined
Uncaught ReferenceError: require is not defined at getPhotos
Uncaught ReferenceError: process is not defined at getPhotos
</code></pre>
<p>This is because there is no way to reference the environment variables specified in the <strong>.env</strong> file, since they weren't committed to the public repository on GitHub.</p>
<p>In the next step, select and clone the <code>[testing](https://github.com/frankiefab100/netlify-serverless-functions-demo/tree/testing)</code> branch on your local machine with the following commands:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/frankiefab100/netlify-serverless-functions-demo.git
<span class="hljs-built_in">cd</span> netlify-serveless-functions-demo
npm install
netlify dev
</code></pre>
<p>The app should launch on your browser via <code>localhost:8888</code>.</p>
<p>Now, go to the <strong>Developer tools,</strong> right-click and select <strong>Inspect</strong>. Alternatively, press the <strong>F12</strong> key. Then, navigate to <strong>Network tab</strong> and tab on the <code>getPhotos.js</code> request URL.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Screenshot--124----Copy.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>API key displayed in the Network tab in Developer tools</em></p>
<p>You should see the API key publicly exposed in the <strong>Network tab</strong>'s <strong>Headers</strong> section and return as a response data in your browser.</p>
<p>This is a security issue since the Network tab in the Developer tools is typically responsible to display informations such as the request URL, response status, and response data.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Screenshot--127----Copy.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>API key returned as a response data and exposed in the URL of the request</em></p>
<p>In the next section, you will find a way to secure the API key using Netlify functions.</p>
<h2 id="heading-how-to-get-started-with-netlify-functions">How to Get Started with Netlify Functions</h2>
<p>First, you'll need to go into your terminal and install <strong>Netlify CLI</strong> and <strong>Lambda</strong> as Devdependencies. You can do that by running this command:</p>
<pre><code class="lang-bash">npm install -g netlify-cli netlify-lambda
<span class="hljs-comment">#OR </span>
yarn add -D netlify-cli netlify-lambda --save-dev
</code></pre>
<h3 id="heading-add-custom-build-and-development-commands-in-packagejson">Add custom build and development commands in package.json</h3>
<p>These commands build and start the app in the server and also launch the app on your web browser. Here's an example of how you might add these script commands in the <strong>package.json</strong> file:</p>
<pre><code class="lang-bash"><span class="hljs-string">"scripts"</span>: {
   <span class="hljs-string">"build"</span>: <span class="hljs-string">"npm run-script"</span>,
   <span class="hljs-string">"dev"</span>: <span class="hljs-string">"netlify dev"</span>
 }
</code></pre>
<h3 id="heading-install-axios">Install Axios</h3>
<p>You will use the <code>axios.get</code> method, because it is a node function unlike the <code>fetch</code> method that is intended for browser runtime.</p>
<p>To install Axios, open your terminal and enter the command:</p>
<pre><code class="lang-bash">npm install axios
<span class="hljs-comment">#OR</span>
yarn add -D axios
</code></pre>
<p>In this case, you are working with a vanilla JavaScript app, so you should import Axios in the <code>getPhotos.js</code> file as:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">"axios"</span>);
</code></pre>
<p>For JavaScript libraries, like React, import it as follows:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
</code></pre>
<h3 id="heading-create-a-serverless-function">Create a serverless function</h3>
<p>In the root of the project, create a folder named <code>netlify,</code>and inside it create another folder <code>functions</code>. In this <code>functions</code> directory, create a file named <code>getPhotos.js</code>.</p>
<p>You will create a serverless function in the <code>getPhotos</code>. This will completely hide the API keys while fetching images from the <a target="_blank" href="https://pixabay.com/api">Pixabay API</a>.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//netlify/functions/getPhotos.js </span>
<span class="hljs-built_in">require</span>(<span class="hljs-string">"dotenv"</span>).config();

<span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">"axios"</span>);

<span class="hljs-built_in">exports</span>.handler = <span class="hljs-keyword">async</span> (event, context) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { keyword } = event.queryStringParameters;
    <span class="hljs-keyword">let</span> response = <span class="hljs-keyword">await</span> axios.get(
      <span class="hljs-string">`https://pixabay.com/api/?key=<span class="hljs-subst">${process.env.PIXABAY_API_KEY}</span>&amp;q=<span class="hljs-subst">${keyword}</span>&amp;image_type=photo&amp;safesearch=true&amp;per_page=3`</span>,
      {
        <span class="hljs-attr">headers</span>: { <span class="hljs-attr">Accept</span>: <span class="hljs-string">"application/json"</span>, <span class="hljs-string">"Accept-Encoding"</span>: <span class="hljs-string">"identity"</span> },
        <span class="hljs-attr">params</span>: { <span class="hljs-attr">trophies</span>: <span class="hljs-literal">true</span> },
      }
    );

    <span class="hljs-keyword">let</span> imageURL = response.data.hits;

    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
      <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({ imageURL }),
    };
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">statusCode</span>: <span class="hljs-number">500</span>,
      <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({ error }),
    };
  }
};
</code></pre>
<p>Here, the <code>process.env.PIXABAY_API_KEY</code> references API key environment configuration specified in the <code>.env</code> file for development mode.</p>
<p>The <code>keyword</code> parameter accepts a string accessible in the <code>queryStringParameters</code> property and returns a response data stored in the variable <code>imageURL</code>. This will get passed to the <code>script.js</code> as request response (we'll discuss this later).</p>
<p>If the GET request is successful, it returns a response of <code>statusCode</code> 200 with the corresponding response as a JSON object. For errors, we will get an alert with the error message and status code.</p>
<p>Due to changes in version, Axios might return Buffer as a response in your terminal window, that looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/netlify-data.JPG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Buffer response from Axios in Terminal</em></p>
<p>To prevent this, you should attach the following to the GET request:</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">let</span> response = <span class="hljs-keyword">await</span> axios.get(
      <span class="hljs-string">`https://pixabay.com/api/?key=<span class="hljs-subst">${process.env.PIXABAY_API_KEY}</span>&amp;q=<span class="hljs-subst">${keyword}</span>&amp;image_type=photo&amp;safesearch=true&amp;per_page=3`</span>,
      {
        <span class="hljs-attr">headers</span>: { <span class="hljs-attr">Accept</span>: <span class="hljs-string">"application/json"</span>, <span class="hljs-string">"Accept-Encoding"</span>: <span class="hljs-string">"identity"</span> },
        <span class="hljs-attr">params</span>: { <span class="hljs-attr">trophies</span>: <span class="hljs-literal">true</span> },
      }
    );
</code></pre>
<h3 id="heading-create-a-netlify-configuration-file">Create a Netlify configuration file</h3>
<p>In the project root directory, create a <code>netlify.toml</code> file. This file specifies how Netlify builds and deploys your app.</p>
<p>Now, add the following build configurations in <code>netlify.toml</code>:</p>
<pre><code class="lang-bash">[build]
  <span class="hljs-built_in">command</span> = <span class="hljs-string">"npm run build"</span>
  <span class="hljs-built_in">functions</span> = <span class="hljs-string">"netlify/functions"</span>
  publish = <span class="hljs-string">"dist"</span>
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li><p><code>command = "npm run build"</code> triggers the Netlify CLI to build the app from the functions.</p>
</li>
<li><p><code>functions = "netlify/functions"</code> indicates that the <code>getPhotos</code> functions exist in the <code>netlify/functions</code> directory.</p>
</li>
<li><p><code>publish = "dist"</code> identifies <code>dist</code> as the directory where the file will be served from.</p>
</li>
</ul>
<h3 id="heading-update-the-scriptjs-file-with-the-netlify-functions-request-url">Update the script.js file with the Netlify functions request URL</h3>
<p>Next, update the <code>apiURL</code> from this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> apiURL = <span class="hljs-string">`https://pixabay.com/api/?key=<span class="hljs-subst">${apiKey}</span>&amp;q=<span class="hljs-subst">${keyword}</span>&amp;image_type=photo&amp;safesearch=true&amp;per_page=3`</span>;
</code></pre>
<p>to the functions HTTP request endpoint:</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">let</span> apiURL = <span class="hljs-string">`/.netlify/functions/getPhotos?keyword=<span class="hljs-subst">${keyword}</span>`</span>;
</code></pre>
<p>This serverless function will get queried to the client-side of your app through the endpoint: <code>/.netlify/functions/getPhotos</code>. Once a fetch request is sent, the <code>getphotos</code> function will be invoked and accessed in the <code>script.js.</code></p>
<p>The <code>getPhotos</code> Netlify functions' response <code>imageURL</code> will be passed and the data accessed as the value of the <code>keyword</code> parameter in the query string of function. It will get loop through to return three images from the Pixabay API to the client-side.</p>
<p>The <strong>script.js</strong> file should look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">/* dist/script.js */</span>
<span class="hljs-keyword">const</span> searchbar = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".search"</span>);
<span class="hljs-keyword">const</span> submitBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".search-btn"</span>);
<span class="hljs-keyword">const</span> photoWrapper = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".photo-wrapper"</span>);

submitBtn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
  getPhoto(searchbar.value);
  searchbar.value = <span class="hljs-string">""</span>;
  photoWrapper.innerHTML = <span class="hljs-string">""</span>;
});

<span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"keydown"</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (e.keyCode === <span class="hljs-number">13</span>) {
    getPhoto(searchbar.value);
    searchbar.value = <span class="hljs-string">""</span>;
    photoWrapper.innerHTML = <span class="hljs-string">""</span>;
  }
});

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getPhoto</span>(<span class="hljs-params">keyword</span>) </span>{
  <span class="hljs-keyword">let</span> apiURL = <span class="hljs-string">`/.netlify/functions/getPhotos?keyword=<span class="hljs-subst">${keyword}</span>`</span>;

  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(apiURL, {
      <span class="hljs-attr">method</span>: <span class="hljs-string">"GET"</span>,
      <span class="hljs-attr">headers</span>: { <span class="hljs-attr">accept</span>: <span class="hljs-string">"application/json"</span> },
    });
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; data.imageURL.length; i++) {
      <span class="hljs-keyword">let</span> imageElement = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"img"</span>);
      imageElement.setAttribute(<span class="hljs-string">"src"</span>, <span class="hljs-string">`<span class="hljs-subst">${data.imageURL[i].webformatURL}</span>`</span>);
      photoWrapper.appendChild(imageElement);
    }
  } <span class="hljs-keyword">catch</span> (error) {
    alert(error);
  }
}
</code></pre>
<p><strong>Note:</strong> From the codebase above, your environment variable is secure since it is accessed from the serverless function.</p>
<h3 id="heading-run-the-development-server">Run the development server</h3>
<p>Now, execute your app by running the command:</p>
<pre><code class="lang-bash">netlify dev
</code></pre>
<p>This will load the <strong>getPhotos</strong> function via <code>https://localhost:8888/.netlify/functions/getPhotos.</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/netlify-dev-terminal.JPG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>netlify build terminal output</em></p>
<p>Then, start the development server and launch the application in your default web browser on <code>localhost:8888</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/netlify-success2.JPG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>netlify function ready on https://localhost:8888</em></p>
<p>At this point, the Netlify function is fully setup, and you can now proceed to make <code>GET</code> HTTP requests.</p>
<h3 id="heading-how-to-send-fetch-requests">How to Send Fetch Requests</h3>
<p>Now that you already have the web app served, go ahead and send a fetch request. Enter some text in the search input field and hit <strong>Enter</strong> or click the button to fetch images from the Pixabay API.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Stock-Photos-Search-Engine--1-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>flower images fetched from Pixabay API</em></p>
<p>For more information about the Pixabay API, see the <a target="_blank" href="https://pixabay.com/api/docs">Pixabay documentation</a>.</p>
<p>The preceding command will send a request to the serverless function and then return six responses. Here's what the response looks like in your terminal windows:</p>
<blockquote>
<p>Request from ::1: GET /.netlify/functions/getPhotos?keyword=flower<br>Response with status 200 in 4895 ms.</p>
</blockquote>
<p>You can also use <strong>Developer tools</strong> through the <strong>Network</strong> tab to validate the request.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Screenshot--118----Copy.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>serverless function API response data</em></p>
<p>The fetch request returns our app URL, the <strong>getPhotos</strong> Netlify function, script.js and the images from Pixabay.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Screenshot--120-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Netlify function fetch response from Network tab's header section in the browser</em></p>
<h2 id="heading-how-to-host-the-app-on-the-remote-repository">How to Host the App on the Remote Repository</h2>
<p>Now, you should push your project to GitHub version control.</p>
<pre><code class="lang-javascript">git add .
git commit -m<span class="hljs-string">"initial commit"</span>
git push origin -u main
</code></pre>
<h2 id="heading-how-to-deploy-the-app-and-serverless-function-on-netlify">How to Deploy the App and Serverless Function on Netlify</h2>
<p>Once you have published the project on GitHub, log in to <a target="_blank" href="https://app.netlify.com">Netlify</a> and connect your GitHub account by granting authorization.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Screenshot--130-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Import project for deployment on Netlify</em></p>
<p>As shown in the image above, click the <code>Add A New Project</code> and then search for the app repository from the list. Next, click on <code>Build Your Site</code>. This will take a few minutes to complete.</p>
<p>You just deployed the app from the Netlify UI. Your app is now ready at: <code>https://netlify-func-demo.netlify.app.</code>.</p>
<p>The fetch request URL should look like this: <code>https://netlify-func-demo.netlify.app/.netlify/functions/getPhotos</code>.</p>
<h2 id="heading-optional-how-to-configure-the-netlify-app-from-the-dashboard">Optional - How to Configure the Netlify App from the Dashboard</h2>
<p>Alternatively, you can configure the Netlify command from the Netlify Dashboard. If these settings are already specified in <strong>netlify.toml</strong>, it will override any corresponding configuration.</p>
<p>First, select the project directory's Site settings.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Site-overview-netlify-func-demo1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Site settings for project directory on Netlify</em></p>
<h3 id="heading-set-the-build-command-and-publish-directory">Set the Build command and Publish directory</h3>
<p>Navigate to <code>Site settings</code> &gt; <code>Deploy</code> &gt; <code>Build &amp; deploy</code> and edit the following commands and then save the changes:</p>
<ul>
<li><p>Build command: <strong>npm run build</strong></p>
</li>
<li><p>Publish directory: <strong>dist</strong></p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Screenshot--132-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Build and deploy section on Netlify</em></p>
<h3 id="heading-set-the-functions-directory">Set the Functions directory</h3>
<p>By default, Netlify uses <code>netlify/functions</code> as the directory to find the functions to deploy them. In our case, our serverless function <code>getPhotos</code> can be found in the <code>netlify/functions</code> directory.</p>
<p>Now we'll set a custom functions directory so Netlify can find your compiled functions. Go to <code>Site settings</code> &gt; <code>Functions</code> and enter the directory path where the functions are stored in your repository.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Screenshot--131-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Functions directory section on Netlify</em></p>
<h3 id="heading-how-to-set-environment-variables-for-production">How to Set Environment Variables for Production</h3>
<p>In the Netlify Dashboard, click on <code>Site settings</code> &gt; <code>Build &amp; deploy</code> &gt; <code>Environment</code> &gt; <code>Environment variables</code> and then configure KEY/VALUE pairs as follows:</p>
<pre><code class="lang-plaintext">PIXABAY_API_KEY=your-api-key-here
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Screenshot--133-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Environment variables section on Netlify</em></p>
<p>Click on Save, and then redeploy your app so the changes can be added.</p>
<p>To redeploy the app on Netlify, navigate to <code>Deploys</code> &gt; <code>Trigger deploy</code>. Next, select <code>Clear cache and redeploy site</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Screenshot--134-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Trigger redeployment tab on Netlify</em></p>
<p><strong>Note:</strong> The environment variable (PIXABAY_API_KEY) name should match the one mentioned in the <code>getPhotos</code> codebase.</p>
<p>For a React application, prepend the API environment variable with the prefix <code>REACT_APP</code> so they can be read from the <code>.env</code> file.</p>
<pre><code class="lang-plaintext"> REACT_APP_PIXABAY_API_KEY=your-api-key-here
</code></pre>
<h2 id="heading-how-to-initialize-the-serverless-function-to-the-remote-app">How to Initialize the Serverless Function to the Remote App</h2>
<p>To connect your project directory to the existing web app deployed on Netlify, login to your Netlify account from the terminal:</p>
<pre><code class="lang-bash">netlify login
</code></pre>
<p>Next, initialize the app on Netlify by running the command in your terminal:</p>
<pre><code class="lang-bash">netlify init
</code></pre>
<p>Your app is now configured for continuous deployment via Netlify.</p>
<h2 id="heading-how-to-build-the-netlify-serverless-function">How to Build the Netlify Serverless Function</h2>
<p>You need to link your app to site ID on Netlify before running the build command on your terminal. To connect your local project folder to its site ID on Netlify, enter the command in your terminal:</p>
<pre><code class="lang-bash">netlify link
</code></pre>
<p>This will prompt you to link the folder to a site through any of the following options:</p>
<ul>
<li><p>Search by full or partial site name</p>
</li>
<li><p>Choose from a list of your recently updated sites</p>
</li>
<li><p>Enter a site ID</p>
</li>
</ul>
<p>Once you select your preferred option, it will connect the project folder to the hosted site on Netlify. This allows you run <strong>Netlify CLI</strong> commands and also automatically deploy the project repository once there are any changes in the codebase.</p>
<p>In the next step, you will build a serverless function while it is running on the server. To activate the build command defined in <code>netlify.toml</code> file, run the following command:</p>
<pre><code class="lang-bash">netlify build
</code></pre>
<p>This runs the <code>npm run-script</code> command under the hood as specified in the <code>package.json</code>. Now, your serverless function in <code>netlify/functions</code> directory is packaged and bundled successfully!</p>
<h2 id="heading-how-to-test-the-application">How to Test the Application</h2>
<p>To test and confirm that the Netlify function is working fine, run this command on your terminal:</p>
<pre><code class="lang-bash">netlify <span class="hljs-built_in">functions</span>:serve
</code></pre>
<p>This injects your project environment variables from the <strong>.env</strong> file and runs the serverless function.</p>
<h3 id="heading-how-to-confirm-api-keys-security">How to Confirm API Keys Security</h3>
<p>To inspect your app and confirm that the API keys are hidden from the public, follow the steps below:</p>
<p>Click on your hosted app URL, and navigate to <strong>Developer tools</strong> by pressing the <strong>F12</strong> key or right-clicking and selecting <strong>Inspect</strong>. Navigate to <strong>Network</strong> tab, where you should see the fetched data from the Pixabay API.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Screenshot--128-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>API key hidden from the public and unauthorized parties after inspection through the Developer tools</em></p>
<p>Now you've confirmed that you've successfully configured a serverless function and have it deployed on Netlify.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>This tutorial introduced serverless functions, asynchronous JavaScript, and Restful API concepts.</p>
<p>Hopefully you now know how to create a serverless/lambda function and secure any sensitive value such as API keys in your frontend JavaScript application.</p>
<p>If you got stuck with anything, you can access the complete source code in this <a target="_blank" href="https://github.com/frankiefab100/netlify-serverless-functions-demo/tree/main">GitHub repository</a>.</p>
<p>Thank you for reading! If you have any questions, feel free to reach out to me via <a target="_blank" href="https://twitter.com/frankiefab100">Twitter</a>.</p>
<h2 id="heading-relevant-links"><strong>Relevant Links</strong></h2>
<ul>
<li><p><a target="_blank" href="https://docs.netlify.com/functions/overview/">Netlify Functions</a></p>
</li>
<li><p><a target="_blank" href="https://www.netlify.com/blog/intro-to-serverless-functions/">Netlify Intro to Serverless Functions</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/sdras/netlify-functions-example">Netlify Functions Example</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Learn Serverless AWS by Building 7 Projects ]]>
                </title>
                <description>
                    <![CDATA[ By Sam Williams Following tutorials when you start learning serverless is a good first step. But to really get better, you need to build your own projects.  The problem is that coming up with ideas that are realistic but help you grow is hard. To hel... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-serverless-aws-by-building-7-projects/</link>
                <guid isPermaLink="false">66d460dc47a8245f78752ac1</guid>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ projects ]]>
                    </category>
                
                    <category>
                        <![CDATA[ serverless ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 26 Aug 2022 15:34:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/08/pexels-christina-morillo-1181316.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sam Williams</p>
<p>Following tutorials when you start learning serverless is a good first step. But to really get better, you need to build your own projects. </p>
<p>The problem is that coming up with ideas that are realistic but help you grow is hard.</p>
<p>To help you out, I’ve come up with 7 awesome project ideas to progressively help you become a better serverless dev.</p>
<p>If you’re new to working with Serverless, then start with the first projects. If you’ve built APIs and Dynamo with Serverless before, then pick the projects that cover the topics you want to learn most.</p>
<p>I've also made this into a video if you want to watch and follow along:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/ROiAUWX8p5E" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h1 id="heading-combination-api-project">Combination API Project</h1>
<p>This project is designed to get you familiar with deploying an API with Lambda. You'll also practice calling other APIs and merging that data.</p>
<p>There are lots of logic you could use for this, but here are two examples:</p>
<ul>
<li>Get Steam game deals, converted into your local currency</li>
<li>Get news translated into your local language</li>
</ul>
<p><img src="https://completecoding.io/wp-content/uploads/2022/08/ch2.drawio.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The architecture for this one is simple but that is exactly what you want as your first project. The idea is that the API you create will take some parameters, so look something like this</p>
<pre><code>https:<span class="hljs-comment">//apiurl.amazonaws.com/dev/steamdeals?currency=EUR</span>
https:<span class="hljs-comment">//apiurl.amazonaws.com/dev/news/fr</span>
</code></pre><p>The logic is all going to be written into the Lambda. I'm not going to write the full code but here's some pseudo-code:</p>
<pre><code><span class="hljs-keyword">const</span> handler = <span class="hljs-function">(<span class="hljs-params">event: APIGatewayProxyEvent</span>) =&gt;</span> {
    <span class="hljs-comment">// get the path or query string parameter value</span>

    <span class="hljs-comment">// hit the first API to get the first data</span>

    <span class="hljs-comment">// get the data you need to translate / convert</span>

    <span class="hljs-comment">// pass the data from API1 into API2</span>

    <span class="hljs-comment">// combine the data </span>

    <span class="hljs-comment">// return data in API Gateway format</span>
}
</code></pre><p>If you need some free and public APIs to use, then here's a massive doc of them to choose from <a target="_blank" href="https://github.com/public-apis/public-apis">https://github.com/public-apis/public-apis</a>.</p>
<p>Then building this try using the Serverless Framework or AWS CDK. These tools will make you far more valuable as a developer.</p>
<p>To get started with the Serverless Framework <a target="_blank" href="https://youtu.be/HhgXwKFUzT8">check out this video</a>.</p>
<h1 id="heading-url-shortener-project">URL Shortener Project</h1>
<p>This project will get you deploying your first DynamoDB table, then writing and reading data from it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/ch3-url-shortener.drawio.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>There are going to be two API endpoints. One to add a new URL to the shortener, one to give a shortened URL and get the original.</p>
<p>Here's the pseudo-code for the two endpoints:</p>
<pre><code><span class="hljs-comment">// Adding a new URL</span>
<span class="hljs-keyword">const</span> handler = <span class="hljs-function">(<span class="hljs-params">event: APIGatewayProxyEvent</span>) =&gt;</span> {
    <span class="hljs-comment">// get their original url (body of the event)</span>

    <span class="hljs-comment">// generate a random 5 character code</span>

    <span class="hljs-comment">// write to Dyanamo - {id: code, url: originalUrl }</span>

    <span class="hljs-comment">// return the url (https://{apiurl}.amazonaws.com/dev/get/{code})</span>
}
</code></pre><p>To get the <code>apiURL</code> we can pass it in as an environment variable. If you are using the Serverless Framework you can do this by adding this to the environment section of your config:</p>
<pre><code>apiUrl: {
  <span class="hljs-string">"Fn::Join"</span>: [
    <span class="hljs-string">""</span>,
    [
      <span class="hljs-string">"https://"</span>,
      { <span class="hljs-attr">Ref</span>: <span class="hljs-string">"HttpApi"</span> },
      <span class="hljs-string">".execute-api.${self:provider.region}.amazonaws.com"</span>,
    ],
  ],
},
</code></pre><pre><code><span class="hljs-comment">// Getting a URL by code</span>
<span class="hljs-keyword">const</span> handler = <span class="hljs-function">(<span class="hljs-params">event: APIGatewayProxyEvent</span>) =&gt;</span> {
    <span class="hljs-comment">// get code from the url path</span>

    <span class="hljs-comment">// get from dynamo by ID</span>

    <span class="hljs-comment">// return the original url</span>
}
</code></pre><p>You can take this one step further by changing the status code of the <code>getUrl</code> code to return a 301 - permanent redirect. You'll need to add some extra headers but this will automatically redirect the user to the desired page.</p>
<h1 id="heading-reminder-app-project">Reminder App Project</h1>
<p>This project will teach you about Secondary Indexes in Dynamo as well as Dynamo Time-To-Live. You will also get to try either email automation with Amazon Simple Email Service (SES) or text messaging with Simple Notification Service (SNS). </p>
<p>You could also build a simple front end app and learn about hosting it in S3 and using CloudFront to distribute it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/ch4-reminder-app.drawio.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The idea for this app is that you can post a new reminder to the first API endpoint. This will write a new record in DynamoDB, but you will have added a global secondary index (GSI) to the table. This means that you can get a reminder by id, or you can query based on the user. </p>
<p>It will also have a Time-To-Live (TTL) which will allow you to trigger a Lambda at the time of the reminder. The code for set reminders will looks pretty similar to the previous project.</p>
<p>The table will look something like this:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>id</td><td>userId</td><td>TTL</td><td>notificationType</td><td>message</td></tr>
</thead>
<tbody>
<tr>
<td>123</td><td>test@gmail.com</td><td>1648277828</td><td>email</td><td>Publish next youtube video</td></tr>
<tr>
<td>897</td><td>447113350882</td><td>1648842828</td><td>sms</td><td>Get More MILK</td></tr>
</tbody>
</table>
</div><p>The Time-To-Live (TTL) tells dynamo that once the time reaches this date, delete the record from Dynamo. </p>
<p>Two things to note with TTL:</p>
<ul>
<li>Make sure that this is the Unix timestamp for the deletion date – but in seconds. <code>new Date('october 20 2022').getTime()</code> will be in milliseconds, so just divide by 1000.</li>
<li>The record will be deleted within a 15-minute window after your TTL so don't panic if it's been 5 minutes and the record hasn't been deleted yet.</li>
</ul>
<p>You can then set up a second Lambda which is triggered any time a record is deleted from Dynamo. This then sends the message to either their email or phone.</p>
<pre><code><span class="hljs-comment">// Send reminder</span>
<span class="hljs-keyword">const</span> handler = <span class="hljs-keyword">async</span> (event: DynamoDBStreamEvent) =&gt; {
    <span class="hljs-comment">// get the list of deleted records</span>

    <span class="hljs-comment">// map over each record</span>
       <span class="hljs-comment">// Call SES or SNS to send the reminder</span>
}
</code></pre><p>The second API endpoint will be to get all of the reminders for a user. Make sure you've set up a GSI with a partition key of <code>userId</code> and a sort key of <code>TTL</code>.</p>
<pre><code><span class="hljs-comment">// Get My Reminders</span>
<span class="hljs-keyword">const</span> handler = <span class="hljs-function">(<span class="hljs-params">event: APIGatewayProxyEvent</span>) =&gt;</span> {
    <span class="hljs-comment">// get the userId from request</span>

    <span class="hljs-comment">// params = KeyConditionExpression: "'userId' = userId",</span>

    <span class="hljs-comment">// Query Dynamo</span>

    <span class="hljs-comment">// format the reminders </span>

    <span class="hljs-comment">// return to the user</span>
}
</code></pre><p>For the front end you can write a simple web app with two sections: create new reminder, and list my reminders. This can be in React, Vue, Angular, or even raw HTML, CSS, and JavaScript.</p>
<p>Once you have the app you can use <code>serverless-s3-sync</code> to automatically push the code into S3 (which you create in Serverless).</p>
<h1 id="heading-live-chat-app-project">Live Chat App Project</h1>
<p>This project will teach you how to build WebSockets. A user can either create a new 'room' or join an existing room. Any messages sent are sent to everyone connected to the room.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/ch5-live-chat.drawio.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>WebSockets work slightly differently than regular APIs. Instead of having multiple endpoints, you have one endpoint and different message types. </p>
<p>There are some default message types and some custom ones:</p>
<ul>
<li>connectToRoom – Custom</li>
<li>createRoom – Custom</li>
<li>onMessage – Custom</li>
<li>disconnect – Default</li>
</ul>
<p>When a user connects to the WebSocket, they can either send a <code>connectToRoom</code> or <code>createRoom</code> message. Both of these will create a record in Dynamo with the user's WebSocket <code>connectionId</code> and the <code>roomId</code>. As we did before, we'll have a GSI in Dynamo so we can later query to get all users for a <code>roomId</code>.</p>
<p>The code for <code>connectToRoom</code> and <code>createRoom</code> will look very similar to previous "writing data to Dynamo" lambdas. </p>
<p>You may want to check in <code>connectToRoom</code> that the room does exist first. You can do that by querying for all users by roomId. If there are no users in the room then that means they're trying to connect to a room that doesn't exist anymore.</p>
<p>Now a user is in a room they can send a message. Here's the pseudo-code for that Lambda:</p>
<pre><code><span class="hljs-comment">// onMessage</span>
<span class="hljs-keyword">const</span> handler = <span class="hljs-function">(<span class="hljs-params">event: WebsocketMessageEvent</span>) =&gt;</span> {
    <span class="hljs-comment">// get the user's connectionId</span>

    <span class="hljs-comment">// get the user by connectionId from Dynamo to get the roomId</span>

    <span class="hljs-comment">// query for all users in that roomId</span>

    <span class="hljs-comment">// send the message to all users</span>

    <span class="hljs-comment">// return</span>
}
</code></pre><p>Finally, there is the onDisconnect which will be a simple Lambda that just deletes the user's record from Dynamo.</p>
<h1 id="heading-idea-voting-app-project">Idea Voting App Project</h1>
<p>This project will teach you to design and build more advanced Dynamo tables and also work with Cognito for authentication. You should also build a simple front end for this to learn how to integrate Cognito into web apps.</p>
<p>The tool allows you to ask your community for ideas and find out which of those are most popular.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/ch6-idea-voting-app.drawio.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This starts with all users needing to sign up to your application. We use Cognito for this and do it so that we can ensure that each person can only vote once. </p>
<p>You'll need to then create a few endpoints:</p>
<ul>
<li>create a board</li>
<li>add an idea to a board</li>
<li>vote for an idea</li>
<li>get board details</li>
</ul>
<h3 id="heading-create-a-board">Create a board</h3>
<p>The first API endpoint that we need is one to create a new board for ideas. Anyone can create a board and the record in Dynamo is really simple. Just a <code>boardId</code> and then some info about the board owner, maybe a title and description.</p>
<table>
<thead>
<tr>
<th>boardId</th>
<th>owner</th>
<th>title</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>boardId</td>
<td>userId</td>
<td>My awesome idea</td>
<td>some description</td>
</tr>
</tbody>
</table>

<h3 id="heading-add-ideas-to-a-board">Add ideas to a board</h3>
<p>Next we need to be able to add ideas to a board. This will be another API endpoint and Lambda. With the idea database record we need to be a bit smarter as we need to be able to directly reference an idea, but also get all ideas for a board.</p>
<p>To do this we have a schema like this. <code>pk</code> is a partition key and <code>sk</code> is a sort key, which are both needed for querying on DynamoDB.</p>
<table>
<thead>
<tr>
<th>id</th>
<th>pk</th>
<th>sk</th>
<th>idea</th>
<th>owner</th>
</tr>
</thead>
<tbody>
<tr>
<td>id</td>
<td>boardId</td>
<td>ideaId</td>
<td>the idea</td>
<td>userId</td>
</tr>
</tbody>
</table>

<p>With the <code>id</code> we can directly reference the idea, but we can also query on the record. We can get all ideas for board <code>1234</code> by querying for <code>pk = 1234</code>.</p>
<h3 id="heading-add-vote-to-the-idea">Add vote to the idea</h3>
<p>Now that we have ideas on the board, we need our users to vote for them. This will be a new API endpoint and Lambda. This Lambda has a bit more work to do than the other two. First, we'll look at the schema for this record.</p>
<table>
<thead>
<tr>
<th>pk</th>
<th>sk</th>
<th>pk2</th>
<th>sk2</th>
</tr>
</thead>
<tbody>
<tr>
<td>ideaId</td>
<td>userId</td>
<td>userId</td>
<td>ideaId</td>
</tr>
</tbody>
</table>

<p>This may look strange at first but I'll explain why we want to structure it like this.</p>
<p>For a given idea, we want to know how many votes it has. We can find that out by querying on  <code>pk = ideaId</code> which will return all votes for the idea.</p>
<p>When adding a vote we want to check that the user hasn't already voted for the idea. We can do that by querying <code>pk = ideaId &amp;&amp; sk = userId</code>. If we find a record that matches, we know they've already voted for this idea. If not then we can add the <code>vote</code> record for this user and idea.</p>
<h3 id="heading-get-board-details">Get Board Details</h3>
<p>We can now write a lambda that will query the data we have:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> handler = <span class="hljs-keyword">async</span> (event: APIGatewayProxyEvent) =&gt; {
    <span class="hljs-comment">// get boardId from the request</span>
    <span class="hljs-comment">// query all ideas on the board</span>
    <span class="hljs-comment">// map over each idea</span>
        <span class="hljs-comment">// query for all votes on this idea</span>
    <span class="hljs-comment">// format it all into a nice format</span>
    <span class="hljs-comment">// return to the user</span>
}
</code></pre><h3 id="heading-get-votes-for-a-user">Get votes for a user</h3>
<p>Lastly, we want to be able to show all votes for a given user. We can't query where <code>sk = userId</code> as you always need a partition key when querying DynamoDB. Therefore we created a second partition key (<code>pk2</code>) which contains the userId. Now we can query <code>pk2 = userId</code> to get all ideas that a user has voted for.</p>
<p>This pattern of having a second GSI where the PK and SK are switched is very common. It allows you to have a many-to-many relationship. You can query for all of B that are connected to a specific A and all of A that are connected to a specific B. This is often called a junction table.</p>
<h2 id="heading-messaging-app-project">Messaging App Project</h2>
<p>This project will teach you to about Dynamo compound keys and give you more practice with websockets and Cognito.</p>
<p>This app allows users to sign up, request to join a room, and then see all messages that have been sent in that room. The owner of a room decides whether to let someone join the room.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/ch7-messaging-app-api.drawio.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The architecture will start by looking a lot like the live chat application – with a WebSocket connection with Lambdas for <code>onConnect, onDisconect, create</code>Group, <code>joinGroup, listMyGroups handleJoinGroupRequest</code> and <code>sendMessage</code>.</p>
<p>Before we get onto the Lambda code, we want to add Cognito to the application so we can have users signup. This will be used later when a user requests access to a group.</p>
<p>The <code>createGroup</code> Lambda will be almost identical to the live chat solution. It just creates a simple <code>group</code> record.</p>
<h3 id="heading-websocket-connect-disconnect">Websocket Connect / Disconnect</h3>
<p>Now when a user logs in and connects to the WebSocket, we can create an onConnection Lambda. This will get the userId and verify their Cognito user token. This token will easily give us the userId and userName. </p>
<p>If they don't pass a token or the token is invalid (or has expired) then we can kill the websocket, stopping them from doing anything else without a valid token.</p>
<p>If the token is valid then we can store a simple connection record. This will allow us to send messages back down the websocket later.</p>
<p>Just remember to delete this record when the user disconnects from the WebSocket. We can use the default <code>$disconnect</code> action to trigger an <code>onDisconnect</code> lambda.</p>
<h3 id="heading-create-a-group">Create a group</h3>
<p>The first thing that someone needs to be able to do is to create a group that they can then invite their friends to.</p>
<p>This will involve creating two records in Dynamo. The first is just a record of the group. This will include the group ID, group name, and who is the group owner.</p>
<p>The second is going to be a group membership record. This will be saying that this user is part of this group.</p>
<table>
<thead>
<tr>
<th>pk</th>
<th>sk</th>
<th>pk2</th>
<th>sk2</th>
<th>userName</th>
<th>groupName</th>
</tr>
</thead>
<tbody>
<tr>
<td>groupId</td>
<td>user#{userId}</td>
<td>userId</td>
<td>groupId</td>
<td>user name</td>
<td>group name</td>
</tr>
</tbody>
</table>

<p>This first part will allow us to query on <code>pk = groupId and sk startsWith('user')</code> to get all users for the group. That will be used in the <code>sendMessage</code> Lambda to get all the users to send the WebSocket message to.</p>
<p>The second parts (PK2, SK2) are added to allow us to get all groups that a user is authorised for by querying where <code>PK2 = userId</code>. This is used when we need to get a list of all of the user's groups.</p>
<h3 id="heading-joining-a-group">Joining a group</h3>
<p>The <code>join</code> Group request will now create a record in Dynamo for an <code>access request</code>. This will not give the user access to the group but will allow the owner of the group to review the access requests.</p>
<p>These records will be the first time that we're going to use compound keys. This is taking the sort key to the next level and the record will look like this:</p>
<table>
<thead>
<tr>
<th>pk</th>
<th>sk</th>
</tr>
</thead>
<tbody>
<tr>
<td>groupId</td>
<td>joinRequest#{userId}</td>
</tr>
</tbody>
</table>

<p>This enables us to query where <code>pk = groupId and sk startsWith('joinRequest')</code>. This will return all of the access requests for that group. When someone makes this request we can first check that they are the owner of the group.</p>
<p>The group owner then has two options – accept or reject. If the owner rejects the user we can just delete the access request record. If they accept the user then we need to add an <code>authorised user</code>. This will require a new record to Dynamo.</p>
<h3 id="heading-send-message">Send Message</h3>
<p>Now we're onto the core of the messaging app – sending and storing messages.</p>
<p>In the <code>sendMessage</code> WebSocket Lambda, we can query for all users in the group and send the message to all current connections. We also need to store the message in Dynamo.</p>
<table>
<thead>
<tr>
<th>pk</th>
<th>sk</th>
<th>message</th>
<th>user</th>
</tr>
</thead>
<tbody>
<tr>
<td>groupId</td>
<td>message#{timestamp}</td>
<td>my message</td>
<td>userId</td>
</tr>
</tbody>
</table>

<h3 id="heading-get-previous-messages">Get Previous Messages</h3>
<p>When a user logs in they need to be able to get the messages they missed whilst offline. With the message data structured this way, we can query where:</p>
<p><code>pk = groupId and sk &gt; 'message#{ timestamp for yesterday }'</code></p>
<p>This will return all messages created since yesterday.</p>
<p>We could also allow them to get older messages by passing up the last message they have. This will allow us to get the next chuck of messages. This will allow us to create an infinite up scroll on the message history.</p>
<h2 id="heading-event-driven-e-commerce-system-project">Event Driven E-Commerce System Project</h2>
<p>This project will teach you about Event Bridge, plus give you some extra practice with DynamoDB Table design and services like SES and SNS for email and text.</p>
<p>This system will have products and filtering, carts and orders as you would expect. The key here is that order placement, order status changes, and delivery updates will all be handled through Event Bridge.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/ch8-event-ecomerce.drawio.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-storing-products">Storing Products</h3>
<p>To start we need to store products. We can structure our sort keys in a way to allow a level of hierarchy for our products.</p>
<table>
<thead>
<tr>
<th>id</th>
<th>pk</th>
<th>sk</th>
<th>title</th>
<th>description</th>
<th>...</th>
</tr>
</thead>
<tbody>
<tr>
<td>productId</td>
<td>clothing</td>
<td>mens#tops#{productId}</td>
<td>Next Slimfit T-Shirt</td>
<td>...</td>
<td>...</td>
</tr>
<tr>
<td>productId</td>
<td>clothing</td>
<td>womens#trousers#{productId}</td>
<td>Levi's Jeans</td>
<td>...</td>
<td>...</td>
</tr>
</tbody>
</table>

<p>This allows us to query for <code>pk = clothing and sk beginsWith mens</code> to get all men's clothes or for <code>pk = clothing and sk beginsWith womens#trousers</code> to get all women's trousers.</p>
<h3 id="heading-placing-an-order">Placing an Order</h3>
<p>The next part is being able to place an order. We're not going to try and take payment, just add an order record to the dynamoDB table.</p>
<h3 id="heading-event-bridge">Event Bridge</h3>
<p>The big difference here is that we're going to start using Event Bridge. This is a tool which allows us to have events which can trigger multiple lambdas. This is great as we can add a new listener without having to change the upfront code.</p>
<h3 id="heading-order-created">Order Created</h3>
<p>We're going to have two lambdas that listen for the <code>orderCreated</code> event. The first is going to take the order data and send it to a warehouse API to get packed. The second is going to send the user an order confirmation email</p>
<h3 id="heading-order-packed">Order Packed</h3>
<p>We're going to pretend that there is a real warehouse and after getting the order packing list, they packed up and got the order ready for shipping. They have a system that calls our API and changes the order status to <code>packed</code>.</p>
<p>This change in the Dynamo record will trigger another Event Bridge event for <code>orderPacked</code>. This also has two listeners: one to email an update to the user, and another to email a delivery service to collect the parcel from the warehouse and deliver it to the customer.</p>
<h3 id="heading-order-shipped">Order Shipped</h3>
<p>Similarly we're going to pretend that a delivery company took the parcel and delivered it. They call another <code>Order Shipped</code> API endpoint and that changes the status of the order in the database again.</p>
<p>That triggers another event for <code>orderDelivered</code> and that has two listeners:</p>
<p>One for sending a "thank you" message to the customer.</p>
<p>And another one that will do something a bit different. It will take the order, remove any personal data, and store it into another DynamoDB table. </p>
<p>This is something becoming increasingly common as a preparation step for a data scientist. We remove the personal data to reduce the legal issues but still allow a data scientist to do things like train a model to give you "People also bought ...." kinds of recommendations.</p>
<h2 id="heading-whats-next">What's Next</h2>
<p>If you like these project ideas but don't know where to start, then I have a full video course that will teach you how to build all of these projects.</p>
<p><a target="_blank" href="https://completecoding.mykajabi.com/7-serverless-projects">Check out the course here</a>.</p>
<p>You can also download a <a target="_blank" href="https://completecoding.mykajabi.com/7-practical-project-pdf">Free PDF</a> of these projects so you can visualise your progress in your learning journey.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Speed Up Your Lambda Functions ]]>
                </title>
                <description>
                    <![CDATA[ By Ali Haydar Lambda has gained massive popularity over the past few years. It has various use cases, from running simple scripts to gluing flows and processes within a serverless architecture or when running microservices.  Still, if you've just sta... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-speed-up-lambda-functions/</link>
                <guid isPermaLink="false">66d45d99787a2a3b05af4378</guid>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ performance ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 25 Apr 2022 19:43:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/04/pexels-zhang-kaiyv-842654.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ali Haydar</p>
<p>Lambda has gained massive popularity over the past few years. It has various use cases, from running simple scripts to gluing flows and processes within a serverless architecture or when running microservices. </p>
<p>Still, if you've just started working in a new environment or organisation, you might feel cautious about using it because it's complex to configure. </p>
<p>This is fair with any new technology you're getting ready to start using, and being careful is a sign of good business sense. </p>
<p>An argument you might often hear is that lambda might slow down your operation because of cold starts.</p>
<p>This is also a common topic in technical interviews, so it's worth digging a bit deeper if you're keeping an eye on that next dream cloud engineering position.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><img src="https://www.freecodecamp.org/news/content/images/2022/04/cold-start-image.jpeg" alt="cold-start-image" width="600" height="400" loading="lazy"></td></tr>
</thead>
<tbody>
<tr>
<td>Photo by <a target="_blank" href="https://pixabay.com/users/myriams-fotos-1627417/">Myriams-Fotos</a> on <a target="_blank" href="https://pixabay.com/photos/dawn-winter-snow-nature-frost-3142990/">pixabay</a></td></tr>
</tbody>
</table>
</div><p>In this article, we'll talk about one way that can help enhance the performance of your Lambda functions. </p>
<p>But let's start first with an overview of what happens when you execute a Lambda function, touching on cold starts.</p>
<h2 id="heading-how-is-a-lambda-function-executed">How is a Lambda Function Executed?</h2>
<p>When your Lambda function is triggered, the Lambda service runs the code in an "Execution Environment" with three phases: <code>Init</code>, <code>Invoke</code> and <code>Shutdown</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/execution-environment-1.png" alt="execution-environment-1" width="600" height="400" loading="lazy"></p>
<ul>
<li>In the <code>Init</code> phase, Lambda creates the execution environment, downloads the code, sets up the configuration (for example, memory), and runs the <em>code</em> that lives outside of the <code>handler</code> function. (You might already have the gist of the article at this point – but read on for further explanation and a demo.)</li>
<li>In the <code>Invoke</code> phase, Lambda runs the code inside the <code>handler</code> function</li>
<li>In the <code>Shutdown</code> phase, Lambda terminates the environment</li>
</ul>
<p>There could be multiple <code>Invocations</code> between an <code>Init</code> phase and a <code>Shutdown</code> phase if the Lambda got triggered a bunch of times in a row in a fairly short period of time (this time is not precisely determined in the Lambda docs). </p>
<p>This means that if multiple consecutive executions of the Lambda happened in a short timeframe, the Lambda service would leverage the first created execution environment to run the following invokation. That is, it would only call the handler function with every new call to the Lambda without having to create a new execution environment and without having to run the code that's outside the handler function.</p>
<p>The <code>Init</code> phase happens only once upon the first execution, and we can visualise it as two parts (both of them run once per execution):</p>
<ul>
<li>The part where a new execution environment is created and the code is downloaded is the <em>cold start</em>.</li>
<li>The part where the code outside the Lambda handler is run is the initialisation code.</li>
</ul>
<p>From the <a target="_blank" href="https://docs.aws.amazon.com/lambda/latest/dg/runtimes-context.html">AWS docs</a>, this picture provides a proper visualisation of the 3 phases:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/execution-environment-phases.png" alt="execution-environment-phases" width="600" height="400" loading="lazy"></p>
<p>The Function INIT (the last block of the INIT phase) will run only once, along with the first two blocks that form the cold start.</p>
<p>Ok enough talk – show us the code!</p>
<h2 id="heading-lambda-function-code">Lambda Function Code</h2>
<p>In the previous section, we discussed that Lambda would run the initialisation code (code outside the handler function) once upon first execution. And it would run the code inside the handler using the same execution environment if the following invocations did not happen too far from each other. </p>
<p>That's a perfect way to leverage the initialisation code to run the reusable code and save time re-running this code every time with every invocation.</p>
<p>Assume we have a Lambda function that's interacting with a DynamoDB to retrieve a set of items (please keep in mind that this code is for demo purposes only, so it's not the cleanest you'll see).</p>
<p>Create an <code>index.js</code> file:</p>
<pre><code><span class="hljs-keyword">const</span> { DynamoDB } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"@aws-sdk/client-dynamodb"</span>);

<span class="hljs-built_in">exports</span>.handler = <span class="hljs-keyword">async</span> (event, context) =&gt; {
  <span class="hljs-keyword">const</span> dynamodb = <span class="hljs-keyword">new</span> DynamoDB({ <span class="hljs-attr">region</span>: <span class="hljs-string">"ap-southeast-2"</span> }); <span class="hljs-comment">// creating a new instance of DynamoDB</span>
  <span class="hljs-keyword">const</span> params = {
    <span class="hljs-attr">TableName</span>: <span class="hljs-string">"company"</span>,
  };

  <span class="hljs-keyword">const</span> results = <span class="hljs-keyword">await</span> dynamodb.scan(params); <span class="hljs-comment">// avoid using scan in production - it's expensive and not performant</span>

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify(results),
  };
};
</code></pre><p>In the previous snippet, the initialisation code is the following:</p>
<pre><code><span class="hljs-keyword">const</span> { DynamoDB } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'@aws-sdk/client-dynamodb'</span>);
</code></pre><p>It will run once upon first execution and won't run in the following executions if they happen in a short time – that is, the subsequent executions happened before the Shutdown phase was reached.</p>
<h2 id="heading-lambda-demo">Lambda Demo</h2>
<p>Awesome, now we're ready for the demo. In this section, we will build the infrastructure and test the performance of the Lambda.</p>
<h3 id="heading-build-the-infrastructure">Build the Infrastructure</h3>
<p>As this tutorial aims to demonstrate how to enhance the performance of our Lambda, we won't be putting much focus on the infrastructure as code.</p>
<p>Follow these steps to build and deploy your app:</p>
<ul>
<li>Install the dependencies: <code>npm install</code></li>
<li>Zip your Lambda File: <code>zip -r ./get-companies-lambda.zip index.js node_modules</code></li>
<li>Download the following Terraform file: https://gist.github.com/AHaydar/bfc173db2078b2eeb884da8632248c5d</li>
<li>Apply the Terraform changes: <code>terraform apply</code></li>
</ul>
<p>Open the AWS console and validate that both DynamoDB and Lambda got created correctly (I am using the <code>ap-southeast-2</code> region in this example).</p>
<h3 id="heading-test-the-performance">Test the performance</h3>
<p>First, navigate to your Lambda function in the AWS console and click the <code>Test</code> button to run your code. You will get a result similar to the following: <img src="https://www.freecodecamp.org/news/content/images/2022/04/init-duration.png" alt="init-duration" width="600" height="400" loading="lazy"></p>
<p>Notice the following in the last line:</p>
<p><code>Duration: 569.85 ms</code></p>
<p>and</p>
<p><code>Init Duration: 429.13 ms</code></p>
<p>The <code>Init Duration</code> is the duration to run the code outside the Lambda handler – that's the code requiring the DynamoDB SDK.</p>
<p>The <code>Duration</code> is the duration of running the code inside your Lambda handler – instantiating DynamoDB passing the "ap-southeast-2" region and scanning the table.</p>
<p>Click the <code>Test</code> button again. You should get a response like this: <img src="https://www.freecodecamp.org/news/content/images/2022/04/second-execution.png" alt="second-execution" width="600" height="400" loading="lazy"></p>
<p>Notice the last line – it does NOT contain an <code>Init Duration</code>. If your result included an Init Duration, it means the execution environment was shutdown before you clicked the <code>Test</code> button again. In this case, click it another time.</p>
<p>So in the second execution, we saved the <code>Init Duration</code>. It's a hint to optimise our function and add more common code outside the Lambda handler. How can we do that?</p>
<pre><code><span class="hljs-keyword">const</span> { DynamoDB } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"@aws-sdk/client-dynamodb"</span>);

<span class="hljs-keyword">const</span> dynamodb = <span class="hljs-keyword">new</span> DynamoDB({ <span class="hljs-attr">region</span>: <span class="hljs-string">"ap-southeast-2"</span> }); <span class="hljs-comment">// creating a new instance of DynamoDB</span>
<span class="hljs-keyword">const</span> params = {
  <span class="hljs-attr">TableName</span>: <span class="hljs-string">"company"</span>,
};

<span class="hljs-built_in">exports</span>.handler = <span class="hljs-keyword">async</span> (event, context) =&gt; {
  <span class="hljs-keyword">const</span> results = <span class="hljs-keyword">await</span> dynamodb.scan(params); <span class="hljs-comment">// avoid using scan in production - it's expensive and not performant</span>

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify(results),
  };
};
</code></pre><p>In the above snippet, I moved the instantiation of DynamoDB outside of the handler, along with the params object. </p>
<p>So this would increase the execution time of the Init Code (outside the lambda handler), which runs only during the first execution of the Execution environment lifecycle. And it would decrease the execution time of the Lambda Handler, which happens upon every invocation.</p>
<p>Keep in mind that you should never write business logic that relies on having a running execution environment. Your code should always assume it needs to init the execution environment upon every invocation.</p>
<p>What other tips do you have on optimising your Lambda performance? Share them with me on <a target="_blank" href="https://twitter.com/Alee_Haydar">Twitter</a> or <a target="_blank" href="https://www.linkedin.com/in/ahaydar/">LinkedIn</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ AWS Serverless – How to Use AWS Rekognition to Identify Celebrities in Images ]]>
                </title>
                <description>
                    <![CDATA[ By Shivang In this article we're going to learn how to make an application using AWS Serverless that lets us identify images of celebrities. We'll use AWS Rekognition for AI-based identification. We are going to attach an event to the S3 Bucket so th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/use-aws-rekognition-to-identify-celebrities-in-images/</link>
                <guid isPermaLink="false">66d460f09208fb118cc6d017</guid>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ serverless ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 13 Jan 2022 16:47:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/fe.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Shivang</p>
<p>In this article we're going to learn how to make an application using AWS Serverless that lets us identify images of celebrities. We'll use AWS Rekognition for AI-based identification.</p>
<p>We are going to attach an event to the S3 Bucket so that whenever a file gets uploaded to the bucket, it'll invoke a Lambda function that will process the information from the image and save it to the DynamoDB table. </p>
<p>Before you use DynamoDB, just make sure that you check out this guide on <a target="_blank" href="https://devswisdom.com/aws-dynamodb-pricing-and-features/">AWS DynamoDB Pricing</a> so you only spend what you want to spend.</p>
<h2 id="heading-tech-spec"><strong>Tech Spec</strong></h2>
<p>We are going to use Lambda functions to code our project logic and AWS Rekognition for AI-based image identification of the celebrity. </p>
<p>If we get valid data from the AWS Rekognition API then we are going to store that data in a DynamoDB Table.</p>
<p>All these resources except from the S3 bucket will be created inside the <em>serverless.yml</em> file.</p>
<h2 id="heading-project-setup"><strong>Project Setup</strong></h2>
<p>We are going set up all the things we need in this project step by step. First we'll go through the <em>serverless.yml</em> file. To learn more about this file, check out <a target="_blank" href="https://devswisdom.com/use-websockets-with-aws-serverless/">this</a> post. Let’s get started with the first step.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/pt-1.PNG" alt="Project structure" width="600" height="400" loading="lazy"></p>
<p>Our project folder structure should look like this at the end of this tutorial.</p>
<h3 id="heading-how-to-set-up-the-serverlessyml-file"><strong>How to set </strong>up the serverless.yml file<em>**</em></h3>
<p>We will break down the <em>serverless.yml</em> file into different parts to make it easier to understand.</p>
<h4 id="heading-how-to-set-permissions-and-configure-the-project"><strong>How to set </strong>permissions and<strong> configure the </strong>project<em>**</em></h4>
<pre><code class="lang-yaml"><span class="hljs-attr">service:</span> <span class="hljs-string">meta-data-serverless</span>

<span class="hljs-attr">provider:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">aws</span>
  <span class="hljs-attr">runtime:</span> <span class="hljs-string">nodejs12.x</span>
  <span class="hljs-attr">environment:</span>
    <span class="hljs-attr">DYNAMO_TABLE_NAME:</span> <span class="hljs-string">MetaData</span>
    <span class="hljs-attr">BUCKET_NAME:</span> <span class="hljs-string">new-bucket-caps2</span>
  <span class="hljs-attr">iamRoleStatements:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">Effect:</span> <span class="hljs-string">Allow</span>
      <span class="hljs-attr">Action:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">dynamodb:PutItem</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">rekognition:RecognizeCelebrities</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">s3:Get*</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">s3:List*</span>
      <span class="hljs-attr">Resource:</span> <span class="hljs-string">"*"</span>
</code></pre>
<p>In this code block, we are setting different environment variables and AWS IAM permissions which will be given to our lambda functions. So for our use, we need to write an item to the DynamoDB table, use AWS Rekognition's API to do image identification on the image, and get the file from S3 (all of which we've done in the above code). </p>
<p>Note that you will need to create a new public S3 bucket and set the name of that bucket here in place of <em>“new-bucket-caps2</em>” as the BUCKET_NAME property. To read more about IAM roles check out the official <a target="_blank" href="https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html">AWS documentation</a>.</p>
<h4 id="heading-how-to-add-a-lambda-function"><strong>How to add a </strong>lambda function<em>**</em></h4>
<pre><code class="lang-yaml"><span class="hljs-attr">functions:</span>
  <span class="hljs-attr">processImg:</span>
    <span class="hljs-attr">handler:</span> <span class="hljs-string">src/index.handler</span>
    <span class="hljs-attr">events:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">s3:</span>
          <span class="hljs-attr">bucket:</span> <span class="hljs-string">${self:provider.environment.BUCKET_NAME}</span>
          <span class="hljs-attr">event:</span> <span class="hljs-string">s3:ObjectCreated:*</span>
          <span class="hljs-attr">existing:</span> <span class="hljs-literal">true</span>
</code></pre>
<p>In the functions block, we are defining a single lambda function which will be invoked when any file is uploaded to the S3 bucket.</p>
<p>As you can see, we are attaching an event to this lambda function on which it will be invoked. <code>s3:ObjectCreated</code> is the event when any file gets uploaded into the S3 bucket.</p>
<p>We are also declaring that this bucket already exists by setting the <code>existing</code> option to <code>true</code>. So make sure that you create this bucket before you deploy the project. </p>
<p>We are also referencing the environment variable for the bucket name which we created in the above section.</p>
<h4 id="heading-how-to-add-dynamodb-table-configuration"><strong>How to add </strong>DynamoDB table configuration<em>**</em></h4>
<pre><code class="lang-javascript">resources:
  Resources:
    UsersDynamoDbTable:
      Type: AWS::DynamoDB::Table
      <span class="hljs-attr">DeletionPolicy</span>: Retain
      <span class="hljs-attr">Properties</span>:
        AttributeDefinitions:
          - AttributeName: id
            <span class="hljs-attr">AttributeType</span>: S
        <span class="hljs-attr">KeySchema</span>:
          - AttributeName: id
            <span class="hljs-attr">KeyType</span>: HASH
        <span class="hljs-attr">ProvisionedThroughput</span>:
          ReadCapacityUnits: <span class="hljs-number">1</span>
          <span class="hljs-attr">WriteCapacityUnits</span>: <span class="hljs-number">1</span>
        <span class="hljs-attr">TableName</span>: ${<span class="hljs-attr">self</span>:provider.environment.DYNAMO_TABLE_NAME}
</code></pre>
<p>In this block, we are defining our DynamoDB table and its configuration. Any resource we want to create on our AWS account is defined under the resources block in the <em>serverless.yml</em> file. Here we are defining things like table attributes, key schema, and how much provisioned throughput capacity we want to give our table.</p>
<p>For the table attributes, all other attributes will be dynamically added to the table except the id. We will generate the id in the code using a module called UUID.</p>
<h3 id="heading-how-to-set-up-the-lambda-function"><strong>How to set </strong>up the lambda function<em>**</em></h3>
<p>After creating the <em>serverless.yml</em> file, it is now time to create our lambda function which we defined inside the yml file. So let’s get started on this. </p>
<p>We will again see different parts of the lambda function so you can understand it better.</p>
<h4 id="heading-imports">Imports</h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> AWS = <span class="hljs-built_in">require</span>(<span class="hljs-string">"aws-sdk"</span>);
<span class="hljs-keyword">const</span> {
    <span class="hljs-attr">v4</span>: uuidv4
} = <span class="hljs-built_in">require</span>(<span class="hljs-string">'uuid'</span>);
<span class="hljs-keyword">const</span> rekognition = <span class="hljs-keyword">new</span> AWS.Rekognition();
<span class="hljs-keyword">const</span> dynamoDb = <span class="hljs-keyword">new</span> AWS.DynamoDB.DocumentClient();
</code></pre>
<p>We are importing two packages, aws-sdk and UUID, to call the APIs for DynamoDB and AWS Rekognition. We are also initializing instances of them.</p>
<h4 id="heading-define-the-parameters"><strong>Defin</strong>e the <strong>parameters</strong></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Bucket = event.Records[<span class="hljs-number">0</span>].s3.bucket.name;
<span class="hljs-keyword">const</span> Name = <span class="hljs-built_in">decodeURIComponent</span>(event.Records[<span class="hljs-number">0</span>].s3.object.key.replace(<span class="hljs-regexp">/\+/g</span>, <span class="hljs-string">" "</span>));

<span class="hljs-keyword">const</span> params = {
    <span class="hljs-attr">Image</span>: {
        <span class="hljs-attr">S3Object</span>: {
            Bucket,
            Name
        }
    }
};
</code></pre>
<p>When our lambda gets called by an S3 event, it receives data about the object which was uploaded to the S3 bucket. Were we are just getting that object data like the name of the Bucket it was uploaded to and the name of the file as well.</p>
<p>After that we are passing this data into the parameter object we will be passing to the AWS Rekognition API call.</p>
<h4 id="heading-call-the-aws-rekognition-api"><strong>Call the AWS Rekognition API</strong></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> celebrityData = <span class="hljs-keyword">await</span> rekognition.recognizeCelebrities(params).promise();
<span class="hljs-keyword">if</span> (celebrityData.CelebrityFaces &amp;&amp; celebrityData.CelebrityFaces.length) {

    <span class="hljs-keyword">const</span> {
        Name,
        Urls,
        KnownGender,
        Face
    } = celebrityData.CelebrityFaces[<span class="hljs-number">0</span>];
    <span class="hljs-keyword">const</span> closelyMatchedEmotion = Face.Emotions.reduce(<span class="hljs-function">(<span class="hljs-params">prev, current</span>) =&gt;</span> (prev.Confidence &gt; current.Confidence) ? prev : current)

    <span class="hljs-keyword">const</span> params = {
        <span class="hljs-attr">TableName</span>: process.env.DYNAMO_TABLE_NAME,
        <span class="hljs-attr">Item</span>: {
            <span class="hljs-attr">id</span>: uuidv4(),
            Name,
            <span class="hljs-attr">readMore</span>: Urls,
            KnownGender,
            closelyMatchedEmotion
        },
        <span class="hljs-attr">ConditionExpression</span>: <span class="hljs-string">"attribute_not_exists(id)"</span>
    };
    <span class="hljs-keyword">await</span> dynamoDb.put(params).promise();
</code></pre>
<p>Finally, we are calling the AWS Rekognition API with the parameters we declared in the previous step. After we get the response from the API, we check to see if it was able to identify the celebrity or not. </p>
<p>If it found celebrity data, then we are fetching data like Name, Gender, Emotion in the image, and so on from the identified celebrity data.</p>
<p>Then we generate an id using the UUID package we imported earlier. The last thing we're doing is inserting this data into the DynamoDB table. </p>
<p>Note that to query this saved data with non-key attributes you will need to create an index if you don’t wish to scan the whole table. Check out this post to learn how to create a <a target="_blank" href="https://devswisdom.com/dynamodb-global-secondary-index-detailed-guide/">DynamoDB Global Secondary Index</a> using AWS Serverless.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>If you reached this point, then congratulations! You now have an application that will identify celebrity data from an image. </p>
<p>You can now just go to your created S3 bucket and upload any celebrity image and then wait for a couple of seconds, then check the DynamoDB table to see the results saved there.</p>
<p>You can enhance this application in many ways. For example you can add APIs like GET to get the data and see the data which got added to the DynamoDB table. You can also use MongoDB in place of DynamoDB. To learn more about the differences between these two check out <a target="_blank" href="https://devswisdom.com/dynamodb-vs-mongodb-detailed-comparison/">DynamoDB Vs MongoDB</a>.</p>
<h2 id="heading-get-the-source-code"><strong>Get the source code</strong></h2>
<p>Click <a target="_blank" href="https://github.com/shivangchauhan7/celebrity-recoknition">here</a> to get the source code for this application.</p>
<p><em>You can <a target="_blank" href="https://devswisdom.com/">check out more articles like this</a> on my site.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Serverless Architecture? What are its Pros and Cons? ]]>
                </title>
                <description>
                    <![CDATA[ By Faizan Bashir Serverless, the new buzzword in town has been gaining a lot of attention from the pros and the rookies in the tech industry. Partly due to the manner in which cloud vendors like AWS have hyped the architecture, from conferences to m... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-serverless-architecture-what-are-its-pros-and-cons/</link>
                <guid isPermaLink="false">66d45ef7bc9760a197a103c3</guid>
                
                    <category>
                        <![CDATA[ architecture ]]>
                    </category>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ serverless ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 05 Jul 2019 18:43:27 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/07/1_16x1_xEclXT4MB0FN_xr2g.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Faizan Bashir</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*16x1_xEclXT4MB0FN_xr2g.jpeg" alt="Image" width="1920" height="1080" loading="lazy"></p>
<p>Serverless, the new buzzword in town has been gaining a lot of attention from the pros and the rookies in the tech industry. Partly due to the manner in which cloud vendors like AWS have hyped the architecture, from conferences to meetups to blog posts to almost everywhere. But serverless is not just about the hype, it promises the possibility of ideal business implementations which sounds quite pleasant to the ears and probably light on the budget as well.</p>
<blockquote>
<p><em>“Focus on your</em> <strong><em>application</em></strong>, not the <strong>infrastructure</strong>”</p>
</blockquote>
<p>Sounds relieving though, knowing a lot of your daylight hours go into implementing, maintaining, debugging, and monitoring the infrastructure. With all of that infrastructure heavy lifting out of the way, we really can focus on the business goals our applications serve. A lot of productive efforts could be channeled in the right direction, where they were meant to be ideally. Maybe it sounds too good to be true, but this is the way things should have been. At least for those of you who cant afford to spend a lot of time caught up in the web of intricacies in modern complex infrastructure.</p>
<p>Expectations apart, Serverless is really breaking ground in its path to disrupt your server infrastructure. Serverless is already used in production by companies like Netflix, Reuters, AOL, and Telenor. Industry-wide adoption is constantly increasing. Serverless is all set to take up its own place, but don’t expect Serverless to conquer your infrastructure completely. There will be use cases where serverless might prove to be the wrong choice.</p>
<hr>
<h3 id="heading-so-what-is-serverless">So, What is Serverless?</h3>
<p>Serverless is a cloud computing execution model where the cloud provider dynamically manages the allocation and provisioning of servers. A serverless application runs in stateless compute containers that are event-triggered, ephemeral (may last for one invocation), and fully managed by the cloud provider. Pricing is based on the number of executions rather than pre-purchased compute capacity, isn’t it the ideal framework for that project you have been planning since a long time? Well, go ahead do it.</p>
<blockquote>
<p><em>Serverless applications are event-driven cloud-based systems where application development rely solely on a combination of</em> <strong><em>third-party services, client-side logic</em></strong> and cloud-hosted remote procedure calls <strong>(Functions as a Service)</strong>.</p>
</blockquote>
<p>Most of the cloud providers have invested heavily in serverless and thats a lot of money; with the given massive promotion and realistic offering you can safely assume serverless to be one of the most used cloud services in upcoming years. Here are some of the currently available cloud services:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*t4O4UXpdG68MQboNKC6bBw.jpeg" alt="Image" width="638" height="359" loading="lazy"></p>
<p><em>Source:</em> <a target="_blank" href="https://www.slideshare.net/loige/building-a-serverless-company-with-nodejs-react-and-the-serverless-framework-jsday-2017-verona"><em>https://www.slideshare.net/loige/building-a-serverless-company-with-nodejs-react-and-the-serverless-framework-jsday-2017-verona</em></a></p>
<ul>
<li><p><a target="_blank" href="https://aws.amazon.com/lambda/"><strong>AWS Lambda</strong></a></p>
</li>
<li><p><a target="_blank" href="https://cloud.google.com/functions/"><strong>Google Cloud Functions</strong></a></p>
</li>
<li><p><a target="_blank" href="https://azure.microsoft.com/en-us/services/functions/"><strong>Azure Functions</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.ibm.com/cloud-computing/bluemix/openwhisk"><strong>IBM OpenWhisk</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.alibabacloud.com/product/function-compute"><strong>Alibaba Function Compute</strong></a></p>
</li>
<li><p><a target="_blank" href="http://open.iron.io/"><strong>Iron Functions</strong></a></p>
</li>
<li><p><a target="_blank" href="https://webtask.io/"><strong>Auth0 Webtask</strong></a></p>
</li>
<li><p><a target="_blank" href="https://fnproject.io/"><strong>Oracle Fn Project</strong></a></p>
</li>
<li><p><a target="_blank" href="https://kubeless.io/"><strong>Kubeless</strong></a></p>
</li>
</ul>
<hr>
<h3 id="heading-traditional-vs-serverless-architecture">Traditional vs. Serverless Architecture</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*x_v5NRC3TTMt1MaYl1gMUg.jpeg" alt="Image" width="1024" height="768" loading="lazy"></p>
<p><em>Source:</em> <a target="_blank" href="https://www.gocd.org/2017/06/26/serverless-architecture-continuous-delivery/"><em>https://www.gocd.org/2017/06/26/serverless-architecture-continuous-delivery/</em></a></p>
<p>For years your applications have run on servers which you had to patch, update, and continuously look after late nights and early mornings due to all the unimaginable errors that broke your production. As long as you managed them, the whole responsibility of their proper functioning was on you. Serverless tends to be unlike the aforementioned, you no longer need to worry about the underlying servers. Reason being, they are not managed by you anymore and with management out of the picture the responsibility falls on the Cloud vendors. But regardless the cool features of Serverless in some cases, the traditional architecture outshines it.</p>
<h4 id="heading-pricing">Pricing</h4>
<p>One of the major advantages of using Serverless is reduced cost, for years the cost of provisioning servers and maintaining that 24x7 server team which blew a hole in your pocket is gone. The cost model of Serverless is execution-based: you’re charged for the number of executions. You’re allotted a certain number of seconds of use that varies with the amount of memory you require. Likewise, the price per MS (millisecond) varies with the amount of memory you require. Obviously, shorter running functions are more adaptable to this model with a peak execution time of 300-second to 15-minutes for most Cloud vendors.</p>
<p><em>The winner here is Serverless Architecture.</em></p>
<h4 id="heading-networking">Networking</h4>
<p>The downside is that Serverless functions are accessed only as private APIs. To access these you must set up an API Gateway. This doesn’t have an impact on your pricing or process, but it means you cannot directly access them through the usual IP, snap!</p>
<p><em>The winner here is Traditional Architecture.</em></p>
<h4 id="heading-3rd-party-dependencies">3rd Party Dependencies</h4>
<p>Most, if not all of your projects have external dependencies, they rely on libraries that are not built into the language or framework you use. You often use libraries with functionality that includes cryptography, image processing, etc., these libraries can be pretty heavy. Without system-level access, you must package these dependencies into the application itself.</p>
<blockquote>
<p><em>Reinventing the wheel isn’t always a good idea.</em></p>
</blockquote>
<p><em>The winner here is based on the context. For simple applications with few dependencies, Serverless is the winner; for anything more complex, Traditional Architecture is the winner.</em></p>
<h4 id="heading-environments">Environments</h4>
<p>Setting up different environments for Serverless is as easy as setting up a single environment. Given that it’s pay per execution, this is a large improvement over traditional servers, you no longer need to set up dev, staging, and production machines. Eventually you’d lose count of all the environments, at some point.</p>
<p><em>The winner here is Serverless Architecture.</em></p>
<h4 id="heading-timeout">Timeout</h4>
<p>With Serverless computing, there’s a <a target="_blank" href="https://aws.amazon.com/about-aws/whats-new/2018/10/aws-lambda-supports-functions-that-can-run-up-to-15-minutes/">hard 15-minute timeout limit for AWS Lambda</a>. Too complex or long-running functions aren’t good for Serverless, but having a hard timeout makes it impossible to perform certain tasks. A hard limit on this time makes Serverless unusable for applications that have variable execution times, and for certain services which require information from an external source. This is likely to change in the future.</p>
<p><em>The clear winner here is Traditional Architecture.</em></p>
<h4 id="heading-scale">Scale</h4>
<p>Scaling process for Serverless is automatic and seamless, but there is a lack of control or entire absence of control. While automatic scaling is great, it’s difficult not to be able to address and mitigate errors related to new Serverless instances.</p>
<p><em>It’s a tie between Serverless and Traditional Architecture.</em></p>
<hr>
<h3 id="heading-functions-as-a-service-faas">Functions as a Service (FaaS)</h3>
<p>FaaS is an implementation of Serverless architectures where engineers can deploy an individual function or a piece of business logic. They start within milliseconds (~100ms for AWS Lambda) and process individual requests within a 300-second to 15-minute timeout imposed by most cloud vendors.</p>
<h4 id="heading-principles-of-faas"><strong>Principles of FaaS:</strong></h4>
<ul>
<li><p>Complete management of servers</p>
</li>
<li><p>Invocation based billing</p>
</li>
<li><p>Event-driven and instantaneously scalable</p>
</li>
</ul>
<h3 id="heading-key-properties-of-faas">Key properties of FaaS:</h3>
<h4 id="heading-independent-server-side-logical-functions">Independent, server-side, logical functions</h4>
<p>FaaS are similar to the functions you’re used to writing in programming languages, small, separate, units of logic that take input arguments, operate on the input and return the result.</p>
<h4 id="heading-stateless">Stateless</h4>
<p>With Serverless, everything is stateless, you can’t save a file to disk on one execution of your function and expect it to be there at the next. Any two invocations of the same function could run on completely different containers under the hood.</p>
<h4 id="heading-ephemeral">Ephemeral</h4>
<p>FaaS are designed to spin up quickly, do their work and then shut down again. They do not linger unused. As long as the task is performed the underlying containers are scrapped.</p>
<h4 id="heading-event-triggered">Event-triggered</h4>
<p>Although functions can be invoked directly, yet they are usually triggered by events from other cloud services such as HTTP requests, new database entries or inbound message notifications. FaaS are often used and thought of as the glue between services in a cloud environment.</p>
<h4 id="heading-scalable-by-default">Scalable by default</h4>
<p>With stateless functions multiple containers can be initialised, allowing as many functions to be run (in parallel, if necessary) as needed to continually service all incoming requests.</p>
<h4 id="heading-fully-managed-by-a-cloud-vendor">Fully managed by a Cloud vendor</h4>
<p>AWS Lambda, Azure Functions, IBM OpenWhisk and Google Cloud Functions are most well-known FaaS solutions available. Each offering typically supports a range of languages and runtimes e.g. Node.js, Python, .NET Core, Java.</p>
<hr>
<h3 id="heading-the-serverless-app">The Serverless App</h3>
<p>A Serverless solution consists of a web server, Lambda functions (FaaS), security token service (STS), user authentication and database.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*TIrjN7EjLUVJmJ6YvHR7Dg.png" alt="Image" width="1376" height="704" loading="lazy"></p>
<p><em>Source:</em> <a target="_blank" href="http://blog.tonyfendall.com/2015/12/serverless-architectures-using-aws-lambda/"><em>http://blog.tonyfendall.com/2015/12/serverless-architectures-using-aws-lambda/</em></a></p>
<ul>
<li><p><strong>Client Application</strong> — The UI of your application is rendered client side in Modern Frontend Javascript App which allows us to use a simple, static web server.</p>
</li>
<li><p><strong>Web Server</strong> — Amazon S3 provides a robust and simple web server. All of the static HTML, CSS and JS files for our application can be served from S3.</p>
</li>
<li><p><strong>Lambda functions (FaaS)</strong> — They are the key enablers in Serverless architecture. Some popular examples of FaaS are AWS Lambda, Google Cloud Functions and Microsoft Azure Functions. AWS Lambda is used in this framework. The application services for logging in and accessing data will be built as Lambda functions. These functions will read and write from your database and provide JSON responses.</p>
</li>
<li><p><strong>Security Token Service (STS)</strong> — generates temporary AWS credentials (API key and secret key) for users of the application. These temporary credentials are used by the client application to invoke the AWS API (and thus invoke Lambda).</p>
</li>
<li><p><strong>User Authentication</strong> — AWS Cognito is an identity service which is integrated with AWS Lambda. With Amazon Cognito, you can easily add user sign-up and sign-in to your mobile and web apps. It also has the options to authenticate users through social identity providers such as Facebook, Twitter or Amazon, with SAML identity solutions, or using your own identity system.</p>
</li>
<li><p><strong>Database</strong> — AWS DynamoDB provides a fully managed NoSQL database. DynamoDB is not essential for a serverless application but is used as an example here.</p>
</li>
</ul>
<hr>
<h3 id="heading-benefits-of-serverless-architecture">Benefits of Serverless Architecture</h3>
<h4 id="heading-from-business-perspective"><strong>From business perspective</strong></h4>
<ol>
<li><p>The cost incurred by a serverless application is based on the number of function executions, measured in milliseconds instead of hours.</p>
</li>
<li><p>Process agility: Smaller deployable units result in faster delivery of features to the market, increasing the ability to adapt to change.</p>
</li>
<li><p>Cost of hiring backend infrastructure engineers goes down.</p>
</li>
<li><p>Reduced operational costs</p>
</li>
</ol>
<h4 id="heading-from-developer-perspective"><strong>From developer perspective</strong></h4>
<ol>
<li><p>Reduced liability, no backend infrastructure to be responsible for.</p>
</li>
<li><p>Zero system administration.</p>
</li>
<li><p>Easier operational management.</p>
</li>
<li><p>Fosters adoption of Nanoservices, Microservices, SOA Principles.</p>
</li>
<li><p>Faster set up.</p>
</li>
<li><p>Scalable, no need to worry about the number of concurrent requests.</p>
</li>
<li><p>Monitoring out of the box.</p>
</li>
<li><p>Fosters innovation.</p>
</li>
</ol>
<h4 id="heading-from-user-perspective"><strong>From user perspective</strong></h4>
<ol>
<li><p>If businesses are using that competitive edge to ship features faster, then customers are receiving new features quicker than before.</p>
</li>
<li><p>It is possible that users can more easily provide their own storage backend(i.e Dropbox, Google Drive).</p>
</li>
<li><p>It’s more likely that these kinds of apps may offer client-side caching, which provides a better offline experience.</p>
</li>
</ol>
<hr>
<h3 id="heading-drawbacks-of-serverless-architecture">Drawbacks of Serverless Architecture</h3>
<h4 id="heading-from-business-perspective-1"><strong>From business perspective</strong></h4>
<ol>
<li><p>Reduced overall control.</p>
</li>
<li><p>Vendor lock-in requires more trust for a third-party provider.</p>
</li>
<li><p>Additional exposure to risk requires more trust for a third party provider.</p>
</li>
<li><p>Security risk.</p>
</li>
<li><p>Disaster recovery risk</p>
</li>
<li><p>Cost is unpredictable because the number of executions is not predefined</p>
</li>
<li><p>All of these drawbacks can be mitigated with open-source alternatives but at the expense of cost benefits mentioned previously</p>
</li>
</ol>
<h4 id="heading-from-developer-perspective-1"><strong>From developer perspective</strong></h4>
<ol>
<li><p>Immature technology results in component fragmentation, unclear best-practices.</p>
</li>
<li><p>Architectural complexity.</p>
</li>
<li><p>The discipline required against function sprawl.</p>
</li>
<li><p>Multi-tenancy means it’s technically possible that neighbour functions could hog the system resources behind the scenes.</p>
</li>
<li><p>Testing locally becomes tricky.</p>
</li>
<li><p>Significant restrictions on the local state.</p>
</li>
<li><p>Execution duration is capped.</p>
</li>
<li><p>Lack of operational tools</p>
</li>
</ol>
<h4 id="heading-from-user-perspective-1"><strong>From user perspective</strong></h4>
<ol>
<li>Unless architected correctly, an app could provide a poor user experience as a result of increased request latency.</li>
</ol>
<hr>
<h3 id="heading-serverless-frameworks">Serverless Frameworks</h3>
<p><em>Source: https//serverless.com</em></p>
<p>Serverless platforms need infrastructures where they can be executed, provider agnostic frameworks provide a platform agnostic way to define and deploy Serverless code on various cloud platforms or commercial services.</p>
<ul>
<li><p><a target="_blank" href="https://serverless.com/">Serverless Framework</a> (Javascript, Python, Golang)</p>
</li>
<li><p><a target="_blank" href="http://apex.run/">Apex</a> (Javascript)</p>
</li>
<li><p><a target="_blank" href="https://claudiajs.com/">ClaudiaJS</a> (Javascript)</p>
</li>
<li><p><a target="_blank" href="https://gosparta.io/">Sparta</a> (Golang)</p>
</li>
<li><p><a target="_blank" href="https://github.com/jorgebastida/gordon">Gordon</a> (Javascript)</p>
</li>
<li><p><a target="_blank" href="https://www.zappa.io/">Zappa</a> (Python)</p>
</li>
<li><p><a target="_blank" href="https://github.com/apex/up">Up</a> (Javascript, Python, Golang, Crystal)</p>
</li>
</ul>
<hr>
<h3 id="heading-summary">Summary</h3>
<p>Serverless architecture is certainly very exciting, but it comes with a bunch of limitations. As the validity and success of architectures depend on the business requirements and by no means solely on technology. In the same way, Serverless can shine when used in proper place.</p>
<p>Take a look at the awesomeness that is Serverless, it's time to take a peek at what Serverless looks from the inside. Here are few links to get you started on your Serverless journey.</p>
<p><a target="_blank" href="https://github.com/serverless/examples"><strong>serverless/examples</strong></a><br><a target="_blank" href="https://github.com/serverless/examples">_Serverless Examples - A collection of boilerplates and examples of serverless architectures built with the Serverless…_github.com</a></p>
<p><a target="_blank" href="https://github.com/anaibol/awesome-serverless"><strong>anaibol/awesome-serverless</strong></a><br><a target="_blank" href="https://github.com/anaibol/awesome-serverless">_awesome-serverless - :cloud: A curated list of awesome services, solutions and resources for serverless / nobackend…_github.com</a></p>
<p><a target="_blank" href="https://hackernoon.com/building-serverless-contact-form-for-static-websites-b0e622d5a035"><strong>Building Serverless Contact Form For Static Websites</strong></a><br><a target="_blank" href="https://hackernoon.com/building-serverless-contact-form-for-static-websites-b0e622d5a035">_Handling static forms with AWS serverless lambda functions_hackernoon.com</a></p>
<p>I hope this article helped in the understanding of Serverless Computing. I’d love to hear about how you use Serverless in your projects. Share the knowledge, help it reach more people.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Integrate DynamoDB into your API using AWS Lambda ]]>
                </title>
                <description>
                    <![CDATA[ By Sam Williams In the first part of this tutorial, we created an API which passed requests through to a Lambda which returned the top tv show or movie for that genre. Now we’re going to use DynamoDB to allow users to vote for their favourite genre. ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/building-an-api-with-lambdas-and-api-gateway-part-2-7c674a0eb121/</link>
                <guid isPermaLink="false">66c346c7160da468ed76f174</guid>
                
                    <category>
                        <![CDATA[ Amazon ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 25 Jul 2018 20:38:49 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*DpwCOdwJh84BzmZCuJPLmA.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sam Williams</p>
<p>In the <a target="_blank" href="https://medium.freecodecamp.org/building-an-api-with-lambdas-and-api-gateway-11254e23b703">first part of this tutorial</a>, we created an API which passed requests through to a Lambda which returned the top tv show or movie for that genre. Now we’re going to use DynamoDB to allow users to vote for their favourite genre.</p>
<p>If you’ve not read the first part of this series, then <a target="_blank" href="https://medium.freecodecamp.org/building-an-api-with-lambdas-and-api-gateway-11254e23b703">check it out here</a>!</p>
<h3 id="heading-dynamodb">DynamoDB</h3>
<p>DynamoDB is a non-relational database created by Amazon that we can use to store the users’ votes. It’s also great, because we can access it easily using the <strong>aws-sdk</strong> which Lambdas have preinstalled.</p>
<p>The first thing we need to do is to create a table to store the movie votes. Navigate to DynamoDB in AWS and click “Create table”.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/gw6O3QWWUiAy784JH5lWIm1K2SVgfq7dNFT9" alt="Image" width="800" height="410" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/HyNfOnvaam0CEq7vhE-YBZZ9lWcdHDBtJEZT" alt="Image" width="800" height="382" loading="lazy"></p>
<p>On the next page, we will name our table and provide a primary key. The primary key needs to be unique so we don’t have two records with the same key. We can call the table “movie-api” and set the primary key to “movie-genre”, as each movie should only appear once in each genre.</p>
<p>We’ve now set up all that we need to set up in DynamoDB so we can go back into our code.</p>
<h3 id="heading-adding-a-dynamo-handler">Adding a Dynamo handler</h3>
<p>Getting and putting data into a Dynamo table is done using the <code>documentClient</code> on <strong>aws-sdk</strong>, but the structure of the requests is very specific. To make our lives easier, we can make a Dynamo handler to do all of the formatting.</p>
<p>Start by creating a new file called “dynamo.js” in the “movieAPI” Lambda. In this file we start by requiring <strong>aws-sdk</strong> and creating our <code>documentClient</code>.</p>
<pre><code><span class="hljs-keyword">const</span> AWS = <span class="hljs-built_in">require</span>(<span class="hljs-string">'aws-sdk'</span>);
</code></pre><pre><code><span class="hljs-keyword">let</span> documentClient = <span class="hljs-keyword">new</span> AWS.DynamoDB.DocumentClient({    <span class="hljs-string">'region'</span>: <span class="hljs-string">'eu-west-1'</span>});
</code></pre><p>We now want to create and export a class that has three methods on it: a <code>get</code>, a <code>write</code>, and an <code>update</code>.</p>
<pre><code><span class="hljs-built_in">module</span>.exports = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DB</span> </span>{    get(key, value, table) {}    write(ID, data, table) {}    <span class="hljs-keyword">async</span> increment(ID, table) {}}
</code></pre><p>We’ll start by creating our <code>get</code> method. The first thing we need to do is to check that we have a valid <code>key</code><em>,</em> <code>value</code>, and <code>table</code>.</p>
<pre><code><span class="hljs-keyword">if</span> (!table) <span class="hljs-keyword">throw</span> <span class="hljs-string">'table needed'</span>;<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> key !== <span class="hljs-string">'string'</span>) <span class="hljs-keyword">throw</span> <span class="hljs-string">`key was not string and was <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(key)}</span> on table <span class="hljs-subst">${table}</span>`</span>;<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> value !== <span class="hljs-string">'string'</span>) <span class="hljs-keyword">throw</span> <span class="hljs-string">`value was not string and was <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(value)}</span> on table <span class="hljs-subst">${table}</span>`</span>;
</code></pre><p>Because we want this method to be promise-based, we need to return a <code>new Promise</code>.</p>
<pre><code><span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {})
</code></pre><p>To get data from Dynamo, we need to pass a set of parameters to the document client. These params need to include <code>TableName</code> and <code>Key</code><em>.</em></p>
<pre><code><span class="hljs-keyword">let</span> params = {    <span class="hljs-attr">TableName</span>: table,    <span class="hljs-attr">Key</span>: {[key]: value}};
</code></pre><p>We pass these <strong>params</strong> to <code>documentClient</code> and then <code>reject</code> if there is an error or <code>resolve</code> if there isn’t.</p>
<pre><code>documentClient.get(params, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err, data</span>) </span>{    <span class="hljs-keyword">if</span> (err) {        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`There was an error fetching the data for <span class="hljs-subst">${key}</span> <span class="hljs-subst">${value}</span> on table <span class="hljs-subst">${table}</span>`</span>, err);        <span class="hljs-keyword">return</span> reject(err);    }    <span class="hljs-keyword">return</span> resolve(data.Item);});
</code></pre><p>A similar process is done for the <code>write</code> method. We check that the <strong>parameters</strong> are valid, create the <strong>parameters</strong>, and pass them to <code>documentClient</code><em>.</em></p>
<pre><code><span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> ID !== <span class="hljs-string">'string'</span>) <span class="hljs-keyword">throw</span> <span class="hljs-string">`the id must be a string and not <span class="hljs-subst">${ID}</span>`</span>;    <span class="hljs-keyword">if</span> (!data) <span class="hljs-keyword">throw</span> <span class="hljs-string">"data is needed"</span>;    <span class="hljs-keyword">if</span> (!table) <span class="hljs-keyword">throw</span> <span class="hljs-string">'table name is needed'</span>;
</code></pre><pre><code>    <span class="hljs-keyword">let</span> params = {        <span class="hljs-attr">TableName</span>: table,        <span class="hljs-attr">Item</span>: { ...data, <span class="hljs-attr">ID</span>: ID }    };
</code></pre><pre><code>    documentClient.put(params, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err, result</span>) </span>{        <span class="hljs-keyword">if</span> (err) {            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Err in writeForCall writing messages to dynamo:"</span>, err);            <span class="hljs-built_in">console</span>.log(params);            <span class="hljs-keyword">return</span> reject(err);        }        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'wrote data to table '</span>, table)        <span class="hljs-keyword">return</span> resolve({ ...result.Attributes, ...params.Item });    });});
</code></pre><p>The <code>increment</code> method is a lot easier. To increment, we try getting the data for that key, increase the count by one, and then write it back to the database. If we can’t get the data, or if there is no count on the data, then we assume that we need to set the count to 0.</p>
<pre><code><span class="hljs-keyword">async</span> increment(ID, table) {    <span class="hljs-keyword">if</span> (!table) <span class="hljs-keyword">throw</span> <span class="hljs-string">'table needed'</span>;    <span class="hljs-keyword">if</span> (!ID) <span class="hljs-keyword">throw</span> <span class="hljs-string">'ID needed'</span>;    <span class="hljs-keyword">let</span> data;    <span class="hljs-keyword">try</span> {        data = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.get(<span class="hljs-string">'movie-genre'</span>, ID, table);        <span class="hljs-keyword">if</span> (!data.count) <span class="hljs-keyword">throw</span> <span class="hljs-string">'no count in data'</span>    } <span class="hljs-keyword">catch</span> (err) {            data = { <span class="hljs-string">"movie-genre"</span>: ID, <span class="hljs-attr">count</span>: <span class="hljs-number">0</span> };    };    <span class="hljs-keyword">let</span> newData = { ...data, <span class="hljs-attr">count</span>: data.count + <span class="hljs-number">1</span> };    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.write(ID, newData, table);}
</code></pre><h3 id="heading-modifying-our-lambda">Modifying our Lambda</h3>
<p>Now we have an easy way to get, write, and update our Dynamo table. We can use this to allow our users to vote. Inside “index.js”, we first need to import our new Dynamo class and create an instance of it.</p>
<pre><code><span class="hljs-keyword">const</span> DB = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./dynamo'</span>);<span class="hljs-keyword">const</span> Dynamo = <span class="hljs-keyword">new</span> DB();
</code></pre><p>Now, inside of our <code>putMovie</code> we can add the logic to allow users to vote. The two things we need to get are <code>movie</code> from the body and <code>genre</code> from the path parameters. We then combine these to create our <code>movie-genre</code> ID. This then gets passed into <code>Dynamo.increment</code> with a table name of <code>movie-api</code> and our <code>putMovie</code> is complete.</p>
<pre><code><span class="hljs-keyword">const</span> putMovie = <span class="hljs-keyword">async</span> event =&gt; {    <span class="hljs-keyword">let</span> { movie } = <span class="hljs-built_in">JSON</span>.parse(event.body);    <span class="hljs-keyword">let</span> genre = event.pathParameters.genre;    <span class="hljs-keyword">let</span> ID = <span class="hljs-string">`<span class="hljs-subst">${movie}</span>-<span class="hljs-subst">${genre}</span>`</span>;    <span class="hljs-keyword">return</span> Dynamo.increment(ID, <span class="hljs-string">'movie-api'</span>)}
</code></pre><p>To get this to work when we receive the <code>Put</code> request, we need to slightly modify our base handler function.</p>
<pre><code><span class="hljs-keyword">if</span> (event.httpMethod === <span class="hljs-string">'PUT'</span>) {    <span class="hljs-keyword">let</span> response = <span class="hljs-keyword">await</span> putMovie(event)    <span class="hljs-keyword">return</span> done(response);}
</code></pre><p>Because we’ve added <strong>AWS</strong> to our Lambda, we need to run <code>npm init</code> and then <code>npm install — save aws-sdk</code> while in the Lambda folder. This can be done locally and uploaded, or done using Cloud9.</p>
<h3 id="heading-adding-the-api-gateway-method">Adding the API Gateway method</h3>
<p>With the new function, we can add a new method to our API. In API Gateway, we can select our “movieAPI” and then select “/movies/{genre}”<em>.</em> Click “Actions” -&gt; “Create Meth_o_d” and choose to add a “PUT” method.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/nkKXDo9fZIwCBmib5CuBVhOuPYgt5kCxuF7b" alt="Image" width="800" height="453" loading="lazy"></p>
<p>This “PUT” can be directed at our “movieAPI”<em>,</em> and tick “Use Lambda Proxy Integration”. Once saved we can test it out. On the method we can click “TEST” and enter a genre and a body containing a movie. When we click “TEST” we get a response containing the movie and new count. As this is the first vote, the count will be 1.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/22fOgFeE-f4fu84NrhXqW3NDtfYjCpiDfMCO" alt="Image" width="624" height="244" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Z6vdhExeuNJFJQCoAZZcHdndLzjRy3hmxu0I" alt="Image" width="774" height="270" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/mLrC1ijul84nx3VvTJsjo6RFIZCjQqHIHQ7e" alt="Image" width="800" height="296" loading="lazy"></p>
<p>Running the test a second time will now increment the votes for this movie by one.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ZriL39b1A9v2MyEFt4Zlk7oat5jHGVrT6DZj" alt="Image" width="800" height="283" loading="lazy"></p>
<h3 id="heading-modifying-the-get-method">Modifying the <em>GET</em> method</h3>
<p>Now that we have a new voting system, we can update our “GET” to use this new data. We need to get all of the movies that are in the requested genre and list them in order of votes.</p>
<p>We first need to make a new dynamo method. This method will scan each of the entries and pick out the ones that match our criteria.</p>
<pre><code>scan(key, value, table) {    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {        <span class="hljs-keyword">let</span> params = {             <span class="hljs-attr">TableName</span>: table,             <span class="hljs-attr">FilterExpression</span>: <span class="hljs-string">`<span class="hljs-subst">${key}</span> = :value`</span>,             <span class="hljs-attr">ExpressionAttributeValues</span>: { <span class="hljs-string">':value'</span>: value }         };         documentClient.scan(params, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err, data</span>) </span>{             <span class="hljs-keyword">if</span> (err) reject(err);             resolve(data);         });    });}
</code></pre><p>We can now modify our <code>getMovie</code> function to use this new Dynamo method. We need to pass the genre, selected movie, and current count.</p>
<pre><code><span class="hljs-keyword">const</span> getMovie = <span class="hljs-keyword">async</span> event =&gt; {    <span class="hljs-keyword">let</span> genre = event.pathParameters.genre;    <span class="hljs-keyword">let</span> data = <span class="hljs-keyword">await</span> Dynamo.scan(<span class="hljs-string">'genre'</span>, genre, <span class="hljs-string">'movie-api'</span>);    <span class="hljs-keyword">let</span> result = data.Items.sort(<span class="hljs-function">(<span class="hljs-params">a,b</span>) =&gt;</span> b.count - a.count);    result = result.map(<span class="hljs-function">(<span class="hljs-params">{count, ID, genre}</span>)=&gt;</span> { <span class="hljs-keyword">return</span> {count, ID, genre}});    <span class="hljs-keyword">return</span> data;}
</code></pre><p>The last thing to do is to add an <code>await</code> before out <code>getMovie</code> function so that it handles the async database scan.</p>
<pre><code><span class="hljs-keyword">let</span> response = <span class="hljs-keyword">await</span> getMovie(event);
</code></pre><h4 id="heading-testing">Testing</h4>
<p>When we hit this new “GET” endpoint we receive an ordered list of all of the movies in the database.</p>
<pre><code>[  {    <span class="hljs-string">"count"</span>: <span class="hljs-number">2</span>,    <span class="hljs-string">"ID"</span>: <span class="hljs-string">"Desperado (1995)-action"</span>,    <span class="hljs-string">"genre"</span>: <span class="hljs-string">"action"</span>  },  {    <span class="hljs-string">"count"</span>: <span class="hljs-number">1</span>,    <span class="hljs-string">"ID"</span>: <span class="hljs-string">"Team America (2004)-action"</span>,    <span class="hljs-string">"genre"</span>: <span class="hljs-string">"action"</span>  }]
</code></pre><h3 id="heading-summary">Summary</h3>
<p>We’ve now built an API that can handle “GET” and “PUT” requests, storing and retrieving data from a Dynamo database. You can also reuse a lot of the Dynamo class code for other APIs that work with Dynamo.</p>
<h3 id="heading-want-some-practice">Want some practice?</h3>
<p>If you’ve enjoyed this, then why not try to implement a similar setup for tv shows? If you do, then let me know how it goes!</p>
<p>You can also improve this API by making sure that <code>Desperado (1995)</code> and <code>desperado (1995)</code> both count towards the same movie, or only allow a certain format of movie title.</p>
<p>If you’ve liked this, then make sure to give it a clap and subscribe for more Amazon tutorials and guides. <strong>See you in the next article and Keep Coding!</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/SClwEaQxE4CUJ6oJviWTugWNaGOAH4Xxqohh" alt="Image" width="800" height="288" loading="lazy"></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Building community sign-up app with Serverless, StepFunctions and StackStorm Exchange — Episode  2 ]]>
                </title>
                <description>
                    <![CDATA[ By Dmitri Zimine Build a real-world serverless application on AWS with Serverless framework and ready-to-use functions from StackStorm Exchange open-source catalog. Episode One | Episode Two | Episode Three | Episode Four In this second episode, I’ll... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/building-community-sign-up-app-with-serverless-stepfunctions-and-stackstorm-exchange-episode-2-b1efeb1b9bd6/</link>
                <guid isPermaLink="false">66c346de160da468ed76f178</guid>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Devops ]]>
                    </category>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ serverless ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 19 Dec 2017 19:41:18 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*-0KcbVF9M6t_UvLpObeNYw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dmitri Zimine</p>
<p>Build a real-world serverless application on AWS with <a target="_blank" href="https://serverless.com/framework/">Serverless framework</a> and ready-to-use functions from <a target="_blank" href="https://exchange.stackstorm.org">StackStorm Exchange</a> open-source catalog.</p>
<p><a target="_blank" href="https://medium.com/@dzimine/tutorial-building-a-community-on-boarding-app-with-serverless-stepfunctions-and-stackstorm-b2f7cf2cc419">Episode One</a> | Episode Two | <a target="_blank" href="https://medium.com/@dzimine/building-a-community-sign-up-app-with-serverless-stepfunctions-and-stackstorm-exchange-episode-6efb9c102b0a">Episode Three</a> | <a target="_blank" href="https://medium.com/@dzimine/building-a-community-sign-up-app-with-serverless-stepfunctions-and-stackstorm-exchange-episode-7c5f0e93dd6">Episode Four</a></p>
<p>In this second episode, I’ll add two more actions: create a contact in ActiveCampaign, and record a user in Dynamo DB. The full code for this episode is on Github at <a target="_blank" href="https://github.com/dzimine/slack-signup-serverless-stormless/tree/DZ/2-add-more-actions">2-add-more-actions branch</a>.</p>
<h3 id="heading-add-more-actions">Add more actions</h3>
<p>To continue to the next step, you’ll need an <a target="_blank" href="https://www.activecampaign.com">ActiveCampaign</a> account. Fear not: it takes 2 minutes — I just tried — they didn’t ask me for a credit card or anything stupid. Just email. Once in, go to “My Settings”, and select “Developer”.</p>
<p>Note the <code>URL</code> and <code>Key</code> fields in the "API access" section. Add them into <code>env.yml</code> like this:</p>
<pre><code># Copy to env.yml and replace <span class="hljs-keyword">with</span> your values.# Don<span class="hljs-string">'t commit to Github :)slack:  admin_token: "xoxs-111111111111-111111111111-..."  organization: "your-team"active_campaign:  url: "https://YOUR-COMPANY.api-us1.com"  api_key: "1234567a9012a12345z12aa2..."</span>
</code></pre><p><strong>PRO TIP:</strong> If you’re not in the mood for Active Campaign, or any sign-ups, just mock up the API endpoint with something like <a target="_blank" href="https://www.mocky.io/">Mocky</a> or <a target="_blank" href="https://www.mocky.io/">mockable.io</a>and adjust the examples accordingly. For bonus points, create another serverless function with API Gateway endpoint in your <code>serverless.yml</code> and use it to mock the ActiveCampaign API call.</p>
<p>Now I am ready to add an <a target="_blank" href="https://exchange.stackstorm.org/#activecampaign">Active Campaign</a> lambda function. Same routine as in <a target="_blank" href="https://medium.com/@dzimine/tutorial-building-a-community-on-boarding-app-with-serverless-stepfunctions-and-stackstorm-b2f7cf2cc419">Episode One</a>: start with finding a new action in a pack with <code>sls stackstorm info --pack activecampaign</code> (hint: the action you're looking is <code>contact_sync</code> which adds and updates a contact). Inspect the action with <code>sls stackstorm info --action activecampaign.contact_sync</code>:</p>
<p>Bunch of parameters, but besides the config, only <code>email</code> is required. I also want to use <code>first_name</code> and <code>last_name</code>. The function definition in <code>serverless.yml</code> will look like this:</p>
<pre><code>RecordAC:    timeout: <span class="hljs-number">10</span>    memorySize: <span class="hljs-number">128</span>    stackstorm:      action: activecampaign.contact_add      input:        email: <span class="hljs-string">"{{ input.body.email }}"</span>        first_name: <span class="hljs-string">"{{ input.body.first_name }}"</span>        last_name: <span class="hljs-string">"{{ input.body.last_name }}"</span>      config: ${file(env.yml):activecampaign}
</code></pre><p>I had to bump up the timeout as the ActiveCampaign API is taking longer than Lambda's default 6 seconds during Christmas season. But I can reclaim invocation cost by lowering memory use from default 512Mb. This time I don't bother to expose it to AWS API Gateway - we can conveniently test it with <code>sls</code>.</p>
<p>The function is ready to fly to AWS. We could do it at once with <code>sls deploy</code>but let's take it slow again and repeat the deployment steps just like in <a target="_blank" href="https://medium.com/@dzimine/tutorial-building-a-community-on-boarding-app-with-serverless-stepfunctions-and-stackstorm-b2f7cf2cc419">episode 1</a> of this tutorial to engrave the workflow in your mind:</p>
<ol>
<li>Build and package the bundle:</li>
</ol>
<pre><code>sls package
</code></pre><ol start="2">
<li>Test locally (note I’m using <code>--passthrough</code> to only test transformations, remove it to make an actual call):</li>
</ol>
<pre><code>sls  stackstorm docker run --<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">RecordAC</span> \--<span class="hljs-title">passthrough</span> \--<span class="hljs-title">verbose</span> --<span class="hljs-title">data</span> '</span>{<span class="hljs-string">"body"</span>:{<span class="hljs-string">"email"</span>:<span class="hljs-string">"santa@mad.russian.xmas.com"</span>, <span class="hljs-string">"first_name"</span>:<span class="hljs-string">"Santa"</span>, <span class="hljs-string">"last_name"</span>: <span class="hljs-string">"Claus"</span>}}<span class="hljs-string">'</span>
</code></pre><ol start="3">
<li>Deploy to AWS:</li>
</ol>
<pre><code>sls deploy
</code></pre><ol start="4">
<li>Test on AWS with <code>sls invoke</code>:</li>
</ol>
<pre><code>sls invoke --<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">RecordAC</span> --<span class="hljs-title">logs</span> \ --<span class="hljs-title">data</span> '</span>{<span class="hljs-string">"body"</span>:{<span class="hljs-string">"email"</span>:<span class="hljs-string">"santa@mad.russian.xmas.com"</span>, <span class="hljs-string">"first_name"</span>:<span class="hljs-string">"Santa"</span>, <span class="hljs-string">"last_name"</span>: <span class="hljs-string">"Claus"</span>}}<span class="hljs-string">'</span>
</code></pre><ol start="5">
<li>Check the logs:</li>
</ol>
<pre><code>sls logs --<span class="hljs-function"><span class="hljs-keyword">function</span>  <span class="hljs-title">RecordAC</span></span>
</code></pre><p>and I checked, it works: Santa Claus appeared in ActiveCampaign’s contact list. How do I know it’s our Lambda? Because I no longer believe Santa is real enough to subscribe to community without our little Lambda function.</p>
<p><strong>PRO TIP:</strong> If you hit a bug or want a feature in a pack you are using from <a target="_blank" href="https://exchagne.stackstorm.org">StackStorm Exchange</a>, you can fix it on the spot. Packs are cloned under <code>./~st2/packs</code>. Find your action there, modify the code, and use a local run to debug and validate.<br>Big bonus for pushing fixes back to the Exchange: each pack is already a git clone that makes it naturally easy to contribute back to the community.</p>
<p>Let’s add the final action, RecordDB, that writes contact info into a DynamoDB table. I could have used the <code>aws.dynamodb_put_item</code> action from the <a target="_blank" href="https://exchange.stackstorm.org/#aws">AWS pack on StackStorm Exchange</a> - the pack is heavily used and well maintained. But I decided to make it a native Lambda: it's just 30 lines of code, with no extra Python dependencies, since the Boto library is already in the AWS Lambda environment.</p>
<p>The function’s code goes into <code>./record_db/handler.py</code>:</p>
<p>The final <code>serverless.yml</code> with all three actions now looks like this:</p>
<p>Wow! The file doubled. The function itself is just 2 lines (35:36), but quite a few interesting additions took place. Let’s review them:</p>
<ol>
<li>Line 9 — Table name generated to avoid collisions between regions and environments.</li>
<li>Lines 10:13 — IAM Role created to give the function access to the DynamoDB table.</li>
<li>Line 39:56 — AWS CloudFormation template defining the table.</li>
</ol>
<p>The last point brings up an important observation: <a target="_blank" href="https://www.freecodecamp.org/news/building-community-sign-up-app-with-serverless-stepfunctions-and-stackstorm-exchange-episode-2-b1efeb1b9bd6/(https://serverless.com/framework)">Serverless framework</a> simplifies mainly the FaaS part of serverless. But because servereless is more than FaaS, you’ll find yourself writing quite a lot of CloudFormation to provision other services. Serverless framework leaves space for provider specific resources. To be seriously serverless on AWS, master CloudFormation. Looking for “provider-agnostic serverless”? Double-check your assumptions.</p>
<p>Also, I moved <code>memorySize</code> and <code>timeout</code> to apply to all functions (lines 6:7). And the API Gateway endpoint is gone from the InviteSlack function: it served the demonstration role in the first episode, but now we've learned to test Lambda functions directly. We'll return to API Gateway later to invoke the final StepFunction end-to-end workflow.</p>
<p>Let’s get the RecordDB function up to the sky and running.<br>Deploy, invoke, logs. Rinse repeat.</p>
<pre><code># Deploysls deploy ...
</code></pre><pre><code># Invokesls invoke --<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">RecordDB</span> --<span class="hljs-title">logs</span> --<span class="hljs-title">data</span> '</span>{<span class="hljs-string">"body"</span>:{<span class="hljs-string">"email"</span>:<span class="hljs-string">"santa@mad.russian.xmas.com"</span>, <span class="hljs-string">"first_name"</span>:<span class="hljs-string">"Santa"</span>, <span class="hljs-string">"last_name"</span>: <span class="hljs-string">"Claus"</span>}}<span class="hljs-string">'...</span>
</code></pre><pre><code># Check logs.sls logs --<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">RecordDB</span>.</span>
</code></pre><p>Now all three actions are here, waiting to be wired together into a final workflow with a StepFunction. But I’m just reminded not to be Mr. Scrooge: it’s the holiday season, let’s take it easy and put it off to the next episode. Until then, keep the spirits high!</p>
<p>The complete code example for this episode is on Github at <a target="_blank" href="https://github.com/dzimine/slack-signup-serverless-stormless/tree/DZ/2-add-more-actions">2-add-more-actions</a> branch.</p>
<p><a target="_blank" href="https://medium.com/@dzimine/building-a-community-sign-up-app-with-serverless-stepfunctions-and-stackstorm-exchange-episode-6efb9c102b0a"><strong>Episode 3</strong></a><strong>: Wiring the actions with a StepFunction</strong></p>
<p>Hope this helped you learn something new, find something interesting, or provoked some good thoughts. Please share your thoughts in the comments here, or tweet me <a target="_blank" href="https://twitter.com/dzimine">@dzimine</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to claw your way out of AWS Lambda function hell using the power of Docker ]]>
                </title>
                <description>
                    <![CDATA[ By Liz Rice When you’re building Lambda functions, it’s easy to get trapped in an “Invalid ELF header” nightmare. The problem is that your binaries are built for the wrong platform. Here’s what’s going on, and how you can fix it easily using Docker. ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/escaping-lambda-function-hell-using-docker-40b187ec1e48/</link>
                <guid isPermaLink="false">66c349d89972b7c5c7624e36</guid>
                
                    <category>
                        <![CDATA[ Alexa ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Docker ]]>
                    </category>
                
                    <category>
                        <![CDATA[ lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 17 Feb 2017 21:58:27 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*HlfWIN7pNtK3ffZ-ll1cZQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Liz Rice</p>
<p>When you’re building Lambda functions, it’s easy to get trapped in an “Invalid ELF header” nightmare. The problem is that your binaries are built for the wrong platform. Here’s what’s going on, and how you can fix it easily using Docker.</p>
<p>When most people get started with Lambda functions, they’ll use the online editor in the console to input their code. This is fine for your first example or two, but pretty soon you’ll want to do something wild and crazy like, y’know, import a library.</p>
<p>Over the past few weekends I’ve been working on <a target="_blank" href="https://hackernoon.com/my-first-alexa-custom-skill-6a198d385c84#.qfxjk23ov">my first Alexa skill for an Amazon Echo</a> and I’ve reached that point where I want to use some third party code to add some additional functionality.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/vktAeFvMs7ITPSm0PgNVUG6EWPSvDRoG7Xfu" alt="Image" width="800" height="356" loading="lazy">
<em>Your options for supplying the code for your Lambda function, as seen in the AWS Console</em></p>
<p>The online editor simply lets you edit a single file. If you want to refer to other files — including imported libraries — you can upload them in a ZIP file (Amazon call this a <a target="_blank" href="http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html">deployment package</a>). But if you‘re working on a Mac or a Windows computer, there’s a catch.</p>
<p>When you use pip to install Python libraries on your laptop, it gives you binaries (.so files) that are built to run on your machine. But when the Lambda function runs in the AWS cloud it is going to be running on Linux — and binaries built for Mac (these are often called ‘darwin’ builds) or Windows won’t run on Linux (and vice versa).</p>
<p>If you upload the Mac version, you’ll see “invalid ELF header” logs when you try to test your Lambda function.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/q0v1xD6yQw0OfdQsiZVo3Fgzlm1jTvAzNUqA" alt="Image" width="800" height="241" loading="lazy">
<em>Invalid ELF header indicates it’s the wrong binary format for the platform</em></p>
<p>So you’re going to need Linux versions of those library files. But what if you don’t have a Linux box to hand?</p>
<p>You could grab yourself an EC2 instance from Amazon (or a droplet on Digital Ocean, or any Linux VM of your preference) but to my mind that’s quite a performance, and could even cost you a little bit of money (especially if you forget to take the EC2 box down again when you don’t need it).</p>
<p>I think the easiest solution is to use Docker.</p>
<h3 id="heading-the-docker-approach">The Docker approach</h3>
<p>With <a target="_blank" href="http://docker.com">Docker</a> you can very easily can run a Linux container locally on your Mac, install the Python libraries within the container so they are automatically in the right Linux format, and zip up the files ready to upload to AWS. You’ll need <a target="_blank" href="https://www.docker.com/products/docker">Docker for Mac (or Windows)</a> installed first.</p>
<p>Spin up an Ubuntu container that can see the Lambda code you want to upload.</p>
<pre><code>docker run -v &lt;directory <span class="hljs-keyword">with</span> your code&gt;:/working -it --rm ubuntu
</code></pre><ul>
<li>The <code>-v</code>flag makes your code directory available inside the container in a directory called “working”.</li>
<li>The <code>-it</code>flag means you get to interact with this container.</li>
<li>The <code>--rm</code> flag means Docker will remove the container when you’re finished.</li>
<li><code>ubuntu</code> is the name of an official container image containing, you guessed it, Ubuntu. If this container image isn’t already on your machine, Docker will download it for you.</li>
</ul>
<p>You should now be inside the container at a shell prompt looking something like this:</p>
<pre><code>root@c1996f32a397:/#
</code></pre><p>Install pip and zip:</p>
<pre><code>$ apt-get update$ apt-get install python-pip$ apt-get install zip
</code></pre><p>Move into the working directory (you should be able to see your Lambda function code here):</p>
<pre><code>$ cd working
</code></pre><p>Use pip to get the library/ies you’re interested in. You can use the -t flag to tell pip to put the libraries here in the current directory, which will be more convenient later as it’s where the AWS deployment package wants them to be:</p>
<pre><code>$ pip install -t . &lt;library&gt;
</code></pre><p>If you’re very curious, you can take a look to see what this installs. In my own case I installed the <code>editdistance</code> library, which gave me the following additional directories and files.</p>
<pre><code>editdistance:__init__.py __init__.pyc _editdistance.h bycython.so def.h
</code></pre><pre><code>editdistance<span class="hljs-number">-0.3</span><span class="hljs-number">.1</span>.dist-info:DESCRIPTION.rst INSTALLER METADATA RECORD WHEEL metadata.json top_level.txt
</code></pre><p>You can see that bycython.so file? This is the correct, Linux version of the binary that AWS was objecting to when I hit the Invalid ELF header (shown in the error log screenshot above).</p>
<p>Create the ZIP file with your Lambda code (in my case, a single file called lambda_function.py) and the libraries (for me, the two editdistance directories and their contents.</p>
<pre><code>$ zip linux-lambda.zip lambda_function.py
</code></pre><pre><code>$ zip -r linux-lambda.zip edit*
</code></pre><p>The <code>-r</code> flag on zip tells it to recursively add the contents of directories.</p>
<p>Now you have an archive file called linux-lambda.zip which is ready to upload to AWS. And because the directory is mounted from the host (your Mac) into the container, you can simply upload the file into the console.</p>
<p>Back in the terminal type <code>exit</code> to quit the container, and it will be as if it never existed, except for the existence of the linux-lambda.zip file, which is still available on the host.</p>
<p>Upload the ZIP file in the console, save it and try running a test. Invalid ELF header error no more!</p>
<p>If this article helps you out, please hit the ? button to make it easier for other people to find it. If you really like it, why not go bananas and share it too?</p>
<p>I’ve written a few other posts about what I’m learning as I write my first Alexa skill, like this one where I <a target="_blank" href="https://hackernoon.com/my-alexa-skill-with-storage-5adb1d097b88#.d0a1a7xha">add database storage capabilities to my Lambda function</a>. If you find them useful, you might be interested in a book I’m writing called <a target="_blank" href="http://leanpub.com/adventureswithalexa">Adventures with Alexa</a>. Pick your own price!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
