Reputation: 6451
This is my current lambda function, which return all data from Table "Banner".
getBanner.js
'use strict'
const AWS = require('aws-sdk');
exports.handler = async function (event, context, callback) {
const documentClient = new AWS.DynamoDB.DocumentClient();
let responseBody = "";
let statusCode = 0;
const params = {
TableName : "Banner",
};
try{
const data = await documentClient.scan(params).promise();
responseBody = JSON.stringify(data.Items);
statusCode = 200
}catch(err){
responseBody = `Unable to get products: ${err}`;
statusCode = 403
}
const response = {
statusCode: statusCode,
headers:{
"Content-Type": "application/json",
'Access-Control-Allow-Origin': '*', // Required for CORS support to work
},
body: responseBody
}
return response
}
It is the sample returned data
[
{
Order: 123,
Year: 2000
...
},
{
Order: 77,
Year: 2007
...
}
]
I understand If I want to do some query for attribute order, I need to change to following.
...
var params = {
TableName : "Banner",
KeyConditionExpression: "#od = :yyyy",
ExpressionAttributeNames:{
"#od": "order"
},
ExpressionAttributeValues: {
":yyyy": 1
}
};
...
What if I want to do the following?
There may be some use cases which make me need to do query for another attribute, or multiple attributes.
How should I do have a function which can handle the queryStringParameters dynamically?
Updated based on the comment, but another error occurs
'use strict'
const AWS = require('aws-sdk');
exports.handler = async function (event, context, callback) {
const documentClient = new AWS.DynamoDB.DocumentClient();
let responseBody = "";
let statusCode = 0;
console.log(event)
const queryStringParams = event.queryStringParameters;
console.log(queryStringParams)
let KeyConditionExpression = ''
let ExpressionAttributeNames={};
let ExpressionAttributeValues = {};
for (const property in queryStringParams) {
KeyConditionExpression += ` #${property} = :${property} ,`;
ExpressionAttributeNames['#'+property] = property ;
ExpressionAttributeValues[':'+property]=queryStringParams[property];
}
KeyConditionExpression= KeyConditionExpression.slice(0, -1);
const params = {
TableName : "Banner",
KeyConditionExpression: KeyConditionExpression,
ExpressionAttributeNames: ExpressionAttributeNames,
ExpressionAttributeValues: ExpressionAttributeValues
};
console.log(params) //Response A
try{
const data = await documentClient.scan(params).promise();
responseBody = JSON.stringify(data.Items);
statusCode = 200
}catch(err){
responseBody = `Unabel to get products: ${err}`;
statusCode = 403
}
const response = {
statusCode: statusCode,
headers:{
"Content-Type": "application/json",
'Access-Control-Allow-Origin': '*', // Required for CORS support to work
},
body: responseBody
}
return response
}
Unabel to get products: ValidationException: ExpressionAttributeNames can only be specified when using expressions
This is the value of the ‘params’ obtained from cloudwatch Response A
{
TableName: 'Banner',
KeyConditionExpression: ' #order = :order , #year = :year ',
ExpressionAttributeNames: { '#order': 'order', '#year': 'year' },
ExpressionAttributeValues: { ':order': '1', ':year': '2007' }
}
Upvotes: 1
Views: 2141
Reputation: 21
Use FilterExpression when using scan instead of KeyConditionExpression. Sample
const queryStringParams = event.queryStringParameters;
let FilterExpression = "";
let ExpressionAttributeNames = {};
let ExpressionAttributeValues = {};
for (const property in queryStringParams) {
FilterExpression += ` #${property} = :${property} ,`;
ExpressionAttributeNames["#" + property] = property;
ExpressionAttributeValues[":" + property] = queryStringParams[property];
}
FilterExpression = FilterExpression.slice(0, -1);
const params = {
TableName: tableName,
FilterExpression: FilterExpression,
ExpressionAttributeNames: ExpressionAttributeNames,
ExpressionAttributeValues: ExpressionAttributeValues
};
Upvotes: 2
Reputation: 516
You can this query parameters from the event object in your Lambda function handler. The event object content depends on what service invoked the Lambda function. If Lambda function invoked from Elastic Load Balancing or from API gateway you can get the query parameters from the event object. The event object will have an attribute called queryStringParameters
which have all the query string parameters in the request.
This is a sample for an event object from the documentation:
{
"requestContext": {
"elb": {
"targetGroupArn": "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a"
}
},
"httpMethod": "GET",
"path": "/lambda",
"queryStringParameters": {
"query": "1234ABCD"
},
"headers": {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"accept-encoding": "gzip",
"accept-language": "en-US,en;q=0.9",
"connection": "keep-alive",
"host": "lambda-alb-123578498.us-east-2.elb.amazonaws.com",
"upgrade-insecure-requests": "1",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
"x-amzn-trace-id": "Root=1-5c536348-3d683b8b04734faae651f476",
"x-forwarded-for": "72.12.164.125",
"x-forwarded-port": "80",
"x-forwarded-proto": "http",
"x-imforwards": "20"
},
"body": "",
"isBase64Encoded": false
}
https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html https://docs.aws.amazon.com/lambda/latest/dg/lambda-services.html
Example for your case: (NOTE: name of the query strings must be the same as expression attributes)
const queryStringParams = event.queryStringParams;
const updatedQueryStringParams = {};
Object.keys(queryStringParams).forEach(key => updatedQueryStringParams[`:${key}`] = queryStringParams[key]);
var params = {
TableName : "Banner",
KeyConditionExpression: "#od = :year",
ExpressionAttributeNames:{
"#od": "order"
},
ExpressionAttributeValues: {
...updatedQueryStringParams
}
};
Upvotes: 1
Reputation: 2545
Simple example
const getParams = (key, value) => ({
TableName: "Banner",
KeyConditionExpression: "#key = :value",
ExpressionAttributeNames: {
"#key": key
},
ExpressionAttributeValues: {
":value": value
}
});
And call this function based on your query parameters. Query parameters you can get from the event.
const queryParams = event.queryStringParameters;
Upvotes: 1