This article is the third part of a trilogy I have written on FaaS and Serverless. Here I would like to demonstrate how “simple” it is to create a serverless function and what the points to be considered when doing so are.
In addition, I would like to present to you (if you haven’t already heard of it) a framework that will help us to write our functions quickly, while also allowing us to test them locally.
Let’s use the case explained in the following article: Fallback Job: The Final Link in a Fault-Tolerant Microservice; where we have a microservice that is responsible for managing user information, such as name, surname, etc. as well as including the user’s avatar. The problem raised in the article was the need to depend on a file storage service (Amazon S3 or similar), so what we did was create a service that runs in batches to correct incomplete or erroneous transactions.
In this article what we will do is create the same Fallback Job, but run it in AWS Lambda, which will give us less “manual” control of how our fallback should run. In the article we had to write how often it needs to be run in code (or a configuration file ), while in this case we will use the AWS management console.
Serverless is a framework that provides us with a toolbelt with which we can concentrate on writing our business logic for a function without the need to worry about which cloud provider we will use (this is not 100% the case, but almost).
That is to say we will install the framework, open Visual Studio Code, write our logic, run a couple of tests and then deploy it to AWS and voila, it will work.
There are many different ways to install Serverless. My computer runs Windows 10 with Node installed, so I will concentrate on this method of installation, but here is the documentation to install it according to the equipment you have.
npm install -g serverless
The result should be:
Checking that everything is correctly installed
To begin with, we must know what type of function we are going to write, or to put it another way, what language will we use and what cloud provider will we deploy the solution in?
Remember to have docker desktop or one of its variants running.
The following command will help us in this regard:
serverless create --help
In this case we will be using GOLANG and AWS, therefore we will execute the following command:
serverless create -t "aws-go-mod" -u GitHub --name "go-fallback-job"
And it should give us the following result:
If we open Visual Studio Code (or our favorite IDE), we will see the following file structure:
Now if we want to run the local version, we must do the following:
sls invoke local -f hello
This command will throw up an error:
The error is basically because there is no code that responds to this function, and because of this we must compile the code, which we can do by executing the following command:
Therefore, we need to have “make” installed on our respective computers.
If we run it for the first time we will get the following error:
Clearly the error tells us that we have to update the project dependencies, so we run the following command:
go mod download github.com/aws/aws-lambda-go
And then we run again:
And now if it is executed correctly:
Now we can run a local test and we should see the following:
sls invoke local -f hello
Everything works fine, so let’s start programming!
Writing our code
As we mentioned before, our code must do the same as what we achieved in the following article: Fallback Job: The Final Link in a Fault-Tolerant Microservice, therefore it should look something like this.
First of all, we must make a few small changes in the serverless.yml file so that the service is a cron, and not an API call
rate: rate(1 minute)
Let’s go step by step …
Declaration of environment variables: We can declare them in two places, the provider section, which in the case of having more than one function would be general, or within each function, which would be private for each one.
Plugins: To run our function locally, we must install two plugins, these are serverless-offline-scheduler and serverless-offline, which will allow us to test the cron in our environment. To install them we must execute the following command:
npm i --save-dev serverless-offline-scheduler serverless-offline
Functions: This is where we declare our functions, in this particular case it will be a single one, “fallback-job”, in which we indicate that the handler (the function that must be executed), is in bin/fallback-job, and the event that the execution will be scheduled, with a rate of one minute (in other words, it will be executed every minute).
As for our code in GOLANG, the only thing that we need to change from the boilerplate is that the response is not of the API type, but CloudWatch, as when it is executed we must store the response in this AWS service to have a control and follow up.
Then in the Handler function we simply put the desired code. First validate that the service we want to consume exists, make a Request to the api/health endpoint, and if the response is not satisfactory then we create a log and exit. In the event that the response is satisfactory, then we execute the main process, and make a request to the api/users/fallback endpoint.
Once the code is complete, we must execute these steps to perform our tests.
- Compile the code, so that the compiled code is created in the bin folder
- Run serverless to validate that the function is correct
serverless offline start
- The result should be something very similar to this:
For the next steps we should publish our function on AWS, but unfortunately due to an extension issue I will not include it here in this article, but here is a link with the documentation to do so: Serverless Deploy
I hope this series of 3 articles has been useful for you. We have reviewed a little of FaaS, which is one of the most interesting development technologies/architectures around today and widely used by software development companies. It has many positive aspects, and some not so positive, but as with all technologies when it is applied correctly it is a great ally when it comes to achieving the objectives set by a client.