Appsync response mapping template json key name change - amazon-web-services

What would be the right way to change json response key value in aws appsync response mapping template?
JSON that I get looks like this:
{
"tenant_id": 1,
"id": "bd8ce6a8-8532-47ec-8b7f-dcd1f1603320",
"header": "Header name",
"visible": true
}
and what I would like to pass forward is
{
"tenantId": 1,
"id": "bd8ce6a8-8532-47ec-8b7f-dcd1f1603320",
"header": "Header name",
"visible": true
}
Schema wants tenant id in form of tenantID and lambda returns it in form of tenant_id. I could change it in lambda but I would like to know how to do it in response mapping template.

You could do this via the response mapping template for the field you are resolving to in the following manner:
Consider the JSON response from your lambda to be stored in the response variable, then you can return something like this.
$#set($result = {
"tenantId": ${response.tenant_id},
"id": "${response.id}",
"header": "${response.header}",
"visible": $response.visible
})
$util.toJson($result)
Alternatively, you could also mutate your response from the lambda by setting a tenantId field, something like #set( $response.tenantId = $response.tenant_id ). Let me know if you still face an issue.
Thanks,
Shankar

Related

How do I add the `fields` array parameter when making requests to Patreon API using Postman?

I'm currently learning how to use the Patreon API. Before I integrate it into my site, I want to test the endpoints using POSTMAN. For example, I want to test the /campaign endpoint based on this documentation.
However, I'm confused how to set the parameter
fields[campaign]=created_at,creation_name
I put it in the body > x-www-form-urlencoded but it's not getting displayed in the atributes.
What is the correct way to set it?
Here is my screenshot of Postman:
Based on the documentation, the attributes in the response should have this information:
{
"data":
{
"attributes": {
"created_at": "2018-04-01T15:27:11+00:00",
"creation_name": "online communities",
"discord_server_id": "1234567890",
"image_small_url": "https://example.url",
"image_url": "https://example.url",
"is_charged_immediately": false,
"is_monthly": true,
"main_video_embed": null,
"main_video_url": null,
"one_liner": null,
"patron_count": 1000,
"pay_per_name": "month",
"pledge_url": "/bePatron?c=12345",
"published_at": "2018-04-01T18:15:34+00:00",
"summary": "The most creator-first API",
"thanks_embed": "",
"thanks_msg": null,
"thanks_video_url": null,
},
"id": "12345",
"type": "campaign"
},
From the API documentation
GET /api/oauth2/v2/campaigns/{campaign_id}
[ and ] needs to URL encode
Fields for each include must be explicitly requested i.e. fields[campaign]=created_at,creation_name but url encode the brackets i.e.fields%5Bcampaign%5D=created_at,creation_name
So you needs to change the Query Params KEY but
VALUE keep the same format field , field
From
fields[Bcampaign]
To
fields%5Bcampaign%5D

How do I map a value from the method request body into an API gateway mapping template?

I have a lambda, written in Java, that accepts a Request Object of the structure
{
"id": "1",
"value": "foobar"
}
When I call this Lambda through the test interface with such an object, it works fine.
I want to create an API where a PUT request to /items/1 (i.e. of the form /items/{id}), with a request body of
{
"value": "foobar"
}
calls this Lambda.
I have created the API resourcesitems, and {id} appropriately.
And I have created the PUT method (on /items/{id}) and associated it to the lambda.
I have created a mapping template that maps the id from the path to the object.
{
"id": "$method.request.path.id"
}
However, how do I map the value from the request body into the template so that I get an integration request of the form
{
"id": "1", // came from path
"value": "foobar" // came from HTTP request body
}
How do I achieve this mapping?
Try this application/json mapping template:
{
"id": "$method.request.path.id",
"body" : $input.json('$')
}
Then in your lambda: console.log(event.body)
API Gateway mapping template and access logging variable reference
I found that this in the template works.
#set($inputRoot = $input.path('$'))
{
"id": "$method.request.path.id",
"value": $inputRoot.value
}

Not able to add data into DynamoDB using API gateway POST method

I made a Serverless API backend on AWS console which uses API Gateway, DynamoDB, Lambda functions.
Upon creation I can add the data in dynamoDB online by adding a JSON file, which looks like this:
{
"id": "4",
"k": "key1",
"v": "value1"
}
But when I try to add this using "Postman", by adding the above JSON data in the body of POST message, I get a Positive return (i.e. no errors) but only the "id" field is added in the database and not the "k" or "v".
What is missing?
I think that you need to check on your Lambda function.
As you are using Postman to do the API calls, received event's body will be as follows:
{'resource':
...
}, 'body': '{\n\t"id": 1,\n\t"name": "ben"\n
}', 'isBase64Encoded': False
}
As you can see:
'body': '{\n\t"id": 1,\n\t"name": "ben"\n}'
For example, I will use Python 3 for this case, what I need to do is to load the body into JSON format then we are able to use it.
result = json.loads(event['body'])
id = result['id']
name = result['name']
Then update them into DynamoDB:
item = table.put_item(
Item={
'id': str(id),
'name': str(name)
}
)

Passing array query parameters with API Gateway to lambda

Can we create a Rest URL like below in API Gateway?
[GET] /employees?id=1&id=2&id=3&id=4
I do not find a way to send id array and get that array into a lambda (python) function
this is very late but I had the same issue and found the problem:
From AWS API Gateway Reference:
When a query parameter is a list type, its value must be a string of comma-separated items. For example, GET /restapis/restapi_id/deployments/deployment_id?embed=apisummary,sdksummary.
Amazon API Gateway does not support nested query parameters of the form: GET /team?user[id]=usrid on a method request. You could work around this limitation by passing an encoded map as a single parameter and serializing it as part of a mapping template or in your back-end integration.
So a fix you could use is restructuring your request such that:
[GET] /employees?id=1,2,3,4
Hope this helps!
AWS API events have a "multiValueQueryStringParameters" field which can be used instead of "queryStringParameters". It will contain value arrays for all parameters:
idArray = event["multiValueQueryStringParameters"]["id"]
Try sending array with json syntax e.g.: /employees?ids=['1','2','3']
This could help in javascript
https://www.npmjs.com/package/amazon-api-gateway-querystring
var mapQueryString = require('amazon-api-gateway-querystring');
event.params.querystring = mapQueryString(event.params.querystring);
event.params.querystring = {
"person[0][name]": "Mark",
"person[0][age]": 32,
"person[1][name]": "Luke",
"person[1][age]": 26,
"contacts[home][phone]": "+3333333333",
"contacts[home][email]": "email#email.com",
"contacts[home][twitter]": "#username"
}
// become:
event.params.querystring = {
"person": [{
"name": "Mark",
"age": 32
}, {
"name": "Luke",
"age": 26
}],
"contacts": {
"home": {
"phone": "+3333333333",
"email": "email#email.com",
"twitter": "#username"
}
}
}

Passing JSON data from response to request in Django

I have a Django (1.8.3) view that:
Makes a GET request to Server A (jetty), which returns JSON data in the body of the response. Then,
Makes a POST to Server B (node.js), passing the JSON data recieved from Server A in the body of the request.
The JSON data is structured like:
{
name: "foo",
details: {
"date": "today",
"isCool": "no",
},
stuff: [
{
"id": "1234",
"rating": "5",
}, {
"id": "5678",
"rating": "1",
},
]
}
But I can't figure out how to get the JSON from Server A's response into the request to Server B in my Django view. If I do this:
jetty_response = requests.request(method='GET', url=jetty_url)
node_response = requests.request(method="POST", url=node_url,
data=jetty_response.json())
I get the JSON object in Server B, but it looks like this:
{
name: "foo",
details: [ "date", "isCool"],
stuff: [ "id", "rating", "id", "rating"]
i.e. the name property is correct, but the details dict is instead received as the keyset of the original dict, and the stuff list is received as a flat array of the keysets in all objects in the original dict.
If I instead do this in django:
node_response = requests.request(method="POST", url=node_url,
data=json.dumps(jetty_response.json()))
I get an empty object in node, and same goes if I do simply:
data=jetty_response.content
How do I make this request??
Figured it out myself.
As is usually the case, the simplest answer:
node_response = requests.request(method="POST", url=node_url,
data=jetty_response.content)
worked fine once I took a closer look at my log and realized my POSTs were bouncing back 413, and then adjusted the size limit on my bodyParser in express.