aws-lambda-go-middleware

module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 14, 2025 License: MIT

README

AWS Lambda Go Middleware

Go Reference

aws-lambda-go-middleware is a library that provides net/http style middleware functionality for AWS Lambda Go handlers (handling events.APIGatewayProxyRequest). It allows you to modularize request preprocessing, response postprocessing, error handling, etc., and apply them to handlers as reusable components.

Installation

go get github.com/nakat-t/aws-lambda-go-middleware/middleware

Core Concepts

HandlerFunc

A function type that represents the signature of an AWS Lambda API Gateway Proxy integration handler. This is the ultimate target of the middleware chain.

type HandlerFunc func(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)
MiddlewareFunc

A function type that takes a HandlerFunc and returns a new HandlerFunc. Functions that implement this become middleware.

type MiddlewareFunc func(next HandlerFunc) HandlerFunc
Use

A function to apply middleware to a HandlerFunc.

// Apply middleware m1, m2, m3 to handler h
wrappedHandler := middleware.Use(h, m1, m2, m3)
// Execution order: m1 -> m2 -> m3 -> h -> m3 -> m2 -> m1

Usage

package main

import (
	"context"
	"log"
	"net/http"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
	"github.com/nakat-t/aws-lambda-go-middleware/middleware"
	"github.com/nakat-t/aws-lambda-go-middleware/middleware/requestid"
	"github.com/nakat-t/aws-lambda-go-middleware/middleware/contenttype"
)

// Actual business logic
func myHandler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	reqID := ctx.Value(requestid.CtxKey{}).(string)
	log.Printf("Processing request: %s", reqID)
	// ... business logic ...
	return events.APIGatewayProxyResponse{
		StatusCode: http.StatusOK,
		Headers:    map[string]string{
			"Content-Type": "application/json",
		},
		Body: request.Body,
	}, nil
}

func main() {
    // Add request ID to context
	m1 := requestid.RequestID()
	// Allow only application/json
	m2 := contenttype.AllowContentType([]string{"application/json"})

	// Apply chain to handler
	wrappedHandler := middleware.Use(myHandler, m1, m2)

	// Start Lambda
	lambda.Start(wrappedHandler)
}

Provided Middleware

AllowContentType

Validates that the request's Content-Type header is included in the specified allowlist.

Signature:

func AllowContentType(contentTypes []string, opts ...Option) middleware.MiddlewareFunc

Options:

// Customize the response Content-Type header and body returned when Content-Type is not allowed.
func WithResponse(contentType string, body string) Option

Comparison Rules:

  • Only compares the media type part (e.g., application/json matches application/json; charset=utf-8).
  • Comparison is case-insensitive.
  • Returns 415 Unsupported Media Type if the Content-Type header does not exist or is not in the allowlist.

Sample Code

For a runnable sample code that includes examples of using RequestID and AllowContentType, refer to the examples/middleware directory in the repository.

# Run from the repository root directory
go run examples/middleware/main.go
RequestID, ExtendedRequestID

Extract the request ID (RequestContext.RequestID) or the extended request ID (RequestContext.ExtendedRequestID) from the API Gateway request context and set it to context.Context. Subsequent middleware and handlers can retrieve this ID using the CtxKey key.

Signature:

func RequestID(opts ...Option) middleware.MiddlewareFunc

Options:

// WithCtxKey specifies the key of the request ID to be set in the context.
func WithCtxKey(ctxKey any) Option
StructuredLogger

Creates middleware that logs request and response information using structured logging with log/slog. Requests are automatically recorded before the handler is executed, and responses, execution times, and errors are automatically recorded after the handler is executed.

Signature:

func StructuredLogger(opts ...Option) middleware.MiddlewareFunc

Options:

// WithLogger sets a custom logger for the StructuredLogger middleware.
func WithLogger(logger *slog.Logger) Option

// WithRequestBodyLogging enables or disables request body logging in the middleware.
// By default, logging is disabled.
func WithRequestBodyLogging(enable bool) Option

// WithResponseBodyLogging enables or disables response body logging in the middleware.
// By default, logging is disabled.
func WithResponseBodyLogging(enable bool) Option
Validate

This is middleware that validates the request body using the github.com/go-playground/validator/v10 package. It unmarshals the request body into a variable of type T, performs validation, and if the validation passes, sets it to the context. If there is an error, it returns 400 Bad Request.

Signature:

func Validate[T any](opts ...Option) middleware.MiddlewareFunc

Options:

// WithCtxKey specifies the key of the unmarshaled request value to be set in the context.
func WithCtxKey(ctxKey any) Option

// Customize the response Content-Type header and body returned when validation error.
func WithResponse(contentType string, body string) Option

License

This project is released under the license defined in the LICENSE file.

Directories

Path Synopsis
examples
middleware command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL