<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=160269078105920&amp;ev=PageView&amp;noscript=1">

Build Scalable Applications with AWS Lambda, the Serverless Framework, and Go

Wednesday 10 of March, 2021.
Reading Time: 17 minutes.
By Ariel Orozco



The way we design, build, and deploy web applications has changed greatly in the past few years. Before, all our code lived inside a large folder with a series of files in it; to create an app, we just uploaded the files using FTP and hoped everything would go well. If something went wrong, it was hard to keep track of errors within an overwhelming number of lines of legacy code.

Deploying and managing an application was a time-consuming task that required knowledge of the underlying infrastructure. Servers needed to be upgraded as the application and business grew, and the time spent on these tasks could have gone into developing new features and improving our application instead.  

Nowadays, it has become easier to design and deploy applications that can be scaled, even automatically, as a business grows. With the rise of distributed systems and microservices, it is no longer necessary for all code and logic to be in one place. We can now rely on event-driven architecture to communicate between decoupled services.

In this article, we will be providing a brief overview of how AWS Lambda and the Serverless Framework work together to take advantage of all of these new ways of building scalable applications. We will be using the Go programming language, a language that provides us with additional advantages while developing applications.

 

The Rise of Cloud Computing

When you think about it, everything has been "in the cloud" since the beginning. But the way we understand the term "Cloud Computing" has changed with the rise of new technologies. Back in the day, you had to purchase a server; it didn’t matter if it was virtual or physical, you had to make an estimate of the resources you were going to require and pay for them upfront. Later, if you needed more space, memory, or resources, you had to purchase them and upgrade your server.

Today, "Cloud Computing" is the way to deliver computing services (servers, databases, storage, software, resources, networking) over the internet to build applications that can offer faster innovation, flexible resources, and that can be scaled. This lowers operating costs because you only pay for the services you use. In addition, infrastructure runs more efficiently since it scales as business needs change.

Benefits of Cloud Computing

  • Reduces costs: you only pay for IT as you consume it
  • Elasticity: no need to over-provision resources; you can scale resources instantly as your business needs change
  • Agility: access to a broad range of technologies allows you to innovate faster and to build almost anything you want

There are several Cloud Providers that offer great services, some of them supplied by well-known companies like Microsoft, Google, and Amazon. Amazon AWS is one of the most widely used and provides a great number of services, AWS Lambda among them.

 

Distributed Systems

You may have been using distributed systems without being aware of it. In a nutshell, a distributed system is a group of computers that work together and that share messages with each other to achieve a common goal. For the end-user, this group will appear as a single computer.

To better understand this, let’s go back to the example where you upload all of your application’s code to a server. Here, the code lives in a single computer (virtual or physical); this includes all of the business logic and all components communicate with each other inside this computer. If there’s an infrastructure error or failure, then the entire application goes down. 

A distributed system, in a way, allows us to divide the business logic into different components. This may imply different physical servers, virtual machines, or containers, and it is likely that these will be situated in different locations. In this way, the system can maximize resources and information while preventing failures; if one system fails, this won’t affect the availability of the entire service.

Benefits of Distributed Systems

  • Horizontal Scaling: it is easy and inexpensive to add additional machines when required
  • Fault Tolerance: if one server or data center fails, others could still work without affecting the whole system
  • Performance: workloads can be broken and sent to multiple machines resulting in greater efficiency

Most modern web applications are based on distributed systems. The building of scalable applications relies heavily on this concept, even more so if the app is built on top of cloud provider services.

 

From Monolith to Microservices

Nowadays, monolithic applications are still the backbone of most large organizations, but they are often tied to complex processes that make them fragile when making changes in the codebase. They are built as a single unit where all of the components coexist within the same application; any changes applied to the system involve building and deploying a new version of the entire application.

Currently, one of the most modern software paradigms is to build smaller, independently deployable units of code. This allows you to divide the application into smaller services by applying a single responsibility principle. The system is designed so each module is a standalone microservice responsible for a specific business domain.

https://dev.to/alex_barashkov/microservices-vs-monolith-architecture-4l1m

 If you plan on building a scalable application that leverages cloud computing and distributed systems, then designing your application as a series of microservices will be of great benefit.

 

FaaS (Function-as-a-Service)

FaaS or "Function as a Service" is a type of Cloud Computing service that allows the execution of code in response to events without the need to think about the complexity of the underlying infrastructure typically associated when deploying microservice applications. The Cloud Service Provider automatically handles the provisioning and managing of the infrastructure, allowing you to focus on the individual function in your code. It enables the creation of new applications composed of tiny building blocks.

Benefits of FaaS

  • Focus on the code: free of the need to worry about the infrastructure, you can focus on your application code instead
  • Scale automatically: functions are scaled automatically, independently, and very quickly
  • Pay for the resources you use only: you pay only when the function is executed and this is usually inexpensive

AWS Lambda is the Function-as-a-Service option provided by Amazon AWS. It provides all of the above benefits plus the convenience of being on the AWS platform. The latter makes it very useful to take advantage of all the other services provided by AWS.

 

Event-Driven Architecture

AWS Lambda relies on Event-Driven Architecture. This type of architecture allows your application to detect events whenever you want to trigger any business logic and perform an action in response. This replaces the traditional "request/response" pattern where services would have to wait for a reply before they could move on to the next task.

An event can be anything: from an item added to a cart, an order that was placed, an image uploaded to a server, a record updated on a database, etc. This type of pattern uses events to trigger and communicate between services and it is very common in modern web applications that are built on top of microservices.

 

The Future is Serverless

Serverless is a software development approach that eliminates the need to manage infrastructure by using Cloud Computing services (FaaS) to execute the code and external services and APIs to leverage the application.

Keep in mind that the term “Serverless” does not mean that servers are no longer involved; it simply means developers no longer need to be aware of the underlying infrastructure. Computing resources are used as services without the hassle of managing physical capabilities of limits.

 

The Serverless Framework

The Serverless Framework makes it easy to write event-driven functions for various providers, including AWS. For each provider, a series of events can be configured to invoke the function. All of this is done programmatically by editing a YAML configuration file and running some commands on the terminal. Also, it can be integrated with existing Continuous Integration and Continuous Delivery frameworks.

This makes the task of deploying and updating the code of functions easy and fast. In addition, when you create your serverless project, there are plenty of ready-to-use templates you can choose from, which means you don't have to start from scratch. On AWS, you can use the AWS console and do everything from there; however, every time you want to update your code, you will have to compress it on a zip file and upload it with the AWS console. There are other things you also have to take into consideration, like IAM users, roles, and policies. The Serverless framework takes care of all of this, allowing you to focus on the code only.

 

AWS Lambda

AWS Lambda is an event-driven serverless computing platform. It lets you run code without provisioning or managing servers. It runs code only when needed and scales automatically. You pay only for the compute time you consume, so there is no charge when nothing is running.

It works like this:

 

https://aws.amazon.com/lambda/

 

Currently, AWS Lambda supports several programming languages through the use of runtimes, like node.js, Python, Ruby, Java, and Go. If you want to use other languages in Lambda, you can implement a custom runtime, so the possibilities are endless.  

When using AWS Lambda, you can also take advantage of all of the other AWS Cloud Services. You can trigger events when a photo is uploaded to Amazon S3, listen to streams of data from Amazon Kinesis, trigger a function when data gets added to DynamoDB, or even use Amazon API Gateway to build a serverless REST API. Once more, the possibilities are limitless.

Pricing

You only pay for what you use and will be charged based on the number of requests and the duration of your function. Although we won’t be exploring this topic in-depth, we can say that running a Lambda function is very inexpensive. Even with the Free Tier option, you can play around significantly and run a small service. For more information, visit the AWS Lambda Pricing page.

When should I use AWS Lambda?

First, you have to think in an Event-Driven way. If there's a feature on your application that needs to be run in response to an event, and the feature does not need to be running all of the time, then it’s probably a good idea to use AWS Lambda. Here are some examples:

  • Rapid document conversion
  • Image resizing and processing
  • Handling uploaded AWS S3 objects
  • Operating serverless websites
  • Automated backups and everyday tasks
  • Real-time data processing

Why Go?

Go is without a doubt one of the fastest-growing programming languages today. It has been adopted by a large number of companies but it has seen significant use in Cloud Computing. For this reason, AWS - one of the biggest Cloud Computing providers - added support for Go in AWS Lambda at the beginning of 2018.

 Some of the major advantages of using Go in combination with AWS Lambda are:

  • Runtime versioning: the Go runtime for AWS Lambda supports any 1.x release, so whenever a new version of Go is released, it is possible to use it right away without having to wait for support on the updated runtime.
  • Concurrency: concurrency was built into the core design of Go, allowing us to create more efficient functions with the great benefit of Go routines.
  • Pricing: the pricing model for AWS Lambda is per invocation, plus the duration of the invocation rounded up to the nearest 100ms. Go is not as memory hungry as other dynamic languages and there's a direct relation between CPU performance and the allocated memory, so this makes it very efficient.

Sample Application

To get a better idea of how AWS Lambda and the Serverless Framework work together, we will be going over an example. We will build a simple function that exposes an HTTP endpoint that receives a parameter on the URL and returns a JSON response. It’s nothing major, with small and simple examples it’s easier to understand a new concept. By putting this into practice, you will see how easy and quick is to build and deploy a Lambda function with the Serverless Framework.

Prerequisites

Function Code

The code is pretty straightforward. Most of the Lambda functions are built following the same pattern. Still, it will also depend on which AWS services and integrations are being used as well as on the purpose of your function. The most important aspect here is that you will always need a Handler function; this takes care of all of the logic and will be the function you call on your main() function.

 


package main

import (
"fmt"

"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)

// This function is the one that is going to be called
func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {

// Get the 'name' parameter from the URL
name := request.PathParameters["name"]

// Create the message that is going to be returned
message := fmt.Sprintf(" { \"Message\" : \"AWS Lambda is Awesome! Right %s? \" } ", name)

// Return the response
return events.APIGatewayProxyResponse{Body: message, StatusCode: 200}, nil
}

func main() {
// Start the Handler
lambda.Start(Handler)
}

Serverless Framework Setup

  1. Configure Serverless: replace your access key and secret key. serverless-admin is going to be the name of your profile; this can be whatever you want.

$ serverless config credentials --provider aws --key <your_key> --secret <your_secret> --profile serverless-admin

  1. Create the serverless.yml file (for full configuration options you can check the documentation).

service: lambda-sample

frameworkVersion: '2'

provider:
name: aws
runtime:x
lambdaHashingVersion: 20201221
profile: serverless-admin
region: us-east-2

package:
exclude:
- ./**
include:
   - ./bin/**

functions:
hello:
   handler: bin/hello
   events:
     - http:
         path: hello/{name}
         method: get
  1. Insert the function code inside hello/main.go 
  1. Build the app.

    $ env GOOS=linux go build -ldflags="-s -w" -o bin/hello hello/main.go
  1. Deploy the app.
$ sls deploy -v

Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - hello-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_COMPLETE - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::BucketPolicy - ServerlessDeploymentBucketPolicy
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::BucketPolicy - ServerlessDeploymentBucketPolicy
CloudFormation - CREATE_COMPLETE - AWS::S3::BucketPolicy - ServerlessDeploymentBucketPolicy
CloudFormation - CREATE_COMPLETE - AWS::CloudFormation::Stack - hello-dev
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service hello.zip file to S3 (2.76 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - hello-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHello
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHello
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceHello
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHelloNameVar
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHelloNameVar
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceHelloNameVar
CloudFormation - CREATE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloNameVarGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloNameVarGet
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersion0llM5cHtVxK5BhSODXsBnppzF2TM1roM6OfXw2qXINc
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodHelloNameVarGet
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersion0llM5cHtVxK5BhSODXsBnppzF2TM1roM6OfXw2qXINc
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Version - HelloLambdaVersion0llM5cHtVxK5BhSODXsBnppzF2TM1roM6OfXw2qXINc
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1611337803492
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1611337803492
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1611337803492
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - hello-dev
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - hello-dev
Serverless: Stack update finished...
Service Information
service: hello
stage: dev
region: us-east-2
stack: hello-dev
resources: 12
api keys:
None
endpoints:
GET - https://upr8kq3qsc.execute-api.us-east-2.amazonaws.com/dev/hello/{name}
functions:
hello: hello-dev-hello
layers:
None

Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-2:132653656301:function:hello-dev-hello:1
ServiceEndpoint: https://upr8kq3qsc.execute-api.us-east-2.amazonaws.com/dev
ServerlessDeploymentBucketName: hello-dev-serverlessdeploymentbucket-rdd115w8vsw1

And that’s it! As you can see, the deploy output returns the URL where your endpoint is, in this case, https://upr8kq3qsc.execute-api.us-east-2.amazonaws.com/dev/hello/{name} (where you replace {name} with what you want to send to the function). If you visit this URL on your browser you will get:

 

{
     Message: "AWS Lambda is Awesome! Right Ariel? "
}

Additional Notes

  • As demonstrated, the only thing you need to deploy your function is the serverless.yml configuration file. In this example, everything was created from scratch, but I encourage you to try out any of the sample templates that are generated for you. They even include some boilerplate code, so you can play around with them. You can generate an AWS Go template by running the following command:

 

$ sls create --template aws-go --path sample

Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/code/lambda/sample"
_______                             __
|   _   .-----.----.--.--.-----.----| .-----.-----.-----.
|   |___| -__|   _| | | -__|   _| | -__|__ --|__ --|
|____   |_____|__| \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v2.19.0
-------'

Serverless: Successfully generated boilerplate for template: "aws-go"
  • When you use a template, a Makefile is generated for you, so you can build your app with this command:
$ make build

  • You can also build and deploy at the same time:

    $ make deploy


  • You can deploy only the function as an option as well. Deploying the entire app can take time, but it only needs to be done once, unless you are adding new dependencies. Remember to build with make build

    $ sls deploy function -f hello


  • You can also invoke the function from the command line:

    $ sls invoke -f hello -l


  • View the logs:

    $ sls logs -f hello -t


  • And finally, remove the function:

    $ sls remove

 

AWS Lambda Opens the Door to New Possibilities

AWS Lambda is powering many enterprises around the world and seeing a wide array of uses, from running cloud platforms to extending legacy applications. We covered only the tip of the iceberg in this article, but there are still a lot of features, integrations, and services that can be used with it. I encourage you to explore and read more about what you can do with AWS Lambda and how you can build exciting and scalable web applications.

 

idea-Nov-14-2020-05-00-39-57-PM

KEY TAKEAWAYS

  1. If your aim is to build a scalable application that leverages the use of cloud computing and distributed systems, then designing your application as a series of microservices will have great benefits.
  2. AWS Lambda is an event-driven serverless computing platform that lets you run your code without provisioning or managing servers. It runs your code only when needed and scales automatically.
  3. Currently, Go is one of the fastest-growing programming languages; it has been adopted by a large number of companies and has seen significant use in Cloud Computing.

 

About Avantica

If you are looking for a software partner who will work towards your business goals and success, then Avantica is your solution. We offer dedicated teams, team augmentation, and individual projects to our clients. We are constantly looking for the best methodologies in order to give you the best results.

Let's start a project!
PREVIOUS
Parallel Testing
NEXT
Technology-Assisted Contact-Tracing and Privacy

What do you think about this post?