-
Notifications
You must be signed in to change notification settings - Fork 0
/
apiGateway.go
114 lines (89 loc) · 3.45 KB
/
apiGateway.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package lambda
import (
"context"
"encoding/base64"
"encoding/json"
"net/http"
"github.com/aws/aws-lambda-go/events"
"alox.sh"
)
type APIGatewayHandler func(*APIGateway, context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)
type APIGateway struct {
*Lambda
handler APIGatewayHandler
}
func NewAPIGateway(handler APIGatewayHandler) (apiGateway *APIGateway) {
apiGateway = &APIGateway{Lambda: NewLambda(apiGateway.lambdaHandler)}
apiGateway.SetHandler(handler)
apiGateway.Server.SetHandler(apiGateway.httpHandler)
return apiGateway
}
func (apiGateway *APIGateway) lambdaHandler(lambda *Lambda, context context.Context, request []byte) (response []byte, err error) {
var (
eventRequest = events.APIGatewayProxyRequest{}
eventResponse events.APIGatewayProxyResponse
)
if err = json.Unmarshal(request, &eventRequest); err != nil {
return
}
if eventResponse, err = apiGateway.handler(apiGateway, context, eventRequest); err != nil {
return
}
return json.Marshal(eventResponse)
}
func (apiGateway *APIGateway) httpHandler(_ alox.Server, responseWriter http.ResponseWriter, request *http.Request) {
apiGatewayRequest := events.APIGatewayProxyRequest{
// Resource string `json:"resource"` // The resource path defined in API Gateway
// Path string `json:"path"` // The url path for the caller
HTTPMethod: request.Method,
Headers: map[string]string{},
MultiValueHeaders: map[string][]string{},
// QueryStringParameters map[string]string `json:"queryStringParameters"`
// MultiValueQueryStringParameters map[string][]string `json:"multiValueQueryStringParameters"`
// PathParameters map[string]string `json:"pathParameters"`
// StageVariables map[string]string `json:"stageVariables"`
// RequestContext APIGatewayProxyRequestContext `json:"requestContext"`
// Body string `json:"body"`
// IsBase64Encoded bool `json:"isBase64Encoded,omitempty"`
}
for key, values := range request.Header {
switch len(values) {
case 0:
apiGatewayRequest.Headers[key] = ""
case 1:
apiGatewayRequest.Headers[key] = values[0]
default:
apiGatewayRequest.MultiValueHeaders[key] = values
}
}
// TODO: finish
apiGatewayResponse, err := apiGateway.handler(apiGateway, request.Context(), apiGatewayRequest)
if err != nil {
apiGateway.HandleError(responseWriter, request, err)
return
}
header := responseWriter.Header()
for key, value := range apiGatewayResponse.Headers {
header.Set(key, value)
}
for key, values := range apiGatewayResponse.MultiValueHeaders {
for _, value := range values {
header.Add(key, value)
}
}
responseWriter.WriteHeader(apiGatewayResponse.StatusCode)
if apiGatewayResponse.IsBase64Encoded {
buffer := make([]byte, base64.StdEncoding.DecodedLen(len(apiGatewayResponse.Body)))
if _, err = base64.StdEncoding.Decode(buffer, []byte(apiGatewayResponse.Body)); err != nil {
apiGateway.HandleError(responseWriter, request, err)
return
}
responseWriter.Write(buffer)
return
}
responseWriter.Write([]byte(apiGatewayResponse.Body))
}
func (apiGateway *APIGateway) SetHandler(handler APIGatewayHandler) *APIGateway {
apiGateway.handler = handler
return apiGateway
}