Building and running serverless applications on Netlify or AWS requires building Rust that targets Amazon Linux.
Since you’re probably not running Amazon Linux as a Desktop, we need to compile for a different target than you’re running on.
Cargo Lambda is a subcommand that helps us with this problem, as well as providing some really useful tools like bootstrapping a Lambda emulation locally.
If you’re on macos you can use homebrew to install, otherwise, find an installation method that works for you on the cargo-lambda installation page.
brew tap cargo-lambda/cargo-lambda
brew install cargo-lambda
cargo lambda allows us to run our function locally to test it with cargo lambda watch
.
❯ cargo lambda watch
INFO invoke server listening on 127.0.0.1:9000
This will run a server that we can send event payloads to, but its important to note that the endpoint for sending curl commands is more complicated than just the host and port. The URL used for curl ends up looking something like this.
curl -XPOST http://127.0.0.1:9000/2015-03-31/functions/serverless-intro-netlify/invocations
We’ll use cargo lambda invoke
instead, which lets us send example payloads using --data-example
. In this case we’re using the apigw-request
example payload.
This will hit our function and run it, returning a response.
❯ cargo lambda invoke serverless-intro-netlify --data-example apigw-request
{
"statusCode": 200,
"headers":
{
"content-type": "text/html"
},
"multiValueHeaders":
{
"content-type":
[
"text/html"
]
},
"body": "<html><body><h1>hello!</h1></body></html>",
"isBase64Encoded": false
}
The event also gets logged out because we used the dbg!
macro.
❯ cargo lambda watch
INFO invoke server listening on 127.0.0.1:9000
INFO starting lambda function function="serverless-intro-netlify" manifest="Cargo.toml"
[Running 'cargo run --bin serverless-intro-netlify']
Compiling serverless-intro-netlify v0.1.0 (/Users/chris/github/rust-adventure/_in-progress/intro-to-serverless-on-netlify)
Finished dev [unoptimized + debuginfo] target(s) in 0.58s
Running `target/debug/serverless-intro-netlify`
[src/main.rs:9] event = Request {
method: POST,
uri: https://gy415nuibc.execute-api.us-east-1.amazonaws.com/testStage/hello/world?name=me,
version: HTTP/1.1,
headers: {
"accept": "*/*",
"accept-encoding": "gzip, deflate",
"cache-control": "no-cache",
"cloudfront-forwarded-proto": "https",
"cloudfront-is-desktop-viewer": "true",
"cloudfront-is-mobile-viewer": "false",
"cloudfront-is-smarttv-viewer": "false",
"cloudfront-is-tablet-viewer": "false",
"cloudfront-viewer-country": "US",
"content-type": "application/json",
"headername": "headerValue",
"host": "gy415nuibc.execute-api.us-east-1.amazonaws.com",
"postman-token": "9f583ef0-ed83-4a38-aef3-eb9ce3f7a57f",
"user-agent": "PostmanRuntime/2.4.5",
"via": "1.1 d98420743a69852491bbdea73f7680bd.cloudfront.net (CloudFront)",
"x-amz-cf-id": "pn-PWIJc6thYnZm5P0NMgOUglL1DYtl0gdeJky8tqsg8iS_sgsKD1A==",
"x-forwarded-for": "54.240.196.186, 54.182.214.83",
"x-forwarded-port": "443",
"x-forwarded-proto": "https",
"x-amzn-trace-id": "Root=1-64cb08f0-8896f434d344f107c7c74ebf;Parent=f72114ba2f13b945;Sampled=1",
},
body: Text(
"{\r\n\t\"a\": 1\r\n}",
),
}
Copy the fixture into a file named fixture.json
in the root of the project for later, and make sure you can use it by using --data-file
.
cargo lambda invoke serverless-intro-netlify --data-file ./fixture.json
We’ll want to modify this json fixture later, but for now let’s continue and deploy our function.