In this project we will create a very simple Node.js script that will get exchange rates via a REST API and then email them out. There is not much actual usefulness of this process, however the goal is to provide an introduction into the IronWorker service provided by Iron.io and the Lambda service provided by Amazon Web Services.
The project will first walk you through creating the script and deploying to IronWorker. Once that is completed, we will copy the file, adjust a bit and then upload to Lambda and run.
The slides from the talk can be found at http://www.slideshare.net/jasonfill/workers-and-event-processors-that-scale
NOTE: The Mandrill API key and the values in the iron.json file are expired. You will need to insert your own credentials.
We need to install the CLI in order to deploy our code to iron worker. The CLI requires Ruby 1.9+. Once Ruby is installed you can just run the following command:
gem install iron_worker_ng
To create the node project open terminal in the location you wish to store your files.
- Make the grnodedev_exchange_rates dir, then move into it
mkdir exchange_rates
cd exchange_rates
- Initialize the node package file.
npm init
For this we can just accept all the defaults, we are not too concerned with the actual meta data for the package at this point.
- To help us interact with the IronWorker we will need to install a helper module that exposes some of the config and payload variables.
npm install iron_node_helper --save
note: the save flag will add the dependency to your node package file for you
- We will also be making some http requests in our worker so lets go ahead and add the request module as well.
npm install request --save
- Since we will also be sending mail, so go ahead and install the mandrill client lib.
npm install node-mandrill --save
At this point you can open your editor of choice and continue.
If you do not already have a free Iron.io account, go over to their site and create one. Once you have your account created, go ahead and create your first project.
Supply the application with your iron.io credentials. The CLI will need your credentials when pushing the code to your account.
Create a file in the root of your project called iron.json.
{
"project_id": "INSERT YOUR PROJECT ID HERE",
"token": "INSERT YOUR TOKEN HERE"
}
At this point we are going to write a very simple worker that will get the current exchange rates given the base value that is passed in via the payload. For the project we will interact with the Fixer.io API which is located at http://fixer.io/.
-
Create a file called
ironworker.js. This will be our simple worker file. -
Include the required modules at the top of the file.
var request = require('request');
var worker = require('iron_node_helper');
var mandrill = require('node-mandrill')('5RP2v9vIJByJydifVgw7OQ');
- So we can understand what the helper file is doing, let's go ahead and log all the values that can be returned.
// outputs the payload params
console.log("params:", worker.params);
// outputs the actual config of the worker
console.log("config:", worker.config);
// outputs the task id that is being run
console.log("task_id:", worker.task_id);
- Write a simple function that will make an HTTP request to get the current exchange rates given the base currency and then shoot an email out.
var emailCurrencies = function(base_currency, email, callback) {
var options = {
url: 'http://api.fixer.io/latest?base=' + base_currency
};
request(options, function (err, message, body) {
if (err) {
callback(err);
} else {
mandrill('/messages/send', {
message: {
to: [{email: email}],
from_email: 'bot@grnodedev.com',
subject: "Your exchange rates!",
html: JSON.stringify(body)
}
}, function (err, response) {
if (err) {
callback(err);
} else {
callback();
}
});
}
});
};
- Call the function so it is executed when the script loads.
emailCurrencies(worker.params.base_currency, worker.params.email, function(err){
if(err){
process.exit(1);
}else{
process.exit(0);
}
});
The worker file is a way to define your worker and all its dependencies.
- Create a new file and add the following:
runtime "node"
exec "ironworker.js"
dir "node_modules"
file "package.json"
You can also allow IronWorker to remotely build your application, if this is desired you just need to omit the dir line above and include remote and a build command as shown below.
runtime "node"
exec "index.js"
build "npm install"
remote
Review all the options at http://dev.iron.io/worker/reference/dotworker/
- Save the file with the name
exchangerates.worker
To upload your worker you will just need to run
iron_worker upload exchangerates
iron_worker queue exchangerates -p '{"base_currency":"USD","email":"user@email.com"}'
You can find more CLI options at http://dev.iron.io/worker/reference/cli/
Now that we have a working application, lets see how that same application would be run in AWS Lambda.
- Copy the
ironworker.jsfile into a new file calledlambda.js
cp ironworker.js lambda.js
- Remove the following blocks of code.
// outputs the payload params
console.log("params:", worker.params);
// outputs the actual config of the worker
console.log("config:", worker.config);
// outputs the task id that is being run
console.log("task_id:", worker.task_id);
- Wrap the function to run in the exports.handler
exports.handler = function(event, context) {
...
};
-
Modify the
worker.paramstoevent. -
Change the
process.exit();tocontext.fail(err);andcontext.succeed('Function completed'); -
Zip up the actual files, and upload into your Lambda function.