I'd be really pressed to find relevant and even helpful material online, with actually working examples if you want to get started with API Gateway and Integration via Lambda, particularly when you wish to try interact with the simple databases like dynamoDB. Yes there is a lot of material, but if you're only starting out and exploring the space. And while its obviously not a non-starter, its a laborious task to get going, fine tuning the elements of the product, working out integration semantics and spending hours in the Docs, as helpful as they may be.
Having played with API deployment and Deployed API proxies with the likes of TYK in the past, This AWS offering of cloud-based API configuration, management and infinite scalability really does strikes accord with me. In particular when business logic is not only heading into Cloud and Containerisation but further, - serverless. And all with good reasons mentioned above and not forgetting the key financial incentive. It's really cost effective, not managing your own services you now.
Its been a little while since i've completed my AWS Certifications, and with that helpful knowhow I decided to take a plunge and hands-on to investigate how such offering and projects fare, not having worked on these AWS products in the past.
Deploy a Simple API, which enables PUT and GET requests
In Particular, You should be able to add a record to a database, dynamodb so,
name: James, dateOfBirth: 1990-01-01 would do
I decided to use the native proxy for put function, directly "calling" dynamoDB, its a simpler method, and does not need the coding overhead.
I also decided on the dynamoDB to be my key-pair storage for this trial
Finally, since we want some computational result from GET request, its a lambda with good old NodeJS framework.
Its a fairly straight forward setup, via AWS Console
Once navigate into DynamoDB product offering, simply create a table name of choice. I created namespaces.
Actual PUT request had to be mapped in PUT integration as follows:
#set($inputRoot = $input.path('$'))
{
"TableName": "namespaces",
"Item": {
"name": {
"S": "$input.params('name')"
},
"dateOfBirth": {
"S": "$input.path('$.dateOfBirth')"
}
}
}
This was a what one would find naturally tricky especially if it's not your daily bread-n-butter there.
GET Integration had to be mapped, to ensure we can reach this in our lambda call.
{
"myname" : "$input.params('name')"
}
Once we have our name variable, we can have a function call to dynamoDB and perform GetItem on the table, the latter was predefined in lambda code.
---- example lambda code ----
var aws = require('aws-sdk');
exports.handler = function(event, context) {
var dynamo = new aws.DynamoDB({
region: 'eu-west-2',
maxRetries: 0
});
// getting my passed var over
var nameInfo = event.myname;
console.log('Will run getItem on name key : '+nameInfo);
// params for my dynamodb func
var params = {
TableName : 'namespaces',
Key : {
"name" : {
"S" : nameInfo
},
},
AttributesToGet: [
'name', 'dateOfBirth'
],
ConsistentRead: true,
}
dynamo.getItem(params,
function(err, data) {
console.log("Pre-processing - data view: ",data);
if (err) {
console.log(err, err.stack); // an error occurred
context.done(err);
}
else {
// once its all great success, lets work on dates
var date = new Date();
var getFullYear = date.getFullYear();
var originalDateOfBirth=data.Item.dateOfBirth.S
var strippeddate=originalDateOfBirth.toString().split("-");
var Original_Birthday_MD=strippeddate[1].replace(/(^|-)0+/g, "$1")+"-"+strippeddate[2].replace(/(^|-)0+/g, "$1");
var Current_Date_MD=date.getMonth()+'-'+date.getUTCDate()
console.log('Comparing Original_Birthday_MD: '+Original_Birthday_MD+' & Current_Date_MD: '+Current_Date_MD )
//So, erm, How many days until your birthday?
var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var Original_Birthday_MD_ = new Date(getFullYear+"-"+Original_Birthday_MD);
var Current_Date_MD_ = new Date(getFullYear+"-"+Current_Date_MD);
console.log('Comparing FULL DATE Original_Birthday_MD_: '+Original_Birthday_MD_+' & Current_Date_MD_: '+Current_Date_MD_ )
var daysUntilBday = Math.round(Math.abs(Current_Date_MD_.getTime() - Original_Birthday_MD_.getTime() )/(oneDay));
console.log('How many Days until my birthday? '+daysUntilBday);
// Is this your lucky day
if (daysUntilBday == 0)
{ // lets rock this overriding data response, because we can
data='Happy Birthday '+nameInfo+'!';
}
else if (daysUntilBday < 5)
{ // perhaps even warn if they have bday upcoming
data='Hello '+nameInfo+'! Your Birthday is in '+daysUntilBday+' days.';
}
console.log(data); // successful response
context.succeed(data); // must ssuccessfully terminate the function and return !!
}
});
};
[Latest and Greatest code on] (https://gist.github.com/jpantsjoha/8479ffb137ea873a169fc00e056ed77a)
Time To Test and Play.
Putting Several New Users, bob, kev, kal
bob, will be DOB 1980-01-01
kev, will be DOB closer to today but not today, so 1980-04-30
kal, will be DOB on today's date, to check out birthday message function, so 1980-05-02
And, Lets Curl/URL the results
(URL secrecy aside, this is like for like)
jp@jpmac~$ curl https://secret.execute-api.eu-west-2.amazonaws.com/hello/kal
"Happy Birthday kal!"
jp@jpmac~$ curl https://secret.execute-api.eu-west-2.amazonaws.com/hello/kev
"Hello kev! Your Birthday is in 2 days."
jp@jpmac~$ curl https://secret.execute-api.eu-west-2.amazonaws.com/hello/bob
{"Item":{"name":{"S":"bob"},"dateOfBirth":{"S":"1980-01-01"}}}
PUT
curl -X PUT -H "Content-Type: application/json" -d '{"dateOfBirth":"1998-11-30"}' https://secret.execute-api.eu-west-2.amazonaws.com/hello/jones
{}
GET
curl https://secret.execute-api.eu-west-2.amazonaws.com/hello/jones
{"Item":{"name":{"S":"jones"},"dateOfBirth":{"S":"1998-11-30"}}}
Checkout the Gist Link for the full (especially it i will update it) snipped of the lambda function
Public GitHub Gist on how to see this NodeJS Based Lambda glue is actually working is all there:
https://gist.github.com/jpantsjoha/8479ffb137ea873a169fc00e056ed77a
Clap me for this post if you found it useful.
Cheers!