Home

Awesome

<a id="top" name="top"></a>

<p align="center"><b>THIS PROJECT IS DEPRECATED IN FAVOR OF ITS SUCCESSOR<br><a href="https://github.com/aws/aws-lambda-go">aws/aws-lambda-go</a></b></p><br><br>

<img src="asset/logo_powered-by-aws.png" alt="Powered by Amazon Web Services" align="right"> <img src="asset/logo_created-by-eawsy.png" alt="Created by eawsy" align="right">

eawsy/aws-lambda-go-shim

Author your AWS Lambda functions in Go, effectively.

Status License Help Social

AWS Lambda lets you run code without thinking about servers. For now, you can author your AWS Lambda functions, natively, in C#, Java, Node.js and Python. This project provides a native and full-featured shim for authoring your AWS Lambda functions in Go.

<details> <summary><b>Table of Contents</b></summary>

<sub>      generated with DocToc</sub>

<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> <!-- END doctoc generated TOC please keep comment here to allow auto update --> </details>

<img src="asset/misc_arrow-up.png" align="right">

Preview

package main

import "github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"

func Handle(evt interface{}, ctx *runtime.Context) (string, error) {
	return "Hello, World!", nil
}
wget -qO- https://github.com/eawsy/aws-lambda-go-shim/raw/master/src/preview.bash | bash
# "Hello, World!" executed in 0.45 ms

:hatching_chick: If you like the experience, please spread the word!

<img src="asset/misc_arrow-up.png" align="right">

Features

SerializationContextLoggingExceptionsEnvironmentEventsAPI Gateway
OKOKOKOKOKOKOK

<img src="asset/misc_arrow-up.png" align="right">

Performance

DISCLAIMER: We do not intend to compare Go with other languages but to appreciate the overhead of our shim compared to officially supported AWS Lambda languages.

:sunglasses: It is the 2nd fastest way to run an AWS Lambda function and makes the Node.js spawn process technique obsolete.

Benchmark

<img src="asset/misc_arrow-up.png" align="right">

How It Works

<img src="asset/misc_arrow-up.png" align="right">

Quick Hands-On

  1. Requirements

    docker pull eawsy/aws-lambda-go-shim:latest
    go get -u -d github.com/eawsy/aws-lambda-go-core/...
    wget -O Makefile https://git.io/vytH8
    
  2. Code

    package main
    
    import (
      "encoding/json"
    
      "github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
    )
    
    func Handle(evt json.RawMessage, ctx *runtime.Context) (interface{}, error) {
      // ...
    }
    
  3. Build

    make
    
  4. Deploy

    You can use your preferred deployment method by providing it the following configuration:

    • Runtime: python2.7
    • Handler: handler.Handle

    For example, if you deploy your function through the AWS Lambda Management Console, you will have to fill a bunch of parameters like:

    <p align="center"> <img src="asset/aws_config-preview.png" align="center"> </p>

<img src="asset/misc_arrow-up.png" align="right">

Under the Hood

Considering for example the above preview section, we have the following structure:

.
└── preview
    ├── handler.go
    └── Makefile

The handler.go file is where resides the main entrypoint of your AWS Lambda function. There is no restriction on how many files and dependencies you can have, nor on how you must name your files and functions. Nevertheless however we advocate to retain the handler name and to use Handle as the name of your entrypoint.

Let's review the content of handler.go:

1 package main
2 
3 import "github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
4 
5 func Handle(evt interface{}, ctx *runtime.Context) (string, error) {
6 	return "Hello, World!", nil
7 }

<img src="asset/misc_arrow-up.png" align="right">

Main Package

For a seamless experience we leverage Go 1.8 plugins to separate the shim from your code. At run time, AWS Lambda loads our pre-compiled shim which in turn loads your code (your plugin). A plugin is a Go main package and that is why your entrypoint must be in the main package, as seen at line 1. Notice that this restriction only applies to your entrypoint and you are free to organize the rest of your code in different packages.

<img src="asset/misc_arrow-up.png" align="right">

Runtime Context

While your function is executing, it can interact with AWS Lambda to get useful runtime information such as, how much time is remaining before AWS Lambda terminates your function, the AWS request id, etc. This information is passed as the second parameter to your function via the runtime.Context object, as seen at line 5.
With eawsy/aws-lambda-go-core we empower you with a full-featured context object to access any available information in the exact same way that official AWS Lambda runtimes do. This is the only dependency you ever need, as seen in line 3.

<img src="asset/misc_arrow-up.png" align="right">

Get Dependencies

eawsy/aws-lambda-go-core dependency can be retrieved using the well known go get command:

go get -u -d github.com/eawsy/aws-lambda-go-core/...

Go vendoring is also supported out of the box and behaves the same way expected when building usual go projects:

<img src="asset/misc_arrow-up.png" align="right">

Handler Signature

5 func Handle(evt interface{}, ctx *runtime.Context) (string, error) {
6 	return "Hello, World!", nil
7 }

For AWS Lambda being able to call your handler, you have to make it visible outside your plugin, as seen at line 5. There is no other naming restriction but keep in mind that if you change the name of your function, you must also update it in the AWS Lambda configuration.

Tip: Use a variable to expose a handler from the inside of a package:

var Handle = mypackage.MyHandle

For the rest, the handler follows the AWS Lambda programming model by:

<img src="asset/misc_arrow-up.png" align="right">

Logging

In line with the AWS Lambda programming model, one should be able to output logs using standard abilities of the language. Your function can contain logging statements using the official Go log package and AWS Lambda writes theses logs to AWS CloudWatch Logs asynchronously. There is no restriction on how to configure or use the Go log package.

package main

import (
	"log"

	"github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
)

func Handle(evt interface{}, ctx *runtime.Context) (interface{}, error) {
	log.Println("Hello, World!")
	return nil, nil
}

<img src="asset/misc_arrow-up.png" align="right">

Exceptions

In the course of a normal and controlled execution flow, you can notify AWS Lambda an error occurred by returning an error as explained above.
In case of unexpected situations when the ordinary flow of control stops and begins panicking and if you have not any recover mechanism in place, then the stack trace is logged in AWS CloudWatch Logs and AWS Lambda is notified an error occurred.

<img src="asset/misc_arrow-up.png" align="right">

Building

We provide a Docker image based on Amazon Linux container image to build your binary in the exact same environment than AWS Lambda. This image embeds our pre-compiled shim along with helper scripts to package your function. You can use it as such or build your own custom image from it:

docker pull eawsy/aws-lambda-go-shim:latest

Although not strictly required, we also provide an example Makefile to streamline common use cases. You are free to customize, modify and adapt it to your needs. Let's review its content briefly:

HANDLER ?= handler
PACKAGE ?= $(HANDLER)

docker:
  @docker run ...

build:
  @go build ...

pack:
  @pack ...

<img src="asset/misc_arrow-up.png" align="right">

Deployment

The only intent of this project is to provide the most seamless and effective way to run Go on AWS Lambda. We do not provide any sugar and you are free to use your tools of predilection for deployment with the following settings in AWS Lambda:

<img src="asset/misc_arrow-up.png" align="right">

Known Limitations

<img src="asset/misc_arrow-up.png" align="right">

Edge Behaviors

Even if some of these behaviors can be overcome, we mimic the official AWS Lambda runtimes.

<img src="asset/misc_arrow-up.png" align="right">

About

eawsy

This project is maintained and funded by Alsanium, SAS.

We :heart: AWS and open source software. See our other projects, or hire us to help you build modern applications on AWS.

<img src="asset/misc_arrow-up.png" align="right">

Contact

We want to make it easy for you, users and contributers, to talk with us and connect with each others, to share ideas, solve problems and make help this project awesome. Here are the main channels we're running currently and we'd love to hear from you on them.

Twitter

eawsyhq

Follow and chat with us on Twitter.

Share stories!

Gitter

eawsy/bavardage

This is for all of you. Users, developers and curious. You can find help, links, questions and answers from all the community including the core team.

Ask questions!

GitHub

pull requests & issues

You are invited to contribute new features, fixes, or updates, large or small; we are always thrilled to receive pull requests, and do our best to process them as fast as we can.

Before you start to code, we recommend discussing your plans through the eawsy/bavardage channel, especially for more ambitious contributions. This gives other contributors a chance to point you in the right direction, give you feedback on your design, and help you find out if someone else is working on the same thing.

Write code!

<img src="asset/misc_arrow-up.png" align="right">

License

This product is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this product except in compliance with the License. See LICENSE and NOTICE for more information.

<img src="asset/misc_arrow-up.png" align="right">

Trademark

Alsanium, eawsy, the "Created by eawsy" logo, and the "eawsy" logo are trademarks of Alsanium, SAS. or its affiliates in France and/or other countries.

Amazon Web Services, the "Powered by Amazon Web Services" logo, and AWS Lambda are trademarks of Amazon.com, Inc. or its affiliates in the United States and/or other countries.