How to use lambda and api getaway to trigger a custom event? - node.js

I'm trying to understand how The AWS api gateway works with lambda. What i am wanting to do is quite simple :
When I submit a basic form in a localhosted web page, this simple action should invoke a lambda function.
I know i need to use aws api gateway to complete this action and i read some tutorials online but i can't figure out how to start a lambda function after a custom event.
Thanks yor any help.

It is easier to understand if you work backwards. First, make your custom event handler. Amazon provides a good overview of what you need to do here:
http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html
If you need more of a kick in the right direction, LithosTech has a well-written guide to handling FORM POST events in Lambda here:
http://lithostech.com/2015/10/aws-lambda-example-contact-form-handler/
At its simplest level, you're going to have a function that takes an event parameter and does something with its values:
var AWS = require('aws-sdk');
exports.handler = function(event, context) {
console.log('Received event:', JSON.stringify(event, null, 2));
// TODO: Do something with event.name, event.email, event.*, ...
}
After you make this function in a .JS file, upload it using the Lambda Web console - you can do it entirely from the command line, but it's easier to use the Web interface when you're first starting out. The biggest benefit to doing it this way is that during the creation process, you'll be asked if you want to make an API gateway endpoint for the function - say yes! This will automatically create a suitable entry for you and give you the details. Drop those in your form and you're off to the races!

Related

What do i put in the "handler" prop of aws-cdk's gateway.LambdaRestApi?

I'm building out one of my first gateway api's and have been reading the code and documentation here.
For an apigateway which use made using the LambdaRestApi function, my understanding was that i define the endpoints and the lambda attached to the endpoints.
If that's the case, what do i put as the functions handler function? I don't have any plans for there to be a base route for it so do i have to just have a blank lambda here? Or am i going in the wrong direction with my thinking?
LambdaRestApi is just a utility construct based on RestApi with defaultIntegration to a Lambda function.
You can use a plain RestApi instead if you don't need the default proxy integration to a Lambda handler configured.

Can an Azure Function trigger itself?

I am trying to do the following with Azure Functions:
url='http://localhost:7071/api/testendpoint'
headers = {
'Content-Type': 'application/json'
}
response=requests.post(url,headers=headers)
i.e. "testendpoint" is another endpoint defined in the same function project. This is what I do: endpoint 1 gets a POST request and then the corresponding function code tries to trigger "testendpoint" with a another POST. If i try to do this locally, the function stops responding and runs into a timeout at some point.
Is it not possible to trigger another endpoint in the same function project? Do I have to split my project into multiple Azure Functions?
Thanks in advance!
It should be possibile.
Please find SO topic regarding this subject
How to call another function with in an Azure function

AWS Lambda: using CloudwatchEvent.disableRule() doesn't work within Lambda but works in local

I'm trying to disable the Cloudwatch Event Rule that is triggering a Lambda, within the Lambda itself, so that it doesn't keep running when it's not necessary to do so.
I have a separate Lambda that is calling enableRule to enable the rule, which seems to work fine. The rule is not associated with the function that is doing enableRule. EDIT: Turns out the EnableRule doesn't work in Lambda either.
However, this Lambda that's supposed to disable it isn't working.
Both functions already have Cloudwatch and CloudwatchEvent Full Access rights in their roles.
var cloudwatchEvents = new AWS.CloudWatchEvents();
var params = {
Name: cloudwatchEventRuleName
}
console.log("this message will show up");
cloudwatchEvents.disableRule(params, function (err, data) {
console.log("but this message never appears when it runs via Lambda for some reason!")
if (err)
console.log(err,err.stack);
else
console.log(data);
});
console.log("and this message will also show up");
That line where it was supposed to call the middle console.log doesn't work at all if I run it through Lambda. It's working perfectly in my local, however.
I even printed the cloudwatchEventRuleName to check if I have any typos, but the function name seems right. It's like the function is just outright skipping the disableRule function altogether for whatever reason.
So apparently, years later, setting up VPCs still haunt me.
Yep, it's a VPC configuration thing.
I could swear that the Subnet that the Lambda function was using had a route table that pointed to a properly set up Network Interface with a NAT Gateway Instance.
Out of curiosity, I tried making the route table entry of 0.0.0.0/0 point to the instance (i-#####) rather than the network interface (eni-######).
After I pressed Save in the Route Table, it automatically transformed into eni-######, similar to what I already had it set up...
Except this time the function actually started working now.
I have no idea what kind of magic AWS did so that associating an instance =/= associating to a network interface even though the former transformed into the same ID anyway, but whatever.
So for anyone encountering this same problem: always remember to double-check if your function actually has access to the internet to use the AWS APIs.
EDIT: Also another thing: I had to make sure that enableRule and disableRule were both awaited, as for some reason the AWS requests can in fact not be sent properly if the handler already returned something before the request was completed. So we turned into a promise just so we can await it:
try { await cloudwatchEvents.disableRule(params).promise().then((result) => console.log(result)) }
catch (error) { console.log("Error when disabling rule!", error); }

Independent NPM library that validates request based on swagger file

We are building APIs using Swagger, AWS API gateway and Lambda functions with NodeJS. The API gateway will do the request validation, however as per the design, the lambda functions need to re-validate the request object as an API Gateway Proxy Request Event. This makes sense as in theory we can reuse the lambda functions by invoking them via other event source (e.g. SNS).
Therefore we need an NodeJS tool which can validate the request (not only body but also params, etc) based on the swagger spec - exactly what the swagger-tools and a few other tools (e.g. swagger-request-validator) are doing, but not as a middleware.
I did some search but could not find one, also looked into swagger-tools source code, reckon its validation component was written in the way that cannot be easily used separately.
Any suggestion is welcome. Thanks in advance.
You can use swagger-model-validator.
var Validator = require('swagger-model-validator');
var swaggerFile = require("./swagger.json");
const validator = new Validator(swaggerFile);
console.log(validator.validate({
name: 'meg'
}, swaggerFile.definitions.Pet, swaggerFile.definitions, true).GetErrorMessages())
This outputs:
[ 'photoUrls is a required field' ]
validator.validate returns an object, so you can also check if the returned object contains anything under the errors attribute. It should be as simple as
if (validator.validate({
name: 'meg'
}, swaggerFile.definitions.Pet, swaggerFile.definitions, true).errors) {
// do something with error
}
I have used Swagger's sample JSON for this answer.

How to test advanced interactions when developing an Alexa Skill

I am developing an Alexa Skill, and I am struggling a bit in understanding if I setup everything in the best way possible to debug while developing.
Right now I am developing locally using Node.js, uploading to the cloud when ready, and testing all the responses to intents using the Service Simulator in the Test section of the developer console.
I find the process a bit slow but working... But still, I have two questions:
1) Is there a way of avoiding the process of uploading to the cloud?
And mostly important 2) How do I test advanced interactions, for examples multi-step ones, in the console? How for example to test triggering the response to an intent, but then asking the user for confirmation (Yes/No)? Right now the only way of doing it is using the actual device.
Any improvement is highly appreciated
Like #Tom suggested - take a look at bespoken.tools for testing skills locally.
Also, the Alexa Command Line Interface was recently released and it has some command line options you might look into.
For example, the 'api invoke-skill' command lets you invoke the skill locally via the command line (or script) so you don't have to use the service simulator. Like this...
$ask api invoke-skill -s $SKILL_ID -f $JSON --endpoint-region $REGION --debug
Here is a quick video I did that introduces the ASK CLI. It doesn't specifically cover testing but it will provide a quick intro.
https://youtu.be/p-zlSdixCZ4
Hope that helps.
EDIT: Had another thought for testing locally. If you're using node and Lambda functions, you can call the index.js file from another local .js file (example: test.js) and pass in the event data and context. Here is an example:
//path to the Lambda index.js file
var lambdaFunction = require('../lambda/custom/index.js');
// json representing the event - just copy from the service simulator
var event = require('./events/GetUpdateByName.json');
var context = {
'succeed': function (data) {
console.log(JSON.stringify(data, null,'\t') );
},
'fail': function (err) {
console.log('context.fail occurred');
console.log(JSON.stringify(err, null,'\t') );
}
};
function callback(error, data) {
if(error) {
console.log('error: ' + error);
} else {
console.log(data);
}
}
// call the lambda function
lambdaFunction.handler (event, context, callback);
Here's how I'm testing multi-step interactions locally.
I'm using a 3rd party, free, tool called BSTAlexa:
http://docs.bespoken.tools/en/latest/api/classes/bstalexa.html
It emulates Amazon's role in accepting requests, feeding them to your skill, and maintaining the state of the interactions.
So I start my test script by configuring BSTAlexa - pointing it to my skill config (eg. intents) and to a local instance of my skill (in my case I'm giving it a local URL).
Then I feed BSTAlexa a sequence of textual requests and verify that I'm getting back the expected responses. And I put all this in a Mocha script.
It works quite well.
Please find answers (Answering in reverse order),
You can test multiple steps using simulator (echosim.io) but each time you have to press and hold Mic button (Or hold on space bar). Say for example first you are asking something to Alexa with echosim and alexa responding to confirm'yes/no' then you have to press and hold mic button again to respond to confirm it.
You can automate the lambda deployment process. Please see the link,
http://docs.aws.amazon.com/lambda/latest/dg/automating-deployment.html
It would be good to write complete unit tests so that you can test your logic before uploading Lambda. Also it will help to reduce the number of Lambda deployments

Resources