Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http-dynamodb example #562

Merged
merged 10 commits into from Nov 8, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 24 additions & 0 deletions examples/http-dynamodb/Cargo.toml
@@ -0,0 +1,24 @@
[package]
name = "http-dynamodb"
version = "0.1.0"
edition = "2021"


# Use cargo-edit(https://github.com/killercup/cargo-edit#installation)
# to manage dependencies.
# Running `cargo add DEPENDENCY_NAME` will
# add the latest version of a dependency to the list,
# and it will keep the alphabetic ordering for you.

[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
lambda_http = { path = "../../lambda-http" }
lambda_runtime = { path = "../../lambda-runtime" }
aws-sdk-dynamodb = "0.21.0"
aws-config = "0.51.0"
tokio = { version = "1", features = ["macros"] }
tracing = { version = "0.1.37"}
tracing-subscriber = { version = "0.3", features = ["env-filter"] }


19 changes: 19 additions & 0 deletions examples/http-dynamodb/README.md
@@ -0,0 +1,19 @@
# AWS Lambda Function example

## Build & Deploy

1. Install [cargo-lambda](https://github.com/cargo-lambda/cargo-lambda#installation)
2. Build the function with `cargo lambda build --release`
3. Deploy the function to AWS Lambda with `cargo lambda deploy --iam-role YOUR_ROLE`

## Build for ARM 64

Build the function with `cargo lambda build --release --arm64`

Setting up Dynamodb

1. Log into your account.
2. Create a Dynamodb table with the name 'lambda_dyno_example' with the partition key of "username".
3. Create IAM role with the permissions for Lambda, Cloudwatch and Dynamodb.


87 changes: 87 additions & 0 deletions examples/http-dynamodb/src/main.rs
@@ -0,0 +1,87 @@
use aws_sdk_dynamodb::model::AttributeValue;
use aws_sdk_dynamodb::{Client, Error as OtherError};
use lambda_http::{run, service_fn, Error, IntoResponse, Request};
use tracing::info;

#[derive(serde::Deserialize, serde::Serialize)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add

Suggested change
#[derive(serde::Deserialize, serde::Serialize)]
#[derive(Clone, serde::Deserialize, serde::Serialize)]

pub struct Item {
jknoetzke marked this conversation as resolved.
Show resolved Hide resolved
pub p_type: String,
pub age: String,
pub username: String,
pub first: String,
pub last: String,
}

impl Clone for Item {
fn clone(&self) -> Item {
return Item {
p_type: self.p_type.clone(),
age: self.age.clone(),
username: self.username.clone(),
first: self.first.clone(),
last: self.last.clone(),
};
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need this if you add the derive to the struct.

Suggested change
impl Clone for Item {
fn clone(&self) -> Item {
return Item {
p_type: self.p_type.clone(),
age: self.age.clone(),
username: self.username.clone(),
first: self.first.clone(),
last: self.last.clone(),
};
}
}

/// This is the main body for the function.
/// Write your code inside it.
/// You can see more examples in Runtime's repository:
/// - https://github.com/awslabs/aws-lambda-rust-runtime/tree/main/examples
async fn function_handler(event: Request) -> Result<impl IntoResponse, Error> {
// Extract some useful information from the request
let body = event.body();
let s = std::str::from_utf8(&body).expect("invalid utf-8 sequence");
//Log into Cloudwatch
info!(payload = %s, "JSON Payload received");

//Serialize the data into the struct.
let item: Item = serde_json::from_str(s).map_err(Box::new)?;

//Setup the client to write to DynamoDB
let config = aws_config::load_from_env().await;
let client = Client::new(&config);

//Insert into the table.
add_item(&client, item.clone(), "lambda_dyno_example").await?;

//Deserialize into json to return in the Response
let j = serde_json::to_string(&item)?;

Ok(j)
}

#[tokio::main]
async fn main() -> Result<(), Error> {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::INFO)
// disabling time is handy because CloudWatch will add the ingestion time.
.without_time()
.init();

run(service_fn(function_handler)).await
}

// Add an item to a table.
// snippet-start:[dynamodb.rust.add-item]
pub async fn add_item(client: &Client, item: Item, table: &str) -> Result<(), OtherError> {
let user_av = AttributeValue::S(item.username);
let type_av = AttributeValue::S(item.p_type);
let age_av = AttributeValue::S(item.age);
let first_av = AttributeValue::S(item.first);
let last_av = AttributeValue::S(item.last);

let request = client
.put_item()
.table_name(table)
.item("username", user_av)
.item("account_type", type_av)
.item("age", age_av)
.item("first_name", first_av)
.item("last_name", last_av);

info!("adding item to DynamoDB");

let _resp = request.send().await?;

Ok(())
}