Skip to content

Commit 3b5bb64

Browse files
author
Dana H. P'Simer, Jr
committed
initial check-in of aws-api-to-lambda-shim
0 parents  commit 3b5bb64

File tree

9 files changed

+465
-0
lines changed

9 files changed

+465
-0
lines changed

.gitignore

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Created by .ignore support plugin (hsz.mobi)
2+
### Go template
3+
# Compiled Object files, Static and Dynamic libs (Shared Objects)
4+
*.o
5+
*.a
6+
*.so
7+
8+
# Folders
9+
_obj
10+
_test
11+
12+
# Architecture specific extensions/prefixes
13+
*.[568vq]
14+
[568vq].out
15+
16+
*.cgo1.go
17+
*.cgo2.c
18+
_cgo_defun.c
19+
_cgo_gotypes.go
20+
_cgo_export.*
21+
22+
_testmain.go
23+
24+
*.exe
25+
*.test
26+
*.prof
27+
28+
*.zip
29+
.idea
30+
31+
examples/helloWorld/helloWorld

Readme.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# AWS Lambda HTTP Handler Shim
2+
3+
This software is based, in part, on the work done by [eawsy](http://github.com/eawsy/aws-lambda-go/)
4+
Their terrific idea was to use the Python 2.7 runtime available in [AWS Lamnda](https://aws.amazon.com/lambda/)
5+
to run [go](http://golang.com) programs. I was in the midst of creating a new API using [goa](http://goa.design)
6+
and it dawned on me that if I could somehow trick goa into responding to [AWS Api Gateway](https://aws.amazon.com/api-gateway/)
7+
I could have a service that could both run standalone and serverless on API Gateway and Lambnda.
8+
9+
So I created this.
10+
11+
## Usage
12+
13+
For complete details checkout the [helloWorld example](examples/helloWorld)
14+
15+
The basic steps for usage are as follows:
16+
17+
1. separate your configuration of your web service muxer from your call to
18+
http.ListenAndServe.
19+
```golang
20+
package hello
21+
22+
import (
23+
"net/http"
24+
...
25+
)
26+
27+
28+
func InitHandler() (http.Handler, error) {
29+
mux := http.NewServeMux()
30+
mux.HandleFunc("/hello/", func(w http.ResponseWriter, req *http.Request) {
31+
...
32+
})
33+
return mux, nil
34+
}
35+
```
36+
2. Create your main() for your web service:
37+
```go
38+
package main
39+
40+
import (
41+
"github.com/danapsimer/aws-lambda-shim/examples/helloWorld/hello"
42+
"log"
43+
"net/http"
44+
)
45+
46+
func main() {
47+
handler, _ := hello.InitHandler()
48+
log.Fatal(http.ListenAndServe(":8080", handler))
49+
}
50+
```
51+
3. create your main() for your lambda:
52+
```go
53+
package main
54+
55+
import (
56+
"github.com/danapsimer/aws-lambda-shim/examples/helloWorld/hello"
57+
"github.com/danapsimer/aws-lambda-shim/shim"
58+
)
59+
60+
func init() {
61+
shim.NewHttpHandlerShim(hello.InitHandler)
62+
}
63+
64+
func main() {
65+
}
66+
```
67+
4. Make your lambda:
68+
```Makefile
69+
build:
70+
go build -buildmode=c-shared -ldflags="-w -s" -o handler.so
71+
chown `stat -c "%u:%g" .` handler.so
72+
73+
pack:
74+
zip handler.zip handler.so
75+
chown `stat -c "%u:%g" .` handler.zip
76+
```
77+
5. Create your lambda in AWS: (in the directory your lambda handler was built)
78+
```sh
79+
aws lambda create-function \
80+
--function-name hello-world-api \
81+
--runtime python2.7 --handler handler.handle --zip-file fileb://handler.zip \
82+
--role arn:aws:iam::${AWS_ACCOUNT_ID}:role/lambda_basic_execution
83+
```
84+
6. Create your API Gateway API:
85+
```sh
86+
aws apigateway import-rest-api \
87+
--body file://examples/helloWorld/swagger.json --region us-east-1
88+
aws lambda add-permission --region us-east-1 \
89+
--function-name hello-world-api --statement-id 5 \
90+
--principal apigateway.amazonaws.com --action lambda:InvokeFunction \
91+
--source-arn 'arn:aws:execute-api:us-east-1:${AWS_ACCOUNT_ID}:3l3za8xwnd/*/*/*'
92+
```
93+
**NOTE:** you need to replace the '*${AWS_ACCOUNT_ID}*' place holder in
94+
the swagger.json and the aws commands above with your account id.
95+

examples/helloWorld/Readme.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Hello World Example for aws-lambda-shim
2+
3+
This directory contains a simple "Hello, World" webservice that can be
4+
deployed to either AWS Lambda and accessed through AWS Api Gateway or
5+
run standalone as a traditional go HTTP server.

examples/helloWorld/hello/hello.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package hello
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"regexp"
8+
)
9+
10+
var (
11+
helloMatcher = regexp.MustCompile("/hello/(.*)")
12+
)
13+
14+
type greeting struct {
15+
Greeting string `json:"greeting,omitempty"`
16+
}
17+
18+
func InitHandler() (http.Handler, error) {
19+
mux := http.NewServeMux()
20+
mux.HandleFunc("/hello/", func(w http.ResponseWriter, req *http.Request) {
21+
matches := helloMatcher.FindAllStringSubmatch(req.URL.Path, -1)
22+
w.Header().Add("Content-Type", "application/json")
23+
w.WriteHeader(http.StatusOK)
24+
name := matches[0][1]
25+
if name == "" {
26+
name = "World"
27+
}
28+
greeting := greeting{fmt.Sprintf("Hello, %s!", name)}
29+
jsonEncoder := json.NewEncoder(w)
30+
jsonEncoder.Encode(greeting)
31+
})
32+
return mux, nil
33+
}

examples/helloWorld/lambda/Makefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# System build
2+
3+
build:
4+
go build -buildmode=c-shared -ldflags="-w -s" -o handler.so
5+
chown `stat -c "%u:%g" .` handler.so
6+
7+
pack:
8+
zip handler.zip handler.so
9+
chown `stat -c "%u:%g" .` handler.zip
10+
11+
# Docker build for OS X or Windoze
12+
13+
dbuild:
14+
@docker run --rm \
15+
-v $(GOPATH):/go \
16+
-w /go/src/github.com/danapsimer/aws-lambda-shim/examples/helloWorld/lambda \
17+
eawsy/aws-lambda-go make build
18+
19+
dpack:
20+
@docker run --rm \
21+
-v $(GOPATH):/go \
22+
-w /go/src/github.com/danapsimer/aws-lambda-shim/examples/helloWorld/lambda \
23+
eawsy/aws-lambda-go make pack
24+
25+
clean:
26+
@rm -rf handler.zip handler.so
27+
28+
deploy:
29+
@aws lambda update-function-code --function-name hello-world-api --zip-file fileb://handler.zip

examples/helloWorld/lambda/handler.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package main
2+
3+
import (
4+
"github.com/danapsimer/aws-api-to-lambda-shim/examples/helloWorld/hello"
5+
"github.com/danapsimer/aws-api-to-lambda-shim/shim"
6+
)
7+
8+
func init() {
9+
shim.NewHttpHandlerShim(hello.InitHandler)
10+
}
11+
12+
func main() {
13+
}

examples/helloWorld/main.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package main
2+
3+
import (
4+
"github.com/danapsimer/aws-api-to-lambda-shim/examples/helloWorld/hello"
5+
"log"
6+
"net/http"
7+
)
8+
9+
func main() {
10+
handler, _ := hello.InitHandler()
11+
log.Fatal(http.ListenAndServe(":8080", handler))
12+
}

examples/helloWorld/swagger.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"swagger": "2.0",
3+
"info": {
4+
"version": "2016-09-12T17:50:37Z",
5+
"title": "HelloWorldLambdaProxyIntegration"
6+
},
7+
"basePath": "/hello",
8+
"schemes": [
9+
"https"
10+
],
11+
"paths": {
12+
"/{proxy+}": {
13+
"x-amazon-apigateway-any-method": {
14+
"produces": [
15+
"application/json"
16+
],
17+
"parameters": [
18+
{
19+
"name": "proxy",
20+
"in": "path",
21+
"required": true,
22+
"type": "string"
23+
}
24+
],
25+
"responses": {},
26+
"x-amazon-apigateway-integration": {
27+
"uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:${AWS_ACCOUNT_ID}:function:hello-world-api/invocations",
28+
"passthroughBehavior": "when_no_match",
29+
"httpMethod": "POST",
30+
"type": "aws_proxy"
31+
}
32+
}
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)