This is why you should consider using aws-lambda-scala
As time goes on, a micro-library aws-lambda-scala, which appeared as a positive side-effect of experimenting with serverless architecture and researching good ways of using type classes in Scala, gets more attention.
Recently I’ve got a request to explain how does the library compares to Serverless and particularly one of its templates: aws-scala-sbt. And assuming that it can be used with Serverless, how does it help to remove boilerplate from the project. Reflecting on the question and putting myself into the shoes of someone, who is just about to enter the full of misleading marketing terms rabbit hole, I must say that the request is 100% legit and deserves a detailed response.
Serverless framework is defined as “open-source CLI for building serverless architectures”. It helps you with:
- Bootstrapping the project:
serverless create --template aws-scala-sbtwill create
build.sbt, the handler class (more about it further) and
serverless.yml, which basically tells the cloud provider which events should your handler react upon.
- Deploying the lambdas and configuring them on the provider’s end.
That’s it. It doesn’t really care neither about the code, which powers the lambda functions, nor about the way they receive inputs and return outputs. The
serverless create command, which we saw earlier, will generate a handler based on
com.amazonaws.aws-lambda-java-core, which according to the docs:
… supports the following input/output types for a handler:
Simple Java types (AWS Lambda supports the String, Integer, Boolean, Map, and List types);
POJO (Plain Old Java Object) type;
Stream type (If you do not want to use POJOs or if Lambda’s serialization approach does not meet your needs, you can use the byte stream implementation.
It’s clear with the first set: primitive types, cool. Then the POJOS…
AWS Lambda serializes based on standard bean naming conventions (see The Java EE 6 Tutorial). You should use mutable POJOs with public getters and setters.
Let’s skip the streams and take a look at what’s being generated:
In fact, we have two lambda functions here:
ApiGatewayHandler.handleRequest, although only one of them is configured in
serverless.yml. The latter handler is useful when the function is connected with the AWS API Gateway: it allows you to compose the HTTP response, including the status code and the headers, right in the function. In fact
@BeanProperty helps a lot here and allows to use Scala case classes, where AWS expects “POJOs”. However, when you need to maintain some more complex serialization scenarios, you are on your own with “The Java EE 6 Tutorial”, and that’s not fun at all.
When you add aws-lambda-scala to the dependency list, you get (besides a few extra megabytes to the jar size) the full power of Circe by your side. Also the return type of the function changes from
Either[Throwable, R]. Equivalent functions (grouped in a single file) would look like:
Deciding whether adding an extra dependency is more trouble than it’s worth is up to you. There are new features coming up:
- Returning Scala futures;
- More robust proxy responses to indicate a failure (see #12);
- Examples, where having Circe really pays off.
Last, but not least: the library is still young, small and flexible, all contributions are much appreciated and very quickly reacted upon.