Skip to content

Version 1.x.x Breaking Changes

Tom Maiaroto edited this page Mar 19, 2018 · 7 revisions

Official support for Go in AWS Lambda was announced at AWS Re:Invent 2017 (I was cheering along in the audience) and made its way to GA in early 2018. This radically changed how Aegis worked in terms of the deploy tool and as a function helper.

Along with many changes, the command has changed from up to deploy because it simply makes better sense. Also, the Node.js shim is obviously no longer needed. This makes for a much better experience.

Aside from the deploy tool there is also a "framework" package (been avoiding that label for a long time). This is completely optional to use. You can deploy Go Lambdas with any code you like, but one of the goals of Aegis is convenience. So it includes the same router that it did in earlier versions. There will be much more added.

The original goal here was a set of helpers (mainly the router) to help you write Lambdas faster and more conveniently. It started off as just a simple router for an API Gateway {proxy+} resource, but it's growing into much more. So it also made sense to use the f word. Though it will remain a lightweight, conventional, and optional framework. I'm not a believer in bloated frameworks.

Funny enough, AWS' Lambda Go package has structs that were very similar to Aegis' with regard to API Gateway Proxy Request and Response. So it should be a pretty easy upgrade for your existing functions. There are some struct name changes and other argument changes basically (context).

You can refer to the example you get when running aegis init for more details. It's fairly straight forward but, because of this, there are unfortunately breaking changes. Since we there were breaking changes anyway, the opportunity to rename the package was also taken (and it makes better sense now especially given AWS' own "lambda" package was creating confusion).

The event structs Aegis uses (in the router, tasker, etc.) are simply aliases of AWS' Go Lambda package. They were aliased because Aegis composed some additional functionality onto them (see helpers.go).

The results are fantastic! Go Lambdas are very fast and the invocation error rate issues have vanished. The child process and pipe communication process with the shim wasn't the most reliable. Other approaches to shim Go in to Lambda in the past have included HTTP servers.

Funny enough, this seems to be the approach Amazon took to get Go supported (some sort of tcp listener). It uses lambda.Start(handler) whereas Aegis will use router.Listen() which will ultimately call lambda.Start(handler). This is a blocking call. So in order to handle multiple event types within the same binary, a new handler has been added (which uses a little reflection).

// Assuming router and tasker have been set up with handlers (router handles path based events, tasker handles CloudWatch event name/ID/ARN based events)
handlers := aegis.Handlers{
    Router: router,
    Tasker: tasker
}
handlers.Listen()

If your function only works with API Gateway, then there's not much reason to use this new listener of course. How you design your Lambdas is entirely up to you.

Small note about context

Previously, the Lambda context object (from Node.js) was piped to the Go application you built and received by handlers. This has changed. The way AWS Go Lambda package handles this is through Go's context.Context. In order to get the Lambda context, you need to use Amazon's lambdacontext package. See here: https://docs.aws.amazon.com/lambda/latest/dg/go-programming-model-context.html

import "github.com/aws/aws-lambda-go/lambdacontext"

lc, _ := lambdacontext.FromContext(ctx)
Clone this wiki locally