I am setting a serverless application using AWS Amplify
My frontend app has the following code
import React, { Component } from 'react';
import './App.css';
import Layout from './Containers/Layout';
import { Amplify, API } from 'aws-amplify';
import aws_exports from './aws-exports';
Amplify.configure(aws_exports);
const apiName = 'top3DynamoDBAPI';
let path = '/listings/';
let partitionKey = 'Restaurant';
class App extends Component {
componentDidMount() {
API.get(apiName, path + partitionKey).then(response => {
console.log(response)
});
}
state = {
listings: {
}
}
render() {
return (
<div className="App">
<Layout />
</div>
);
}
}
export default App;
in my backend API the get method to retrieve items from the table is as follows
/********************************
* HTTP Get method for list objects *
********************************/
app.get(path + hashKeyPath, function(req, res) {
var condition = {}
condition[partitionKeyName] = {
ComparisonOperator: 'EQ'
}
if (userIdPresent && req.apiGateway) {
condition[partitionKeyName]['AttributeValueList'] = [req.apiGateway.event.requestContext.identity.cognitoIdentityId || UNAUTH ];
} else {
try {
condition[partitionKeyName]['AttributeValueList'] = [ convertUrlType(req.params[partitionKeyName], partitionKeyType) ];
} catch(err) {
res.statusCode = 500;
res.json({error: 'Wrong column type ' + err});
}
}
let queryParams = {
TableName: tableName,
KeyConditions: condition
}
dynamodb.query(queryParams, (err, data) => {
if (err) {
res.statusCode = 500;
res.json({error: 'Could not load items: ' + err});
} else {
res.json(data.Items);
}
});
});
In my Dynamo DB table, I have a primary partition which has categories and one of them is called 'Restaurant' . So in my App.js I set some variables and call the API to get the items in ComponentDidMount
const apiName = 'top3DynamoDBAPI';
let path = '/listings/';
let partitionKey = 'Restaurant';
componentDidMount() {
API.get(apiName, path + partitionKey).then(response => {
console.log(response)
});
this returns all the items from the table where the primary partition matches a value called 'Restaurant'
Now I have global Secondary Partition called 'Listing_Location' which currently has two values -- Sydney and Brisbane.
The backend API uses DynamoDB's Document Client and has the following variable initialised
const userIdPresent = false; // TODO: update in case is required to use that definition
const partitionKeyName = "Listing_Category";
const partitionKeyType = "S";
const sortKeyName = "Listing_Id";
const sortKeyType = "S";
const hasSortKey = sortKeyName !== "";
const path = "/listings";
const UNAUTH = 'UNAUTH';
const hashKeyPath = '/:' + partitionKeyName;
const sortKeyPath = hasSortKey ? '/:' + sortKeyName : '';
I am stuck at trying to figure out how to pass the secondary partition to my backend so I can lookup items based on location. Please can you help with this.
I was able to solve it with a combination of info from DynamoDb how to query a Global Secondary Index? and https://medium.com/@ole.ersoy/sending-an-email-parameter-with-amplify-api-get-request-4c1c8dc0c952
Now, my App.js looks like
componentDidMount() {
let params = {
'queryStringParameters': {
location: 'Brisbane'
}
}
API.get(apiName, path, params).then(response => {
this.setState({
listings: response
})
console.log(response)
});
}
New get function is
/* NEW GET ATTEMPT*/
app.get(path, function (req, res) {
if (userIdPresent) {
req.body['userId'] = req.apiGateway.event.requestContext.identity.cognitoIdentityId || UNAUTH;
}
const location = req.query.location;
var queryItemParams = {
TableName: tableName,
IndexName: "ListingGSI",
KeyConditionExpression: "#location = :v_location",
ExpressionAttributeNames: {
"#location": "Listing_Location"
},
ExpressionAttributeValues: {
":v_location": location
}
};
dynamodb.query(queryItemParams, (err, data) => {
if (err) {
res.statusCode = 500;
res.json({ error: 'Could not load items: ' + err });
} else {
res.json(data.Items);
}
});
});