A ring adapater for use with AWS Lambda and AWS API Gateway.
Develop locally using any ring server, and deploy to AWS Lambda and AWS API Gateway.
This adapter is meant to be used with single lambda function behind multiple AWS API Gateway routes, where routing of the request is done by a ring framework, such as Compojure.
See example/
for a code example and Swagger definition.
Create a lambda function by passing a ring application to
ring-aws-lambda-adapter.core/defhandler
.
For example:
(ns example.lambda
(:require [ring-aws-lambda-adapter.core :refer [defhandler]]
[ring.middleware.params :refer [wrap-params]]
[ring.middleware.keyword-params :refer [wrap-keyword-params]]
[ring.middleware.json :refer [wrap-json-params
wrap-json-response]]
[ring.util.response :as r]
[compojure.core :refer :all]))
(defroutes app
(GET "/" {params :params}
(let [name (get params :name "World")]
(-> (r/response {:message (format "Hello, %s" name)})))))
(defhandler example.lambda.MyLambdaFn (wrap-json-response
(wrap-json-params
(wrap-params
(wrap-keyword-params
app))))
{})
$ lein uberjar
$ aws lambda create-function \
--region eu-west-1 \
--function-name my-lambda-project \
--zip-file fileb://$(pwd)/target/my-lambda-project.jar \
--role arn:aws:iam::YOUR-AWS-ACCOUNT-ID:role/lambda_basic_execution \
--handler example.lambda.MyLambdaFn \
--runtime java8 \
--timeout 15 \
--memory-size 512
Note that the namespace that contains the defhandler
must be AOT compiled.
Create an API Gateway endpoint with the following:
Integration Request
Content-Type: application/json
{
"stage" : "$context.stage",
"request-id" : "$context.requestId",
"api-id" : "$context.apiId",
"resource-path" : "$context.resourcePath",
"resource-id" : "$context.resourceId",
"path": {
#foreach($path in $input.params().path.keySet())
"$path": "$util.escapeJavaScript($input.params().path.get($path))" #if($foreach.hasNext),
#end
#end
},
"http-method" : "$context.httpMethod",
"source-ip" : "$context.identity.sourceIp",
"user-agent" : "$context.identity.userAgent",
"account-id" : "$context.identity.accountId",
"api-key" : "$context.identity.apiKey",
"caller" : "$context.identity.caller",
"user" : "$context.identity.user",
"user-arn" : "$context.identity.userArn",
"query-string": {
#foreach($querystring in $input.params().querystring.keySet())
"$querystring": "$util.escapeJavaScript($input.params().querystring.get($querystring))" #if($foreach.hasNext),#end
#end
},
"headers": {
#foreach($header in $input.params().header.keySet())
"$header": "$util.escapeJavaScript($input.params().header.get($header))" #if($foreach.hasNext),#end
#end
},
"body" : $input.json('$')
}
Method Reponse
Integration Response
Content-Type: application/json
Lambda Error Regex | Method response status | Mapping template |
---|---|---|
200 | $input.json('$.body') | |
.*"status":404.* | 404 | {"error":"Not found"} , or similar |
.+ | 500 | {"error":"Unknown"} , or similar |
/path/{param1}/{param2}
Copyright © 2016 James Brennan
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close