我是生疏的,这个问题可能会变得很愚蠢。我正在尝试开发一个lambda,它读取dynamoDB给出的密钥中的单个条目。返回的项需要作为结果共享给调用lambda。
我希望响应在JSON中。
以下是我所拥有的:
输入结构
#[derive(Deserialize, Clone)]
struct CustomEvent {
#[serde(rename = "user_id")]
user_id: String,
}输出结构
#[derive(Serialize, Clone)]
struct CustomOutput {
user_name: String,
user_email: String,
}主fn
#[tokio::main]
async fn main() -> std::result::Result<(), Error> {
let func = handler_fn(get_user_details);
lambda_runtime::run(func).await?;
Ok(())
}要查询的逻辑
async fn get_user_details(
e: CustomEvent,
_c: Context,
) -> std::result::Result<CustomOutput, Error> {
if e.user_id == "" {
error!("User Id must be specified as user_id in the request");
}
let region_provider =
RegionProviderChain::first_try(Region::new("ap-south-1")).or_default_provider();
let shared_config = aws_config::from_env().region(region_provider).load().await;
let client: Client = Client::new(&shared_config);
let resp: () = query_user(&client, &e.user_id).await?;
println!("{:?}", resp);
Ok(CustomOutput {
// Does not work
// user_name: resp[0].user_name,
// user_email: resp[0].user_email,
// Works because it is hardcoded
user_name: "hello".to_string(),
user_email: "world@gmail.com".to_string()
})
}
async fn query_user(
client: &Client,
user_id: &str,
) -> Result<(), Error> {
let user_id_av = AttributeValue::S(user_id.to_string());
let resp = client
.query()
.table_name("users")
.key_condition_expression("#key = :value".to_string())
.expression_attribute_names("#key".to_string(), "id".to_string())
.expression_attribute_values(":value".to_string(), user_id_av)
.projection_expression("user_email")
.send()
.await?;
println!("{:?}", resp.items.unwrap_or_default()[0]);
return Ok(resp.items.unwrap_or_default().pop().as_ref());
}我的TOML
[dependencies]
lambda_runtime = "^0.4"
serde = "^1"
serde_json = "^1"
serde_derive = "^1"
http = "0.2.5"
rand = "0.8.3"
tokio-stream = "0.1.8"
structopt = "0.3"
aws-config = "0.12.0"
aws-sdk-dynamodb = "0.12.0"
log = "^0.4"
simple_logger = "^1"
tokio = { version = "1.5.0", features = ["full"] }我无法打开并将响应发送回名为lambda。从query_user函数中,我希望能够将构造的CustomOutput结构返回到
Ok(CustomOutput {
// user_name: resp[0].user_name,
// user_email: resp[0].user_email,
})在get_user_details中阻塞。任何帮助或推荐信都会有很大帮助。谢谢。
发布于 2022-06-20 11:29:33
经过几次尝试,我学到了以下内容:可以使用match关键字来代替在变量中收集结果。我做了这个:
match client
.query()
.table_name("users")
.key_condition_expression("#key = :value".to_string())
.expression_attribute_names("#key".to_string(), "id".to_string())
.expression_attribute_values(":value".to_string(), user_id_av)
.projection_expression("user_email")
.send()
.await
{
Ok(resp) => Ok(resp.items),
Err(e) => Err(e),
}当响应从DB返回时,它必须在其中包含一个项键值。
所以,这一行:
Ok(resp) => Ok(resp.items)将确保items数组返回到调用函数。
接下来,要从Hashmap中逐个获取值并将它们加载到CustomOutput中,这是我所做的:
let resp: std::option::Option<Vec<HashMap<std::string::String, AttributeValue>>> = query_user(&client, &e.user_id).await?;一旦我得到了resp,如果需要这样的话,我可以挖掘到第一个元素:
x[0]
.get("user_name")
.unwrap()
.as_s()
.unwrap()
.to_string()对于数字类型,可能类似于"battery_voltage":
x[0]
.get("battery_voltage")
.unwrap()
.as_n()
.unwrap()
.to_string()
.parse::<f32>()
.unwrap(),最后,使用匹配块来确定数据的部分或无值:
match _val {
Some(x) => {
// pattern
if x.len() > 0 {
return Ok(json!(CustomOutput {
user_name: x[0].get("user_name").unwrap().as_s().unwrap().to_string(),
user_email: x[0].get("user_email").unwrap().as_s().unwrap().to_string(),
}));
} else {
return Ok(json!({
"code": "404".to_string(),
"message": "Not found.".to_string(),
}));
}
}
None => {
// other pattern
println!("Got nothing");
return Ok(json!({
"code": "404".to_string(),
"message": "Not found.".to_string(),
}));
}希望这能帮到别人!
https://stackoverflow.com/questions/72644005
复制相似问题