apigo

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 18, 2018 License: MIT Imports: 12 Imported by: 0

README

apigo

Documentation Build Status Go Report Card Exago Exago Exago

Package apigo is an drop-in adapter to AWS Lambda functions (based on go1.x runtime) with a AWS API Gateway to easily reuse logic from serverfull http.Handlers and provide the same experience for serverless function.

Installation

Add apigo dependency using your vendor package manager (i.e. dep) or go get it:

go get -v github.com/piotrkubisa/apigo

Usage

Default behaviour

If you have already registered some http.Handlers, you can easily reuse them with apigo.Gateway. Example below illustrates how to create a hello world serverless application with apigo:

package main

import (
	"log"
	"net/http"

	"github.com/piotrkubisa/apigo"
)

func main() {
	http.HandleFunc("/hello", helloHandler)

	err := apigo.ListenAndServe("", nil)
	if err != nil {
		log.Fatal(err)
	}
}

func helloHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	w.Write([]byte(`"Hello World"`))
}
Custom event-to-request transformation

If you have a bit more sophisticated deployment of your AWS Lambda functions then you probably would love to have more control over event-to-request transformation. Imagine a situation if you have your API in one serverless function and you also have additional custom authorizer in separate AWS Lamda function. In following scenario (presented in example below) context variable provided by serverless authorizer is passed to the API's http.Request context, which can be further inspected during request handling:

package main

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

	"github.com/aws/aws-lambda-go/events"
	"github.com/go-chi/chi"
	"github.com/piotrkubisa/apigo"
)

func main() {
	g := &apigo.Gateway{
		RequestProxy: customTransformation,
		Handler:      routing(),
	}
	err := g.ListenAndServe()
	if err != nil {
		log.Fatal(err)
	}
}

type contextUsername struct{}

var keyUsername = &contextUsername{}

func customTransformation(ctx context.Context, ev events.APIGatewayProxyRequest) (*http.Request, error) {
	r, err := apigo.NewRequest(ctx, ev)
	if err != nil {
		return nil, err
	}
	// Add username to the http.Request's context from the custom authorizer
	r = r.WithContext(
		context.WithValue(
			r.Context(),
			keyUsername,
			ev.RequestContext.Authorizer["username"],
		),
	)
	return r, err
}

func routing() http.Handler {
	r := chi.NewRouter()

	r.Get("/{id}", func(w http.ResponseWriter, r *http.Request) {
		log.Printf("id: %s", chi.URLParam(r, "id"))

		// Remember: headers, status and then payload - always in this order
		// set headers
		w.Header().Set("Content-Type", "application/json")
		// set status
		w.WriteHeader(http.StatusOK)
		// set response payload
		username, _ := r.Context().Value(keyUsername).(string)
		fmt.Fprintf(w, `"Hello %s"`, username)
	})

	return r
}

Credits

Project has been forked from fabulous tj's apex/gateway repository, at 0bee09a.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ListenAndServe

func ListenAndServe(_ string, h http.Handler) error

ListenAndServe is a drop-in replacement for http.ListenAndServe for use within AWS Lambda.

NOTE: First, ignored argument to this function was ignored, because it was left to have the same signature of function, but also to behave as apex/gateway's ListenAndServe.

func NewContext

NewContext populates a context.Context from the http.Request with a request context provided in event from the AWS API Gateway proxy.

func NewRequest

NewRequest returns a new http.Request created from the given Lambda event.

func RequestContext

RequestContext returns the APIGatewayProxyRequestContext value stored in ctx.

Types

type Gateway

type Gateway struct {
	Handler      http.Handler
	RequestProxy RequestTransformer
}

func (*Gateway) ListenAndServe

func (g *Gateway) ListenAndServe() error

ListenAndServe registers a listener of AWS Lambda events.

func (*Gateway) Serve

Serve handles incoming event from AWS Lambda by wraping them into http.Request which is further processed by http.Handler to reply as a APIGatewayProxyResponse.

type RequestBuilder

type RequestBuilder struct {
	Path    string
	URL     *url.URL
	Body    *strings.Reader
	Request *http.Request
	// contains filtered or unexported fields
}

RequestBuilder is an wrapper which helps transforming event from AWS API Gateway as a http.Request.

func NewRequestBuilder

func NewRequestBuilder(ctx context.Context, ev events.APIGatewayProxyRequest) *RequestBuilder

NewRequestBuilder defines new RequestBuilder with context and event data provided from the API Gateway.

func (*RequestBuilder) AttachContext

func (b *RequestBuilder) AttachContext() error

AttachContext attaches events' RequestContext to the http.Request.

func (*RequestBuilder) CreateRequest

func (b *RequestBuilder) CreateRequest() error

CreateRequest provides *http.Request to the RequestBuilder.

func (*RequestBuilder) DefaultTransforms

func (b *RequestBuilder) DefaultTransforms() []Transformer

DefaultTransforms returns a collection of Transformer functions which all used by apigo during event-to-request transformation.

func (*RequestBuilder) ParseBody

func (b *RequestBuilder) ParseBody() error

ParseBody provides body of the request to the RequestBuilder.

func (*RequestBuilder) ParseURL

func (b *RequestBuilder) ParseURL() error

ParseURL provides URL (as a *url.URL) to the RequestBuilder.

func (*RequestBuilder) SetContentLength

func (b *RequestBuilder) SetContentLength() error

SetContentLength sets Content-Length to the request if it has not been set.

func (*RequestBuilder) SetCustomHeaders

func (b *RequestBuilder) SetCustomHeaders() error

SetCustomHeaders sets additional headers from the event's RequestContext to the request.

func (*RequestBuilder) SetHeaderFields

func (b *RequestBuilder) SetHeaderFields() error

SetHeaderFields sets headers to the request.

func (*RequestBuilder) SetRemoteAddr

func (b *RequestBuilder) SetRemoteAddr() error

SetRemoteAddr sets RemoteAddr to the request.

func (*RequestBuilder) SetXRayHeader

func (b *RequestBuilder) SetXRayHeader() error

SetXRayHeader sets AWS X-Ray Trace ID from the event's context.

func (*RequestBuilder) StripBasePath

func (b *RequestBuilder) StripBasePath(basePath string) error

StripBasePath removes a BasePath from the Path fragment of the URL. StripBasePath must be run before RequestBuilder.ParseURL function.

func (*RequestBuilder) Transform

func (b *RequestBuilder) Transform(ts ...Transformer) error

Transform AWS API Gateway event to a http.Request.

type RequestTransformer

type RequestTransformer func(context.Context, events.APIGatewayProxyRequest) (*http.Request, error)

RequestTransformer is a function which transforms an event and context provided from the API Gateway to http.Request.

type ResponseWriter

type ResponseWriter struct {
	// contains filtered or unexported fields
}

ResponseWriter implements the http.ResponseWriter interface in order to support the API Gateway Lambda HTTP "protocol".

func NewResponse

func NewResponse() *ResponseWriter

NewResponse returns a new response writer to capture http output.

func (*ResponseWriter) CloseNotify

func (w *ResponseWriter) CloseNotify() <-chan bool

CloseNotify notify when the response is closed

func (*ResponseWriter) End

End the request.

func (*ResponseWriter) Header

func (w *ResponseWriter) Header() http.Header

Header implementation.

func (*ResponseWriter) Write

func (w *ResponseWriter) Write(b []byte) (int, error)

Write implementation.

func (*ResponseWriter) WriteHeader

func (w *ResponseWriter) WriteHeader(status int)

WriteHeader implementation.

type Transformer

type Transformer func() error

Transformer transforms event from AWS API Gateway to the http.Request.

Jump to

Keyboard shortcuts

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