SkillAgentSearch skills...

Lambdah

A useful abstraction layer over AWS Lambda functions written in Go.

Install / Use

/learn @webbgeorge/Lambdah
About this skill

Quality Score

0/100

Category

Operations

Supported Platforms

Universal

README

lambdah

Godoc CI Coverage Status Go Report Card

lambdah provides a useful abstraction layer over AWS Lambda functions written in Go.

Features:

  • A simple interface for writing lambda functions of all types
  • Extensible middleware framework
  • Data binding for JSON payloads
  • Highly customisable
  • Optional logging and tracing tools via middleware

Installation

lambdah is available as a Go module - import any package under github.com/webbgeorge/lambdah in your project to get started.

Getting started

lambdah has handlers for many types of event. Here are two example handlers for API Gateway Proxy Requests and SQS Messages.

API Gateway Proxy request handler

package main

import (
	"net/http"

	lambdah "github.com/webbgeorge/lambdah/api_gateway_proxy"
)

func main() {
	lambdah.HandlerFunc(handler).Start()
}

// handle http request via API Gateway
func handler(c *lambdah.Context) error {
	return c.String(http.StatusOK, "Hello world!")
}

SQS message handler

package main

import (
	"fmt"

	lambdah "github.com/webbgeorge/lambdah/sqs"
)

func main() {
	lambdah.HandlerFunc(handler).Start()
}

// handle SQS message
func handler(c *lambdah.Context) error {
	// Unmarshal JSON message data into a struct
	var data messageData
	err := c.Bind(&data)
	if err != nil {
		return err
	}

	// just log the name to CloudWatch Logs (via stdout) for the example
	fmt.Println(data.Name)

	return nil
}

type messageData struct {
	Greeting string `json:"greeting"`
	Name     string `json:"name"`
}

More examples

Handler type | Example ----------------- | ----------------- api_gateway_proxy | basic api_gateway_proxy | custom error handler api_gateway_proxy | apitest cloudwatch_events | basic cloudwatch_events | middleware dynamodb | basic dynamodb | middleware generic | basic generic | middleware s3 | basic s3 | middleware sns | basic sns | middleware sqs | basic sqs | middleware

Concepts

Middleware

lambdah provides a middleware system to allow extending the functionality of its handlers. Using middleware on any handler is completely optional.

Each handler includes some default middleware that you can choose to use or not. This includes a CorrelationIDMiddleware and a LoggerMiddleware for all handlers. Some handlers have additional default middleware, such as the api_gateway_proxy.ErrorHandlerMiddleware middleware.

In addition to default middleware, custom middleware can be created using a simple API, described below.

Using middleware

Here is the same simple API Gateway Proxy handler from above, with the addition of two middleware.

package main

import (
	"net/http"
	"os"

	lambdah "github.com/webbgeorge/lambdah/api_gateway_proxy"
)

func main() {
	lambdah.
		HandlerFunc(handler).
		Middleware(
			lambdah.CorrelationIDMiddleware(),
			lambdah.LoggerMiddleware(os.Stdout, nil),
		).
		Start()
}

// handle http request via API Gateway
func handler(c *lambdah.Context) error {
	return c.String(http.StatusOK, "Hello world!")
}

Custom middleware

Here is a simple example of a custom middleware for the API Gateway Proxy handler.

package main

import (
	"fmt"

	lambdah "github.com/webbgeorge/lambdah/api_gateway_proxy"
)

// function which returns our custom middleware
func MyCustomMiddleware() lambdah.Middleware {
	return func(h lambdah.HandlerFunc) lambdah.HandlerFunc {
		return func(c *lambdah.Context) error {
			// just log to CloudWatch Logs (via stdout) for the example
			fmt.Println("middleware triggered")
			return h(c)
		}
	}
}

Default middleware

Handler | Default middleware ----------------- | ------------------ api_gateway_proxy | ErrorHandlerMiddleware, CorrelationIDMiddleware, LoggerMiddleware cloudwatch_events | CorrelationIDMiddleware, LoggerMiddleware dynamodb | CorrelationIDMiddleware, LoggerMiddleware generic | CorrelationIDMiddleware, LoggerMiddleware s3 | CorrelationIDMiddleware, LoggerMiddleware sns | CorrelationIDMiddleware, LoggerMiddleware sqs | CorrelationIDMiddleware, LoggerMiddleware

Binding data

Many of the handler types allow you to bind payload data into a Go data structure.

This includes:

  • API Gateway Proxy request body (from JSON)
  • CloudWatch event detail (from JSON)
  • DynamoDB event images (from DynamoDB attribute map)
  • Generic event payload (from JSON)
  • SNS event data (from JSON)
  • SQS message data (from JSON)

For example, here is an example SNS event handler which binds JSON data:

package main

import (
	"fmt"

	lambdah "github.com/webbgeorge/lambdah/sns"
)

func main() {
	lambdah.HandlerFunc(handler).Start()
}

// handle SNS event
func handler(c *lambdah.Context) error {
	// Unmarshal JSON message data into a struct
	var data messageData
	err := c.Bind(&data)
	if err != nil {
		return err
	}

	// just log the name to CloudWatch Logs (via stdout) for the example
	fmt.Println(data.Name)

	return nil
}

type messageData struct {
	Greeting string `json:"greeting"`
	Name     string `json:"name"`
}

Logging

lambdah provides some built-in logging support using middleware. Logging can be an opinionated matter, so using this is completely optional.

To enable a logger on any type of handler, attach its LoggerMiddleware. This attaches a zerolog logger to the context of each event. Two arguments are required to use the logger middleware:

  • an io.Writer to write log messages to
  • a map[string]string of fields to add to the log data (set to nil if not wanted)
lambdah.
	HandlerFunc(handler).
	Middleware(
		lambdah.LoggerMiddleware(os.Stdout, map[string]string{"logFieldOne": "valueOne"}),
	).
	Start()

The logger middleware will, by default, log the status of each processed event with some basic details about the event. The logger can also be accessed within your handlers and custom middleware.

func handler(c *lambdah.Context) error {
	logger := log.LoggerFromContext(c.Context)
	logger.Info().Msg("hello logs")
	return c.String(http.StatusOK, "Hello world!")
}

Correlation IDs

lambdah provides an optional CorrelationIDMiddleware for all of its handlers. This middleware retrieves or creates a Correlation ID, which is often used for tracing requests through distributed systems in logs. This correlation ID is always a v4 UUID e.g. 9187bcbb-052b-45e5-bffa-99f323a8aa71.

When used in conjunction with the LoggerMiddleware, each log message includes the Correlation ID. Note that the CorrelationIDMiddleware must be included before the LoggerMiddleware.

The Correlation ID can also be accessed from within handlers and custom middleware:

func handler(c *lambdah.Context) error {
	cid := log.CorrelationIDFromContext(c.Context)
	// log correlation id for example
	fmt.Println(cid)
	return c.String(http.StatusOK, "Hello world!")
}

Source of Correlation ID

The handler sources or creates the Correlation ID in different ways depending on its type.

Handler | Correlation ID Source ----------------- | ------------------ api_gateway_proxy | Correlation-Id request header if present, otherwise is created by lambdah cloudwatch_events | CloudWatch Event ID dynamodb | created by lambdah generic | created by lambdah s3 | created by lambdah sns | correlation_id SNS message attribute if present, otherwise is created by lambdah sqs | correlation_id SQS message attribute if present, otherwise is created by lambdah

Contributing

See CONTRIBUTING.md

View on GitHub
GitHub Stars17
CategoryOperations
Updated4y ago
Forks0

Languages

Go

Security Score

80/100

Audited on Aug 28, 2021

No findings