Creating Serverless Functions (FaaS) with AWS Lambda and Golang
Serverless architecture is a new paradigm that is being used in the development of modern applications. The term serverless refers to the abstraction of servers from application development. <!--more--> One advantage of serverless computing over server computing is that the cloud provider takes care of the servers while you concentrate on application development.
Function-as-a-Service (FaaS) is a serverless method of running modular code on the cloud. You can use FaaS to write code that is triggered by events.
For example, when a user clicks on a button in your web application, a specific cloud function is executed.
In this tutorial, we'll build a user profile generator function.
The function will accept some user data and return a profile based on the data.
After uploading the generator function to AWS Lambda, we'll create a client program that communicates with the user-profile-generating function on AWS Lambda.
If you are new to serverless computing, it is highly recommended to go through these articles:
- How to build apps with Serverless architecture
- Comparing serverless computing with containers
- How to migrate an on-premise application to serverless
Requirements
- AWS account to access AWS lambda dashboard.
- Use
git clone https://github.com/Bamimore-Tomi/faas-golang.git
to download the source code for this demo. - Install Go 1.x runtime on your machine.
Setting up an AWS Lambda function
- After creating your AWS account, on the main dashboard, search for
Lambda
.
When you click on Lambda
, the AWS Lambda dashboard will be visible, as shown below:
- Click on the
Create function
button to create a new AWS Lambda function.
Here, we specify the name of the function as user-profile
.
- On the function's dashboard, we will upload the function we want to run in the cloud.
In the next section, we'll look at how to make a function that runs on AWS Lambda.
Creating a user-profile function in Golang
In this section, we will see how to create a function that converts it into a zip file before we upload it on AWS Lambda.
We need to install the aws-lambda-go
package using:
go mod init
go get github.com/aws/aws-lambda-go/lambda
package main
import (
"fmt"
"github.com/aws/aws-lambda-go/lambda"
)
// Struct for the input the program expects from the client
type InfoEvent struct {
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
Age int `json:"age"`
}
// Struct for the output the server will send back to the client
type Response struct {
Profile string `json:"profile"`
}
// Event handler, this function handles requests from clients
func HandleInfoEvent(event InfoEvent) (Response, error) {
return Response{Profile: fmt.Sprintf("Their name is %s %s, they are %d ", event.Firstname, event.Lastname, event.Age)}, nil
}
func main() {
lambda.Start(HandleInfoEvent)
}
Navigate to the server
folder to see this source code.
In the program above, we created the HandleInfoEvent
function. This method runs in the cloud.
Use the following steps to compile and zip the program:
Installation - MacOS and Linux
- Compile the executable:
GOOS=linux go build main.go
- Create the zip file with the following command:
zip user-profile-function.zip main
Installation - Windows
- Download the
build-lambda-zip
tool from GitHub:
go.exe get -u github.com/aws/aws-lambda-go/cmd/build-lambda-zip
- You can now use the tool downloaded earlier to create the zip file:
Set GOOS=linux
Go build -o main main.go
%USERPROFILE%\Go\bin\build-lambda-zip.exe -output main.zip main
You can now upload the generated zip file to AWS Lambda.
You can test the function to check if it works well.
First, we need to change the handler's name from the default hello
to main
.
The Lambda function handler is the method in your function code that processes events.
Click on Edit
:
Change the handler field from hello
to main
and click Save
.
Testing the function on AWS Lambda
- On the main dashboard, click on
Test
:
- Input this sample data in the JSON editor on the page and click on
Test
.
{
"firstname": "Oluwatomisin",
"lastname": "Bamimore",
"age": 19
}
The result will be:
Calling the Lambda function from Golang
We can also execute the same function locally.
For that, we have to install the AWS Go SDK
as shown:
go get github.com/aws/aws-sdk-go
We can now use this code segment to execute the function in the cloud and see the results locally.
package main
import (
"encoding/json"
"fmt"
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/lambda"
"github.com/joho/godotenv"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
)
type Info struct {
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
Age int `json:"age"`
}
type Response struct {
Profile string `json:"profile"`
}
func main() {
// Load the environment variable which has the IAM credentials needed to connect to AWS
godotenv.Load()
// Initialize new aws session
sess := session.Must(session.NewSessionWithOptions(session.Options{SharedConfigState: session.SharedConfigEnable}))
// Initialize new aws client using IAM credentials
client := lambda.New(sess, &aws.Config{Region: aws.String("us-east-1"), Credentials: credentials.NewStaticCredentials(os.Getenv("aws_access_key_id"), os.Getenv("aws_secret_access_key"), "")})
// Prepare request parameters
request := Info{Firstname: "Oluwatomisin", Lastname: "Bamimore", Age: 16}
payload, err := json.Marshal(request)
if err != nil {
fmt.Println("Error marshalling request")
os.Exit(0)
}
result, err := client.Invoke(&lambda.InvokeInput{FunctionName: aws.String("user-profile"), Payload: payload})
if err != nil {
fmt.Println("Error calling user-profile function", err)
os.Exit(0)
}
var resp Response
err = json.Unmarshal(result.Payload, &resp)
if err != nil {
fmt.Println("Error unmarshalling user-profile response")
os.Exit(0)
}
// Print response from lambda function
fmt.Println(resp.Profile)
}
You need to create an IAM user with the correct permissions.
Store the aws_access_key_id
and the aws_secret_access_key
in a .env
file in the directory that you are currently working in.
After running the program, AWS will execute the cloud function, and you will get this result.
The program passes in some arguments (json format) into the cloud function and returns the result.
Conclusion
We have seen how to deploy and consume AWS Lambda functions.
In this tutorial, we learned by building a user-profile generator function written in Golang.
We also tested the Lambda function by sending triggers using an actual client program and the Lambda console on AWS.
In other languages, such as Python, JavaScript, and Java, we use the same mechanism for creating serverless functions.
Happy coding.
Further reading
Peer Review Contributions by: Srishilesh P S