# README
g8
Provides the following utilities to simplify working with AWS lambda and API Gateway.
- Simple handler interface
- HTTP request parsing with JSON support and request body validation
- HTTP response writer with JSON support
- Custom error type with JSON support
- Logging unhandled errors with a stack trace
- Correlation ID
- New Relic integration
Request body parsing
Use the bind method to unmarshal the response body to a struct
type requestBody struct {
Name string `json:"name"`
}
handler := func(c *g8.APIGatewayProxyContext) error {
var b requestBody
err := c.Bind(&b)
if err != nil {
return err
}
...
c.JSON(http.StatusOK, responseBody)
}
Request body validation
Implement the Validate
method on the struct
type requestBody struct {
Name string `json:"name"`
Status string `json:"status"`
}
func (b body) Validate() error {
if b.Status == "" {
return errors.New("status empty")
}
return nil
}
handler := func(c *g8.APIGatewayProxyContext) error {
var b requestBody
err := c.Bind(&b)
if err != nil {
// validation error would be returned here
return err
}
...
c.JSON(http.StatusOK, responseBody)
}
API Gateway Lambda Authorizer Handlers
You are able to define handlers for Lambda Authorizer (previously known as custom authorizers) using g8. Here is an example:
handler := g8.APIGatewayCustomAuthorizerHandlerWithNewRelic(
func(c *APIGatewayCustomAuthorizerContext) error{
c.Response.SetPrincipalID("some-principal-ID")
c.Response.AllowAllMethods()
// other examples:
// c.Response.DenyAllMethods()
// c.Response.AllowMethod(Post, "/pets/*")
return nil
},
g8.HandlerConfig{
...
},
)
lambda.StartHandler(handler)
Response writing
There are several methods provided to simplify writing HTTP responses.
handler := func(c *g8.APIGatewayProxyContext) error {
...
c.JSON(http.StatusOK, responseBody)
}
Errors
Go Errors
Returning Go errors to the error response writer will log the error and respond with an internal server error
handler := func(c *g8.APIGatewayProxyContext) error {
...
return errors.New("something went wrong")
}
Custom Errors
You can return custom g8
errors and also map them to HTTP status codes
handler := func(c *g8.APIGatewayProxyContext) error {
...
return g8.Err{
Status: http.StatusBadRequest,
Code: "SOME_CLIENT_ERROR",
Detail: "Invalid param",
}
}
Writes the following response, with status code 400
{
"code": "SOME_CLIENT_ERROR",
"detail": "Invalid param"
}
Logging stack traces
Unhandled errors are logged automatically with a stack trace if the error is wrapped by eris.
The new version of eris handles errors differently and produce a different JSON response compared to the previous version, additionally all errors now produce a JSON response, please fully test these changes.
eris.Wrapf(err, "failed to send offers to user id: %v", userID)
HTTP Adaptor
In order to facilitate the serving of HTTP and the development of g8.APIGatewayProxyHandler
lambdas, engineers can utilise the NewHTTPHandler
function.
This function is particularly beneficial for local development and pact provider testing, as it assists in verifying that an API provider is adhering to the pacts established by its clients.
By using this feature, engineers can ensure that their API is functioning correctly and meeting the necessary expectations of its users.
Example
g8.NewHTTPHandler(LambdaHandlerEndpoints{
g8.LambdaHandler{
Handler: func(c *g8.APIGatewayProxyContext) error {
c.JSON(http.StatusOK, "success")
return nil
},
Method: http.MethodGet,
PathPattern: "/full/url/path/{var1}/{var2}",
},
g8.LambdaHandler{
Handler: func(c *g8.APIGatewayProxyContext) error {
return errors.New("some error")
},
Method: http.MethodPost,
PathPattern: "/another/full/url/path/{var1}",
},
}, 8080)
Requirements
- Go 1.19+