functions:
create:
handler: todos/create.create
events:
- http:
path: todos
method: post
cors: true
get:
handler: todos/get.get
events:
- http:
path: todos/{id}
method: get
cors: true
update:
handler: todos/update.update
events:
- http:
path: todos/{id}
method: put
cors: true
delete:
handler: todos/delete.delete
events:
- http:
path: todos/{id}
method: delete
cors: true
aws-node-rest-api-with-dynamodb/.serverless> wc -l *.json
15 cloudformation-template-create-stack.json
900 cloudformation-template-update-stack.json
1148 serverless-state.json
2063 total
aws-node-rest-api-with-dynamodb/.serverless> more cloudformation-template-create-stack.json
"CreateLambdaFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": {
"Ref": "ServerlessDeploymentBucket"
},
"S3Key": "serverless/serverless-rest-api-with-dynamodb/dev/1495030572700-2017-05-17T14:16:12.700Z/serverless-rest-api-with-dynamodb.zip"
},
"FunctionName": "serverless-rest-api-with-dynamodb-dev-create",
"Handler": "todos/create.create",
"MemorySize": 1024,
"Role": {
"Fn::GetAtt": [
"IamRoleLambdaExecution",
"Arn"
]
},
"Runtime": "nodejs6.10",
"Timeout": 6
},
"DependsOn": [
"CreateLogGroup",
"IamRoleLambdaExecution"
]
},
service: sls-messages-${env:ENV}
provider:
name: aws
runtime: nodejs6.10
region: ${env:AWS_REGION}
# separate deployment stage concept
stage: ${env:ENV}
profile: ${env:AWS_PROFILE}
functions:
messagesHandler:
handler: src/handler.messagesHandler
environment:
# configuration using Environment variables
DB_HOST: ${env:DATABASE}
DB_USER: ${env:DB_USER}
DB_PASS: ${env:DB_PASS}
# event sourcing from both API Gateway and Kinesis
events
- http: POST messages
- stream:
type: kinesis
arn:
Fn::ImportValue: ${env:MESSAGE_KINESIS_ARN}
# compatible with CloudFormation yml for
# for more complex Resource dependencies
resources:
Resources:
TodosDynamoDbTable:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
-
AttributeName: id
AttributeType: S
KeySchema:
-
AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.DYNAMODB_TABLE}
# Automatic API Gateway provisioning
functions:
events
- http: POST
Code and Infrastructure all packaged into Immutable Artifact
Configured by Env Vars
service: sls-step-up
provider:
name: aws
runtime: nodejs6.10
plugins:
- serverless-step-functions
stepFunctions:
stateMachines:
Function1:
...
Function2:
...
activities:
- myTask
- yourTask
provider:
name: google
plugins:
- serverless-google-cloudfunctions
provider:
name: aws
provider:
name: azure
plugins:
- serverless-azure-functions
provider:
name: openwhisk
Framework | Provider | Language | Infrastructure Management |
---|---|---|---|
Apex | AWS | Node Golang |
None - Terraform Lambda only |
GoSparta | AWS | Golang | Poor - Raw Cloudformation |
Serverless | AWS Azure Openwhisk |
Python Node Java .Net (Golang*) |
Great! - CF compatible custom yml - Neatly defines big picture EDA |
Amaysim/Trineo compared several frameworks for Function + API Gateway + Events. Easy Infrastructure Management is crucial
# already have node, golang docker and make
>
> npm install -g serverless
>
> serverless install -u https://github.com/yunspace/serverless-golang/tree/master/aws/event -n sls-golang-event
>
> cd sls-golang-event
> make package
> serverless deploy
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
......................
Serverless: Stack update finished...
Service Information
service: sls-golang-event
stage: dev
region: ap-southeast-2
api keys:
None
endpoints:
POST - https://XXXXXXX.execute-api.ap-southeast-2.amazonaws.com/dev/raw
POST - https://XXXXXXX.execute-api.ap-southeast-2.amazonaws.com/dev/http
functions:
raw: sls-golang-event-dev-raw
http: sls-golang-event-dev-http
import (
"encoding/json"
"github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
)
func HandleRaw(evt *json.RawMessage, ctx *runtime.Context) (interface{}, error) {
...
}
import (
"github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
"github.com/eawsy/aws-lambda-go-event/service/lambda/runtime/event/apigatewayproxyevt"
)
func HandleHTTP(evt *apigatewayproxyevt.Event, ctx *runtime.Context) (interface{}, error) {
...
}
import (
"github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
"github.com/eawsy/aws-lambda-go-event/service/lambda/runtime/event/kinesisstreamsevt"
)
func HandleKinesis(evt kinesisstreamsevt.Event, ctx *runtime.Context) (interface{}, error) {
...
}
# already have node, golang docker and make
>
> npm install -g serverless
>
> serverless install -u https://github.com/yunspace/serverless-golang/tree/master/aws/net -n sls-golang-net
>
> cd sls-golang-net
> make package
> serverless deploy
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..................
Serverless: Stack update finished...
Service Information
service: sls-golang-net
stage: dev
region: ap-southeast-2
api keys:
None
endpoints:
POST - https://XXXXXXX.execute-api.ap-southeast-2.amazonaws.com/dev/todos
GET - https://XXXXXXX.execute-api.ap-southeast-2.amazonaws.com/dev/todos
GET - https://XXXXXXX.execute-api.ap-southeast-2.amazonaws.com/dev/todos/{id}
PUT - https://XXXXXXX.execute-api.ap-southeast-2.amazonaws.com/dev/todos/{id}
DELETE - https://XXXXXXX.execute-api.ap-southeast-2.amazonaws.com/dev/todos/{id}
functions:
crud: sls-golang-net-dev-crud
Serverless: Removing old service versions...
// Set up the Handler to be exported to AWS Lambda
var Handler apigatewayproxy.Handler
func init() {
Handler = NewHandler()
}
func NewHandler() apigatewayproxy.Handler {
ln := net.Listen()
// Amazon API Gateway Binary support out of the box.
handle := apigatewayproxy.New(ln, nil).Handle
// Any Go framework complying with http.Handler can be used. I.e. Gorilla Mux
r := mux.NewRouter()
r.HandleFunc("/todos", list).Methods(http.MethodGet)
go http.Serve(ln, r)
return handle
}
// Handle the Request as per standard go/net HTTP code
func list(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Powered-By", "serverless-golang")
fmt.Fprintf(w, "%d - Listing All", http.StatusOK)
}