algnhsa

repository·master·Indexed 18 days ago

https://github.com/akrylysov/algnhsa

A Go adapter that translates AWS Lambda events into standard HTTP requests, allowing net/http web applications and frameworks such as Gin, Echo, Chi, and Fiber to run on AWS Lambda, API Gateway, or Application Load Balancer (ALB) without modifying existing handlers.

Tokens
4.2K
Snippets
18
Records
23
Agent score
64%

What's inside algnhsa

  1. Overview of algnhsa

    master
    algnhsa is an AWS Lambda Go net/http server adapter. It allows you to run existing Go web applications on AWS Lambda, API Gateway, or ALB without modifying your existing net/http handlers. It acts as a bridge between the Lambda event structure and the standard Go http.Handler interface.
  2. Deploy to AWS Lambda Function URL

    master
    The simplest way to expose your Lambda function as an HTTP endpoint is to use Lambda Function URLs. In the Lambda console, go to the "Function URL" section of your function configuration and click "Configure Function URL".
  3. Build and package for AWS Lambda

    master

    To deploy to AWS Lambda, build your application for Linux using the lambda.norpc build tag and name the output bootstrap. Then, zip the bootstrap binary.

    GOOS=linux GOARCH=amd64 go build -tags lambda.norpc -o bootstrap
    zip function.zip bootstrap

    When configuring the Lambda function in AWS:

    • Use the "Provide your own bootstrap on Amazon Linux 2" runtime (or "Custom runtime on Amazon Linux 2").
    • Set the handler name to bootstrap.
    • Ensure the executable name is bootstrap.
  4. Deploy to AWS Application Load Balancer (ALB)

    master

    To use an ALB with your Lambda function:

    1. Create a new ALB and point it to your Lambda function.
    2. In the Target Group settings, under the "Attributes" section, enable "Multi value headers".
  5. Deploy to AWS API Gateway

    master

    You can expose your Lambda function via API Gateway using either HTTP APIs or REST APIs.

    HTTP API

    1. Create a new HTTP API.
    2. Configure a catch-all $default route.

    REST API

    1. Create a new REST API.
    2. In the "Resources" section, create a new ANY method for the / path and enable "Use Lambda Proxy Integration".
    3. Add a catch-all {proxy+} resource to handle all other paths and enable "Configure as proxy resource".
  6. Integrate algnhsa with echo

    master

    To use echo with algnhsa, pass the echo instance directly to algnhsa.ListenAndServe.

    package main
    
    import (
    	"net/http"
    
    	"github.com/akrylysov/algnhsa"
    	"github.com/labstack/echo/v4"
    )
    
    func main() {
    	e := echo.New()
    	e.GET("/", func(c echo.Context) error {
    		return c.String(http.StatusOK, "hi")
    	})
    	algnhsa.ListenAndServe(e, nil)
    }
  7. Integrate algnhsa with Fiber

    master

    To use Fiber with algnhsa, you must first wrap the Fiber app using the Fiber adaptor.FiberApp function, then pass the resulting http.Handler to algnhsa.ListenAndServe.

    package main
    
    import (
    	"github.com/akrylysov/algnhsa"
    	"github.com/gofiber/fiber/v2"
    	"github.com/gofiber/fiber/v2/middleware/adaptor"
    )
    
    func main() {
    	app := fiber.New()
    	app.Get("/", func(c *fiber.Ctx) error {
    		return c.SendString("Hello, World!")
    	})
    	algnhsa.ListenAndServe(adaptor.FiberApp(app), nil)
    }
  8. Integrate algnhsa with chi

    master

    To use chi with algnhsa, pass the chi router instance directly to algnhsa.ListenAndServe.

    package main
    
    import (
    	"net/http"
    
    	"github.com/akrylysov/algnhsa"
    	"github.com/go-chi/chi"
    )
    
    func main() {
    	r := chi.NewRouter()
    	r.Get("/", func(w http.ResponseWriter, r *http.Request) {
    		w.Write([]byte("hi"))
    	})
    	algnhsa.ListenAndServe(r, nil)
    }
  9. Integrate algnhsa with Gin

    master

    To use Gin with algnhsa, pass the Gin engine instance directly to algnhsa.ListenAndServe.

    package main
    
    import (
    	"net/http"
    
    	"github.com/akrylysov/algnhsa"
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("/", func(c *gin.Context) {
    		c.JSON(http.StatusOK, gin.H{
    			"message": "hi",
    		})
    	})
    	algnhsa.ListenAndServe(r, nil)
    }
  10. Use algnhsa with standard net/http

    master

    To use algnhsa with the standard library, use algnhsa.ListenAndServe and pass your http.Handler (such as http.DefaultServeMux). You can also access AWS-specific event data (like API Gateway V2 request context) by using algnhsa.APIGatewayV2RequestFromContext(r.Context()) within your handlers.

    package main
    
    import (
    	"fmt"
    	"net/http"
    	"strconv"
    
    	"github.com/akrylysov/algnhsa"
    )
    
    func addHandler(w http.ResponseWriter, r *http.Request) {
    	f, _ := strconv.Atoi(r.FormValue("first"))
    	s, _ := strconv.Atoi(r.FormValue("second"))
    	w.Header().Set("X-Hi", "foo")
    	fmt.Fprintf(w, "%d", f+s)
    }
    
    func contextHandler(w http.ResponseWriter, r *http.Request) {
    	lambdaEvent, ok := algnhsa.APIGatewayV2RequestFromContext(r.Context())
    	if ok {
    		fmt.Fprint(w, lambdaEvent.RequestContext.AccountID)
    	}
    }
    
    func main() {
    	http.HandleFunc("/add", addHandler)
    	http.HandleFunc("/context", contextHandler)
    	algnhsa.ListenAndServe(http.DefaultServeMux, nil)
    }
  11. Configure algnhsa using the Options struct

    master

    The Options struct allows you to customize how algnhsa handles incoming requests, specifically regarding request type detection, binary content handling, and path construction.

    Key configuration fields:

    • RequestType: Specifies the expected request type. If not set (defaults to RequestTypeAuto), algnhsa attempts to deduce the type from the Lambda payload.
    • BinaryContentTypes: A list of MIME types (e.g., application/octet-stream) that should be treated as binary.
    • BinaryContentEncodings: A list of content encodings (e.g., gzip) that should be treated as binary.
    • UseProxyPath: When set to true, algnhsa uses the API Gateway PathParameters ["proxy"] to construct the request URL. This is useful for stripping base path mappings when using custom domains with API Gateway.
    • DebugLog: Enables printing request and response objects to stdout for debugging purposes.
    import "github.com/akrylysov/algnhsa"
    
    opts := &algnhsa.Options{
    	RequestType:          algnhsa.RequestTypeAPIGatewayV2,
    	BinaryContentTypes:   []string{"application/octet-stream"},
    	BinaryContentEncodings: []string{"gzip"},
    	UseProxyPath:         true,
    	DebugLog:             true,
    }
  12. Troubleshoot ALB request errors

    master

    When working with ALB integration, you may encounter the following errors if the incoming payload does not match the expected AWS ALB Target Group format:

    • errALBUnexpectedRequest: The payload was not a valid ALBTargetGroupRequest event (specifically, the TargetGroupArn was empty).
    • errALBExpectedMultiValueHeaders: The request did not contain multi-value headers. To fix this, you must enable Multi-value headers in your ALB Target Group settings in the AWS Console.