Permalink
Browse files

Update docs

  • Loading branch information...
mweagle committed Dec 10, 2018
1 parent 384b534 commit 630d34a6e5b3e8ece3abf598e37334709108f8b7
@@ -48,13 +48,13 @@ To use the `APIGatewayEnvelope` type with your own custom request body, create a

```go
type FeedbackBody struct {
Language string `json:"lang"`
Comment string `json:"comment"`
Language string `json:"lang"`
Comment string `json:"comment"`
}
type FeedbackRequest struct {
spartaEvents.APIGatewayEnvelope
Body FeedbackBody `json:"body"`
spartaEvents.APIGatewayEnvelope
Body FeedbackBody `json:"body"`
}
```

@@ -67,46 +67,57 @@ func myLambdaFunction(ctx context.Context, apiGatewayRequest FeedbackRequest) (m
}
```

## Custom HTTP Headers
## API Gateway Response Types

API Gateway supports returning custom HTTP headers whose values are extracted from your response payload.
The API Gateway [response mappings](https://docs.aws.amazon.com/apigateway/latest/developerguide/mappings.html) must make
assumptions about the shape of the Lambda response. The default _application/json_ mapping template is:

Assume your Sparta lambda function returns a JSON struct as in:
{{% import file="./static/source/resources/provision/apigateway/outputmapping_json.vtl" language="nohighlight" %}}

```go
// API response struct
type helloWorldResponse struct {
Location string `json:"location"`
Message string `json:"message"`
This template assumes that your response type has the following JSON shape:

```json
{
"code" : int,
"body" : {...},
"headers": {...}
}
```

To extract the `location` field and promote it to the HTTP `Location` header, you must configure the [response data mappings](http://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html
):
The [apigateway.NewResponse](https://godoc.org/github.com/mweagle/Sparta/aws/apigateway#NewResponse) constructor
is a utility function to produce a canonical version of this response shape. Note that `header` keys must be lower-cased.

To return a different structure change the content-specific mapping templates defined by the
[IntegrationResponse](https://godoc.org/github.com/mweagle/Sparta#IntegrationResponse). See the
[mapping template reference](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html) for more information.

## Custom HTTP Headers

API Gateway supports returning custom HTTP headers whose values are extracted from your response. To return custom HTTP
headers using the default VTL mappings, provide them as the optional third `map[string]string` argument to
[NewResponse](https://godoc.org/github.com/mweagle/Sparta/aws/apigateway#NewResponse) as in:

```go
//
// Promote the location key value to an HTTP header
//
lambdaFn := sparta.HandleAWSLambda(
sparta.LambdaName(helloWorldResponseFunc),
helloWorldResponseFunc,
sparta.IAMRoleDefinition{})
apiGatewayResource, _ := api.NewResource("/hello", lambdaFn)
apiGWMethod, _ := apiGatewayResource.NewMethod("GET", http.StatusOK)
apiGWMethod.Responses[http.StatusOK].Parameters = map[string]bool{
"method.response.header.Location": true,
func helloWorld(ctx context.Context,
gatewayEvent spartaAWSEvents.APIGatewayRequest) (*spartaAPIGateway.Response, error) {
logger, loggerOk := ctx.Value(sparta.ContextKeyLogger).(*logrus.Logger)
if loggerOk {
logger.Info("Hello world structured log message")
}
// Return a message, together with the incoming input...
return spartaAPIGateway.NewResponse(http.StatusOK, &helloWorldResponse{
Message: fmt.Sprintf("Hello world 🌏"),
Request: gatewayEvent,
},
map[string]string{
"X-Response": "Some-value",
}), nil
}
apiGWMethod.Integration.Responses[http.StatusOK].Parameters["method.response.header.Location"] =
"integration.response.body.location"
```

Note that as the `helloWorldResponse` structured type is serialized to the _body_ property of the response, we include that path selector in the _integration.response.body.location_ value.

See the related [AWS Forum thread](https://forums.aws.amazon.com/thread.jspa?threadID=199443).

## Other Resources
* [Walkthrough: API Gateway and Lambda Functions](http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started.html)

* [Walkthrough: API Gateway and Lambda Functions](http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started.html)
* [Use a Mapping Template to Override an API's Request and Response Parameters and Status Codes](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-override-request-response-parameters.html)
@@ -4,7 +4,6 @@ title: Request Context
weight: 12
---


This example demonstrates how to use the `Context` struct provided as part of the [APIGatewayLambdaJSONEvent](https://godoc.org/github.com/mweagle/Sparta#APIGatewayLambdaJSONEvent) event. The [SpartaGeoIP](https://github.com/mweagle/SpartaGeoIP) service will return Geo information based on the inbound request's IP address.

# Define the Lambda Function
@@ -13,15 +12,14 @@ Our function will examine the inbound request, lookup the user's IP address in t

As this function is only expected to be invoked from the API Gateway, we'll unmarshall the inbound event:


```go
import (
spartaAWSEvents "github.com/mweagle/Sparta/aws/events"
spartaAWSEvents "github.com/mweagle/Sparta/aws/events"
)
func ipGeoLambda(ctx context.Context,
apiRequest spartaAWSEvents.APIGatewayRequest) (map[string]interface{}, error) {
parsedIP := net.ParseIP(apiRequest.Context.Identity.SourceIP)
record, err := dbHandle.City(parsedIP)
parsedIP := net.ParseIP(apiRequest.Context.Identity.SourceIP)
record, err := dbHandle.City(parsedIP)
```
@@ -38,11 +36,11 @@ We'll then parse the inbound IP address from the [Context](https://godoc.org/git
Finally, marshal the data or error result and we're done:
```go
requestResponse := map[string]interface{}{
"ip": parsedIP,
"record": record,
}
return requestResponse, nil
requestResponse := map[string]interface{}{
"ip": parsedIP,
"record": record,
}
return requestResponse, nil
```
# Sparta Integration
@@ -60,23 +58,23 @@ These four steps are managed in the service's `main()` function:
////////////////////////////////////////////////////////////////////////////////
// Main
func main() {
stage := sparta.NewStage("ipgeo")
apiGateway := sparta.NewAPIGateway("SpartaGeoIPService", stage)
stackName := "SpartaGeoIP"
stage := sparta.NewStage("ipgeo")
apiGateway := sparta.NewAPIGateway("SpartaGeoIPService", stage)
stackName := "SpartaGeoIP"
var lambdaFunctions []*sparta.LambdaAWSInfo
var lambdaFunctions []*sparta.LambdaAWSInfo
lambdaFn := sparta.HandleAWSLambda(
sparta.LambdaName(ipGeoLambda),
ipGeoLambda,
sparta.IAMRoleDefinition{})
apiGatewayResource, _ := apiGateway.NewResource("/info", lambdaFn)
apiGatewayResource.NewMethod("GET", http.StatusOK)
lambdaFunctions = append(lambdaFunctions, lambdaFn)
sparta.Main(stackName,
"Sparta app supporting ip->geo mapping",
lambdaFunctions,
apiGateway,
apiGatewayResource, _ := apiGateway.NewResource("/info", lambdaFn)
apiGatewayResource.NewMethod("GET", http.StatusOK)
lambdaFunctions = append(lambdaFunctions, lambdaFn)
sparta.Main(stackName,
"Sparta app supporting ip->geo mapping",
lambdaFunctions,
apiGateway,
nil)
}
```
@@ -132,7 +130,6 @@ curl -vs https://qyslujefsf.execute-api.us-west-2.amazonaws.com/ipgeo/info
Pretty-printing the response body:
```json
{
@@ -216,7 +213,6 @@ Pretty-printing the response body:
}
```
Please see the [first example](/reference/apigateway/echo_event/) for more information on the `code`, `status`, and `headers` keys.
# Cleaning Up
@@ -229,5 +225,5 @@ go run main.go delete
# Notes
* The _GeoLite2-Country.mmdb_ content is embedded in the go binary via [esc](https://github.com/mjibson/esc) as part of the [go generate](https://github.com/mweagle/SpartaGeoIP/blob/master/main.go#L27) phase.
* This is a port of Tom Maiaroto's https://github.com/tmaiaroto/go-lambda-geoip implementation.
* The _GeoLite2-Country.mmdb_ content is embedded in the go binary via [esc](https://github.com/mjibson/esc) as part of the [go generate](https://github.com/mweagle/SpartaGeoIP/blob/master/main.go#L27) phase.
* This is a port of Tom Maiaroto's [go-lambda-geoip](https://github.com/tmaiaroto/go-lambda-geoip) implementation.
@@ -24,9 +24,9 @@ Setting the boolean to `true` will add the necessary `OPTIONS` and mock response

Sparta provides two ways to customize the CORS headers available:

* Via the [apigateway.CORSOptions](https://godoc.org/github.com/mweagle/Sparta#CORSOptions) field.
* Customization may use the [S3Site.CloudformationS3ResourceName](https://godoc.org/github.com/mweagle/Sparta#S3Site) to get the _WebsiteURL_ value
so that the CORS origin options can be minimally scoped.
* Via the [apigateway.CORSOptions](https://godoc.org/github.com/mweagle/Sparta#CORSOptions) field.
* Customization may use the [S3Site.CloudformationS3ResourceName](https://godoc.org/github.com/mweagle/Sparta#S3Site) to get the _WebsiteURL_ value so that the CORS origin options can be minimally scoped.

# References
* [API Gateway Docs](http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html)

* [API Gateway Docs](http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html)
Oops, something went wrong.

0 comments on commit 630d34a

Please sign in to comment.