NAV

Aegis

An AWS Serverless Framework for Go

Aegis Variables

Access via Aegis interface

barStr := AegisApp.GetVariable("foo")

Access via HandlerDependencies

func handler(ctx context.Context, d *aegis.HandlerDependencies, req *aegis.APIGatewayProxyRequest, res *aegis.APIGatewayProxyResponse, params url.Values) error {
    barStr := d.GetVariable("foo")
    return nil
}

Access the map directly

func handler(ctx context.Context, d *aegis.HandlerDependencies, req *aegis.APIGatewayProxyRequest, res *aegis.APIGatewayProxyResponse, params url.Values) error {
    if barStr, ok := d.Services.Variables["foo"]; ok {
        // ...
    }
    return nil
}

One of the most important helpers is the one to work with Aegis Variables which is just a conventional environment variable. It could be an actual environment variable on the operating system, an AWS Lambda environment variable that was configured, or an API Gateway stage variable.

So that means the helper function checks those locations in the following order:

The helper function is available on the Aegis interface or HandlerDependencies. A string value is always returned because that’s the only data type these variables can be.

You could also forgo the helper and access these variables on handler dependencies. It’s considered a service. So you’ll find everything under Services.Variables.

Just note that the helper will check for an actual environment variable as a last resort. Accessing the Services in handler dependencies will not include environment variables since this map is set by AWS Lambda and API Gateway configurations.

Note that this works really well in conjunction with the secret CLI command. See here for more info.

API Gateway Proxy (HTTP)

There are quite a few helpers for working with API Gateway Proxy responses and requests. You can read about all of them through Go documentation.

Though let’s take a look at some of the more common ones here.

APIGatewayProxyRequest

API Gateway requests are not HTTP requests. They come into Lambda as JSON messages. The AWS Lambda Go package, and therefore Aegis, marshals these messages to structs. That’s great, but it still doesn’t give us an easy way to work with the request as if though it were an actual HTTP request. If you wanted to get a cookie, it would be rather annoying to be frank.

GetHeader()

auth := req.GetHeader("Authorization")
cookiesString := req.GetHeader("Cookie")

This will return a given header’s value by name. Pretty easy, but you should note that getting the Cookie header isn’t exactly going to be real useful by itself. You’ll need to parse that string. What you’ll get is a string like yummy_cookie=choco; tasty_cookie=strawberry, which isn’t great to then extract the one you’re after.

Cookie() and Cookies()

cookie := req.Cookie("yummy_cookie")
allCookies := req.Cookies()

So this helper function does just that. It mimicks Go’s standard http package. In fact, Go’s standard package was used to create an empty HTTP request with just the cookie header set. That then allows the Cookie() function to be used. So when you call this function, the same exact function is called against Go’s standard library using this fake request that was created.

Obviously then, Cookies() calls the standard HTTP request’s same name function. It returns []*Cookie.

GetBody(), GetJSONBody(), and GetForm()

bodyString, err := req.GetBody()
bodyMap, err := req.GetJSONBody()
formMap, err := req.GetForm()

These helper functions are used for getting the body content of an API Gateway request. One will give you a string while the other will give you a map. It saves you from needing to decode some things.

GetForm() can be helpful if you made a multipart POST request. If will parse the form values and return to you a map[string]interface{}.

UserAgent()

We don’t actually need to parse headers or use GetHeader() just to get the User-Agent, instead there’s simply UserAgent().

IP()

AWS API Gateway will set the requesting client’s IP address as well. So just like getting the User-Agent, you can simply get the IP address using IP(). Both of these values are under req.RequestContext.Identity. So they aren’t hard to get at, but you have to type and remember more.

APIGatewayProxyResponse

There are some great helper functions on the response struct as well. Obviously, these are all about returning data to the client. Things like the HTTP status code, body content, and more.

String(), HTML(), JSON(), JSONP(), XML(), and XMLPretty()

These are your basic body content helpers. They all take a status int value as their first argument. This automatically sets the status rather than requiring you to use SetStatus() or assign the struct property yourself. The second argument will then vary a little.

Some methods will take an interface{} while others, like HTML() and String() will simply take a string. Those taking an interface are going to be doing a little bit of work of course.

Cognito

router.Handle("GET", "/protected", cognitoProtected, aegis.ValidAccessTokenMiddleware)

There’s a Cognito client helper interface which is obviously a lot more involved than a simple function. Then there’s also a smaller middleware helper function called ValidAccessTokenMiddleware.

You can use this middleware like any other middleware with your route handlers. It uses the Cognito client interface’s ParseAndVerifyJWT() function to check a JWT that you’ll need to send in under an access_token cookie in your HTTP request.

You can certainly check out cognito_helpers.go for how that works if you’d like to do something similar on your own.