ridgenative

package module
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Feb 6, 2024 License: MIT Imports: 19 Imported by: 5

README

Build Status GoDoc

ridgenative

AWS Lambda HTTP Proxy integration event bridge to Go net/http. fujiwara/ridge is a prior work, but it depends on Apex. I want same one that only depends on aws/aws-lambda-go.

SYNOPSIS

package main

import (
	"fmt"
	"net/http"

	"github.com/shogo82148/ridgenative"
)

func main() {
	http.HandleFunc("/hello", handleRoot)
	ridgenative.ListenAndServe(":8080", nil)
}

func handleRoot(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain")
	fmt.Fprintln(w, "Hello World")
}
Run Locally

You can run it locally.

$ go run main.go
$ curl http://localhost:8080/hello
Hello World
Amazon API Gateway REST API with HTTP proxy integration

You can run it as an Amazon API Gateway REST API without any modification of the source code. Here is an example of AWS Serverless Application Model template template. See the example directory to how to deploy it.

AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::Serverless-2016-10-31"
Description: example of shogo82148/ridgenative
Resources:
  ExampleApi:
    Type: AWS::Serverless::Function
    Properties:
      Handler: example
      Runtime: provided.al2
      Timeout: 30
      CodeUri: dist
      Events:
        Proxy:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: any
Amazon API Gateway HTTP API

You can also run it as an Amazon API Gateway HTTP API.

AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::Serverless-2016-10-31"
Description: example of shogo82148/ridgenative
Resources:
  ExampleApi:
    Type: AWS::Serverless::Function
    Properties:
      Handler: example
      Runtime: provided.al2
      Timeout: 30
      CodeUri: dist
      Events:
        ApiEvent:
          Type: HttpApi
Targets of Application Load Balancer

More and more, you can run it as a target of Application Load Balancer.

AWSTemplateFormatVersion: "2010-09-09"

Resources:
  Function:
    Type: AWS::Lambda::Function
    Properties:
      Code: dist
      Handler: example
      Role: !GetAtt ExecutionRole.Arn
      Runtime: provided.al2
      Timeout: 30

  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: "/"
      Policies:
        - PolicyName: CloudWatchLogs
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"

  LambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref Function
      Principal: elasticloadbalancing.amazonaws.com

  LambdaTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      TargetType: lambda
      Targets:
        - Id: !Att Function.Arn
# Configure listener rules of ALB to forward to the LambdaTargetGroup.
# ...
Lambda function URLs

More and more, you can run it as Lambda function URLs.

AWSTemplateFormatVersion: "2010-09-09"

Resources:
  Function:
    Type: AWS::Lambda::Function
    Properties:
      Code: dist
      Handler: example
      Role: !GetAtt ExecutionRole.Arn
      Runtime: provided.al2
      Timeout: 30

  LambdaUrls:
    Type: AWS::Lambda::Url
    Properties:
      AuthType: NONE
      TargetFunctionArn: !GetAtt Function.Arn

  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: "/"
      Policies:
        - PolicyName: CloudWatchLogs
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"
Lambda function URLs with a Response Streaming Enabled Function

The ridgenative also works with a response streaming enabled function. To enable response streaming, set the RIDGENATIVE_INVOKE_MODE environment value to RESPONSE_STREAM.

AWSTemplateFormatVersion: "2010-09-09"

Resources:
  Function:
    Type: AWS::Lambda::Function
    Properties:
      Code: dist
      Handler: example
      Role: !GetAtt ExecutionRole.Arn
      Runtime: provided.al2
      Timeout: 30

      # configure environment values to enable response streaming
      Environment:
        Variables:
          RIDGENATIVE_INVOKE_MODE: RESPONSE_STREAM

  LambdaUrls:
    Type: AWS::Lambda::Url
    Properties:
      AuthType: NONE
      TargetFunctionArn: !GetAtt Function.Arn
      InvokeMode: RESPONSE_STREAM # enables response streaming

  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: "/"
      Policies:
        - PolicyName: CloudWatchLogs
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"

With a response streaming enabled function, the ResponseWriter implements http.Flusher.

package main

import (
	"fmt"
	"net/http"

	"github.com/shogo82148/ridgenative"
)

func main() {
	http.HandleFunc("/hello", handleRoot)
	ridgenative.ListenAndServe(":8080", nil)
}

func handleRoot(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain")
	fmt.Fprintln(w, "Hello World")

	f := w.(http.Flusher)
  f.Flush()
}

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ListenAndServe

func ListenAndServe(address string, mux http.Handler) error

ListenAndServe starts HTTP server.

If AWS_LAMBDA_RUNTIME_API environment value is defined, it wait for new AWS Lambda events and handle it as HTTP requests. The format of the events is compatible with Amazon API Gateway Lambda proxy integration and Application Load Balancers. See AWS documents for details.

https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html

https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html

If AWS_EXECUTION_ENV environment value is AWS_Lambda_go1.x, it returns an error. If AWS_LAMBDA_RUNTIME_API environment value is NOT defined, it just calls http.ListenAndServe.

The handler is typically nil, in which case the DefaultServeMux is used.

If AWS_LAMBDA_RUNTIME_API environment value is defined, ListenAndServe uses it as the invoke mode. The default is InvokeModeBuffered.

Example
package main

import (
	"fmt"
	"io"
	"net/http"
	"time"

	"github.com/shogo82148/ridgenative"
)

func main() {
	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/plain")
		fmt.Fprintln(w, "Hello World")
	})
	go ridgenative.ListenAndServe(":8080", nil)
	time.Sleep(time.Second) // wait for starting the server.

	resp, err := http.Get("http://localhost:8080/hello")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	b, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(b))

}
Output:

Hello World

func Start added in v1.4.0

func Start(mux http.Handler, mode InvokeMode) error

Start starts the AWS Lambda function. The handler is typically nil, in which case the DefaultServeMux is used.

Types

type InvokeMode added in v1.4.0

type InvokeMode string

InvokeMode is the mode that determines which API operation Lambda uses.

const (
	// InvokeModeBuffered indicates that your function is invoked using the Invoke API operation.
	// Invocation results are available when the payload is complete.
	InvokeModeBuffered InvokeMode = "BUFFERED"

	// InvokeModeResponseStream indicates that your function is invoked using
	// the InvokeWithResponseStream API operation.
	// It enables your function to stream payload results as they become available.
	InvokeModeResponseStream InvokeMode = "RESPONSE_STREAM"
)

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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