When to use AWS Lambda and genezio?

In recent years, serverless computing has become increasingly popular among developers seeking to simplify the deployment and management of their applications.

AWS Lambda is a well known serverless computing service provided by Amazon Web Services. It allows developers to write functions which are executed in lightweight virtual machines (micro vms) in response to specific events. These virtual machines process requests before returning to a dormant state, with users only paying for the time they are active.

genezio, on the other hand, is a new platform designed to simplify the development of API servers. It allows developers to write standard classes in their preferred programming language and, using an automatically generated SDK, easily call the methods of these classes without having to worry about URLs, HTTP methods, or headers. genezio uses AWS Lambda under the hood as the underlying technology.

Although both services leverage the same technology, each one excels in specific use cases and applications. In this article, we will explore several scenarios and see where it is better to use genezio and when it’s recommended to use AWS Lambda directly.

What is AWS Lambda good for?

One of the great benefits of AWS Lambda is its seamless integration with the AWS ecosystem. AWS Lambda can be set up to respond to a variety of events generated by multiple AWS services, allowing for flexible and dynamic triggering of the function, making it extremely useful in event-driven architectures . In an event-driven architecture, multiple system components communicate through the production and consumption of events, allowing for a loosely coupled and scalable system.

swiss knife

For instance, an AWS Lambda can be used to validate or process files that are uploaded to an S3 Bucket. Imagine that users can upload files directly to S3 using a pre-signed URL generated by the server. However, you might want to check if the file type is correct or if the files are not too big. In this case, you can use AWS Lambda to analyze the files and remove the ones that don’t match the criteria.

In the image below, we set a trigger for an existing Lambda function. We just have to specify the bucket and the event type. The Lambda function defined will be automatically invoked each time a new file is added to the “aws-uploaded-files-1” bucket and it will delete all files larger than 10KB.

lambda trigger

const aws = require('aws-sdk');

const s3 = new aws.S3({ 
    accessKeyId: "<access_key>",
    secretAccessKey: "<secret_access_key>",
});

async function deleteObject(params) {
    return new Promise((resolve, reject) => {
        s3.deleteObject(params, function(err, data) {
            if (err) reject(err);
            else     resolve(data);
        });
    });
}

exports.handler = async (event) => {
    for (const record of event.Records) {
        if (record.s3.object.size > 10 * 1024) {
            console.log("Deleting object", record.s3.object.key)
            var params = {
                Bucket: record.s3.bucket.name, 
                Key: record.s3.object.key
            };
            await deleteObject(params)
        }
    }
};

Another useful integration is AWS Lambda getting triggered by an SQS event. SQS is a queue that can facilitate communication between different subsystems. Imagine you have to build a reservation system for restaurants. Confirming a reservation can take some time. You can make the user wait for the confirmation or you can process it asynchronously using AWS Lambda. Once the task is added to the queue, the client is immediately informed that the reservation will be confirmed via email. Meanwhile, AWS Lambda will be triggered once the task is added to the queue and it will start processing the reservation.

AWS Lambda can also be used together with EventBridge for periodical scheduling. If you want to clean a table from your database every month, you can do it very easily in an AWS Lambda which is triggered by an EventBridge event.

These are just a couple of examples. AWS Lambda can be triggered by many other subsystems. For the complete list of triggers check the documentation .

When to use genezio?

genezio is a tool tailored for writing, testing and deploying full stack applications on Function-as-a-service infrastructures.

katana

Let’s take them one by one:

  1. Writing: genezio provides a simple and easy-to-use interface for writing API servers. You just have to write regular classes in your preferred programming language, without having to worry about the complexities of handling URLs, HTTP methods, and headers. The tool will also generate a SDK that you can use to make the requests more easily.
  2. Testing: genezio offers a built-in testing framework that allows developers to test their API servers before deployment. Run a simple command and a local server is spawned together with a Postman-like interface. Send requests, look over the logs, find bugs, fix them, and repeat.
  3. Deploying: genezio abstracts away the complexities of deploying on a FaaS infrastructure, making it simple and straightforward for developers by requiring only a simple command “genezio deploy” to be executed.

Write

Now, let’s see how easy it is to write a server with genezio. Below we have an example of a server that exposes a way to save and retrieve articles. That’s it.

export type ArticleResponse = {
  status: String,
  article: Article
}

export class ArticleService {
  constructor() {
    this.#connect();
  }

  #connect() {
    mongoose.connect(MONGO_DB_URI);
  }

  async article(id: string): Promise<ArticleResponse> {
    const article = await Article.find({ id })
    
    return {
      status: "ok",
      article,
    }
  }

  async save(title: string, content: string): Promise<ArticleResponse> {
    const article = await Article.create({ title, content })
    
    return {
      status: "ok",
      article,
    }
}

Test

Let’s test it. Just run the command “genezio local” in the terminal. A process will be spawned that will listen for requests. This command will also generate an SDK that you can use in your client to make requests to the server. Just import the class below in your client code and call the methods.

export type ArticleResponse = {
  status: String,
  article: Article
}  

export class ArticleService {
     static remote = new Remote("http://localhost:8083/")
  
     static async article(id: string): Promise<ArticleResponse>{
          return HelloWorldService.remote.call("HelloWorldService.helloWorld")  
     }

     static async save(title: string, content: string): Promise<ArticleResponse>{
          return HelloWorldService.remote.call("HelloWorldService.helloWorld", title, content) 
     }
}

Deploy

Once you finish testing and you are confident with your code, you can deploy it using the “genezio deploy” command. Your code is now deployed on AWS Lambda, the SDK is regenerated accordingly and your application is ready for production. The nice thing about this auto-generated SDK is that it acts as a documented contract between the server and the clients. You don’t have to communicate the parameters of the ArticleService.article method and the definition of the ArticleResponse type to your front-end colleagues: just generate the SDK and give them the code.

Why use genezio?

A fair question could be: why would I use genezio to deploy on AWS Lambda instead of writing an express.js app and deploy it on AWS EC2? Well, there are a couple of advantages besides the one mentioned above:

  • Your application will scale with traffic without having to do anything (almost anything; you still have to make sure that the database and other third party services that you use will handle the extra workload).
  • You won’t pay anything when your application is idle meaning when there are no incoming requests.

This is great for prototyping applications where you barely have any requests. Moreover, if suddenly your application becomes a success it can scale without effort.

Another cool feature of genezio is the deployment of your frontend application. You have to choose a subdomain <subdomain>.app.genez.io and then run the genezio deploy - -frontend command and your application is online.

Nevertheless, there are also some downsides. The response time could sometimes be higher because of AWS Lambda’s cold start . genezio tries to minimize the cold start by efficiently bundling the code including only the dependencies that the class needs. This bundling feature is important because the code size is one of the important factors that can impact your response time: during cold start a project that has around 200 MB can have a cold start of almost 2 seconds compared to only 400ms for a project that has only a few MBs. Moreover, you can’t have an AWS Lambda that has more than 262 MB package size.

Conclusion

AWS Lambda is an awesome technology that can be used in many different scenarios. Being so flexible also means that it might be hard to learn and get used to it.

genezio, on the other hand, does one thing: it provides an out of the box solution to write and deploy full stack applications.

Whether you’re looking for a versatile serverless computing platform or a specialized solution for API server development, both AWS Lambda and genezio offer unique advantages that can help streamline your workflow and enhance the performance of your applications.