Lambda and API gateway mapping - aws-lambda

I want to return a value from handler to API gateway response header.
Handler.js
module.exports.handler = function(event, context, cb) {
const UpdateDate = new Date();
return cb(null, {
body: {
message: 'test'
},
header: {
Last-Modified: UpdateDate
}
});
};
s-function.json in "endpoints"
"responses": {
"400": {
"statusCode": "400"
},
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Cache-Control": "'public, max-age=86400'",
"method.response.header.Last-Modified": "integration.response.body.header.Last-Modified"
},
"responseModels": {
"application/json;charset=UTF-8": "Empty"
},
"responseTemplates": {
"application/json;charset=UTF-8": "$input.json('$.body')"
}
}
}
This can work. But I want to know how to use "integration.response.header.Last-Modified". Is my handler callback formate wrong?
Edit:
s-function.json in "endpoints"
"integration.response.header.Last-Modified" This doesn't work.
I want to know specific handler return formate to pass data to "integration.response.header.Last-Modified".
"responses": {
"400": {
"statusCode": "400"
},
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Cache-Control": "'public, max-age=86400'",
"method.response.header.Last-Modified": "integration.response.header.Last-Modified"
},
"responseModels": {
"application/json;charset=UTF-8": "Empty"
},
"responseTemplates": {
"application/json;charset=UTF-8": "$input.json('$.body')"
}
}
}

All of the output from your lambda function is returned in the response body, so you will need to map part of the response body to your API response header.
module.exports.handler = function(event, context, cb) {
const UpdateDate = new Date();
return cb(null, {
message: 'test',
Last-Modified: UpdateDate
});
};
will produce payload "{"message" : "test", "Last-Modified" : "..."}"
In this case you would use "integration.response.body.Last-Modified" as the mapping expression. As a side note, naming things "body" and "header" in your response body may make the mapping expressions confusing to read.
Thanks,
Ryan

Related

How to access non-data object in apollo graphql?

Query:
query SampleQuery {
clients {
totalCount
}
}
Response
{
"data": {
"clients": {
"totalCount": 2
}
},
"extensions": {
"cost": {
"requestedQueryCost": 2,
"actualQueryCost": 2,
"throttleStatus": {
"maximumAvailable": 10000,
"currentlyAvailable": 9998,
"restoreRate": 500
}
}
}
}
I seem to only be able to access the "data" object when using apollo. Is there a way to get access to the "extensions" object?
There isn't an extensions object on the response
var results = await client.query<GetClients>({
(results.data.clients exists, but results.extensions does not).
My client is:
const client = new ApolloClient({
cache: new InMemoryCache(),
link: concat(authMiddleware, httpLink),
});

Loopback : Validate model from another model is not returning proper error message

I am validating model from another model like below
Model.addFavorite = function (data, callbackFn) {
if (data) {
var faviroteModel = this.app.models.Favorite;
var objFavorite = new faviroteModel(data);
objFavorite.isValid(function (isValid) {
if (isValid) {
callbackFn(null, objFavorite);
}
else {
callbackFn(objFavorite.errors);
}
});
}
else callbackFn("Post data required", {});
}
If i do this then I am getting error like below
{
"error": {
"statusCode": 500,
"t": [
"is not a valid date"
]
}
}
It should be with error message like below
{
"error": {
"statusCode": 422,
"name": "ValidationError",
"message": "The `Favorite` instance is not valid. Details: `t` is not a valid date (value: Invalid Date).",
"details": {
"context": "Favorite",
"codes": {
"t": [
"date"
]
},
"messages": {
"t": [
"is not a valid date"
]
}
}
}
}
Can anyone tell me what am i missing here.
How can i achieve this.
https://github.com/strongloop/loopback-datasource-juggler/blob/master/lib/validations.js#L843
You might run into situations where you need to raise a validation
error yourself, for example in a "before" hook or a custom model
method.
if (model.isValid()) {
return callback(null, { success: true });
}
// This line shows how to create a ValidationError
var err = new MyModel.ValidationError(model);
callback(err);
}

CppRestSDK https request not working

This is returning error code 401 or 500. Can somebody help me where I am going wrong?
http_client client(L"https://oxford-speech.cloudapp.net/token/issueToken/");
uri_builder query;
query.append_query(L"grant_type", L"client_credentials");
query.append_query(L"client_id", L"test-app");
query.append_query(L"client_secret", L"<client secret goes here>");
query.append_query(L"scope", L"https://speech.platform.bing.com");
query.append_query(L"content_type", L"application/x-www-form-urlencoded");
http_request msg(methods::POST);
msg.headers().set_content_type(L"application/x-www-form-urlencoded");
msg.set_request_uri(query.to_string());
std::wstring str = msg.to_string();
return client.request(msg);
Thanks all. I changed the code to following and i got the token!
pplx::task<void> getAccessToken()
{
istream bodyStream;
http_client client(L"https://api.cognitive.microsoft.com/sts/v1.0/issueToken");
http_request req(methods::POST);
req.headers().add(L"Ocp-Apim-Subscription-Key", L"YOUR_KEY");
return client.request(req)
.then([](http_response response)
{
if (response.status_code() != status_codes::OK)
{
return pplx::task_from_result();
}
istream bodyStream = response.body();
container_buffer<std::string> inStringBuffer;
return bodyStream.read_line(inStringBuffer)
.then([inStringBuffer](size_t bytesRead)
{
const std::string &text = inStringBuffer.collection();
std::cout << text;
});
});
};
Here's a generic JSON representation of a request that worked last time I tried (Sept 2016). Your request looks pretty different. Extracted from Woundify settings file
{
"name": "BingSpeechToTextService",
"classInterface": "BingServices.ISpeechToTextService",
"request": {
"method": "post", // { "get" | "post" | <custom> }
"preferChunkedEncodedRequests": false,
"uri": {
"scheme": "https",
"host": "speech.platform.bing.com",
"path": "recognize",
"query": "scenarios=smd&appid=D4D52672-91D7-4C74-8AD8-42B1D98141A5&locale={locale}&device.os=wp7&version=3.0&format=json&instanceid=565D69FF-E928-4B7E-87DA-9A750B96D9E3&requestid={guid}"
},
"headers": [
{
"Name": "Accept",
"Accept": "application/json"
},
{
"Name": "BearerAuthentication",
"BearerAuthentication": {
"type": "bearer", // { basic | bearer | <custom> }
"clientID": "",
"clientSecret": "",
"scope": "https://speech.platform.bing.com",
"uri": "https://oxford-speech.cloudapp.net/token/issueToken",
"grant": "grant_type=client_credentials&client_id={clientID}&client_secret={clientSecret}&scope={scope}"
}
},
{
"Name": "Content-Type",
"ContentType": "audio/wav; codec=\"audio/pcm\"; samplerate={sampleRate}"
}
],
"data": {
"type": "binary" // { ascii | base64 | binary | json | raw | string | urlencode }
}
},
"response": {
"missingResponse": "whatever",
"jsonPath": "results[0].name"
}
},
Please note that there's a simpler token-issuing URL nowadays. Your C++ code will look something like this:
pplx::task<string_t> getToken()
{
http_client client(L"https://api.cognitive.microsoft.com/sts/v1.0/issueToken");
http_request req(methods::POST);
req.headers().add(L"Ocp-Apim-Subscription-Key", YOUR_API_KEY);
return client.request(req).then([=](http_response response) -> pplx::task<string_t>
{
return response.extract_string(true);
});
}
The entire response body is the token unlike the old scheme, which had a JSON response that included the token.

Api gateway 304 responses with Last-Modified header

I want to response a 304 response with Last-Modified header.
At first I use Error response to implement.
Handler.js
module.exports.handler = function(event, context, cb) {
const UpdateDate = new Date();
return cb("304 Not Modified", {
"Last-Modified": UpdateDate,
"body":{
"message": {}
}
});
};
s-function.json in endpoints
"responses": {
"304 Not Modified.*": {
"statusCode": "304",
"responseParameters": {
"method.response.header.Last-Modified": "integration.response.body.Last-Modified"
},
"responseModels": {
"application/json;charset=UTF-8": "Empty"
},
"responseTemplates": {
"application/json;charset=UTF-8": "$input.json('$.body')"
}
},
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Cache-Control": "'public, max-age=86400'",
"method.response.header.Last-Modified": "integration.response.body.Last-Modified"
},
"responseModels": {
"application/json;charset=UTF-8": "Empty"
},
"responseTemplates": {
"application/json;charset=UTF-8": "$input.json('$.body')"
}
}
}
However, I find it on Lambda doc.
If an error is provided, callback parameter is ignored.
So, this doesn't work.
Is there any solution to response a 304 response with header?
Updated:
Is it possible to return a Error object and map responses 304 in s-function? Below code can't map to 304.
s-funtion.json
"responses": {
".*304 Not Modified.*": {
"statusCode": "304",
"responseParameters": {
"method.response.header.Cache-Control": "'public, max-age=86400'",
"method.response.header.Last-Modified": "integration.response.body.errorMessage.Last-Modified"
}
}
Handler.js
return cb({
"status" : "304 Not Modified",
"Last-Modified": UpdateDate
), null);
I also try this. It can mapping to 304 but header can't get "integration.response.body.errorMessage.Last-Modified"
return cb(JSON.stringify({
"status" : "304 Not Modified",
"Last-Modified": UpdateDate
}), null);
I try $util.parseJson but not working on responseParameter.
Invalid mapping expression specified:$util.parseJson($input.path('$.errorMessage')).Last-Modified
"responseParameters": {
"method.response.header.Cache-Control": "'public, max-age=86400'",
"method.response.header.Last-Modified": "$util.parseJson($input.path('$.errorMessage')).Last-Modified"
},
To return status 304 in your API, you would need to throw an error from your Lambda function. It is possible to return the "Last-Modified" value in the error message from your Lambda function and route that to the "Last-Modified" header in the API response.
For details have a look at Option 2 here
Thanks,
Ryan

How to create *static* property in can.Model

I need somehow to store metadata in the can.Model
I use findAll method and receive such JSON:
{
"metadata": {
"color": "red"
},
"data": [
{ "id": 1, "description": "Do the dishes." },
{ "id": 2, "description": "Mow the lawn." },
{ "id": 3, "description": "Finish the laundry." }
]
}
I can work with data like can.Model.List, but I need metadata like a static property or something.
You can use can.Model.parseModels to adjust your response JSON before it's turned into a can.Model.List.
parseModels: function(response, xhr) {
var data = response.data;
var metadata = response.metadata;
var properties;
if(data && data.length && metadata) {
properties = Object.getOwnPropertyNames(metadata);
can.each(data, function(datum) {
can.each(properties, function(property) {
datum[property] = metadata[property];
});
});
}
return response;
}
Here's a functional example in JS Bin: http://jsbin.com/qoxuju/1/edit?js,console

Resources