sqsd-handler

Express middleware for handling SQS messages in AWS ElasticBeanstalk worker-tier apps.

Usage no npm install needed!

<script type="module">
  import sqsdHandler from 'https://cdn.skypack.dev/sqsd-handler';
</script>

README

Build Status Coverage Status

Introduction

sqsd-handler is Express middleware for handling SQS messages posted by the AWS ElasticBeanstalk worker-tier utility, SQSD.

Quick Start

npm install sqsd-handler --save

Then:

var express = require("express");
var app = express();
var sqsdHandler = require("sqsd-handler");

// Create message handler
var handler = sqsdHandler.create(function (msg) {
    console.log("Received worker message", msg);
});

// Mount handler to Express stack at ElasticBeanstalk worker path
app.use("/", handler);

Usage

Sqsd-handler supports a number of Elastic Beanstalk worker-tier SQS messaging use cases:

  • Messages sent to the environment's worker queue
  • Scheduled task messages
  • Identifying SNS notification messages and parsing SNS fields
  • Logging message handling activity
  • Promises

Additionally, the API provides methods for error handling and logging.

Worker Queue Messages

Sqsd-handler middleware evaluates each incoming message to route it to the most appropriate available handler function. If no specific handler is available, messages are passed to a generic handler, as shown below. In the following code sample, sqsd-handler middleware is created to process all messages posted to the route. Specifying a default handler function is highly recommended for troubleshooting, even if you define specific handlers such that it should not be called.

var sqsdHandler = require("sqsd-handler");
var express = require("express");
var app = express();

var handler = sqsdHandler.create(function (msg) {
    console.log("Received worker queue message", msg);
});

app.use("/", handler);

Message Format

The HTTP headers supplied by sqsd are converted into properties of the message object. The raw text of the message body is contained in the body field. If the content type is application/json, the body is parsed and the resulting object stored as the payload field.

{
    body: '{"job": "doStuff" }',
    msgid: '9d1414a9-44d9-43e1-b3e1-b8f44fc1815a',
    receiveCount: '1',
    firstReceivedAt: '2015-06-15T16:26:42Z',
    sentAt: '2015-06-15T16:26:42Z',
    path: '',
    senderId: 'AIBAIENGLVXQVUPQSWNI3',
    queue: 'awseb-e-feey68hp6j-stack-AWSEBWorkerQueue-QPOHTMVZGWM',
    userAgent: 'aws-sqsd/2.0',
    payload: { job: 'doStuff' }
}

The payload would be accessible as follows:

var handler = sqsdHandler.create(function (msg) {
    if (msg.payload.job === "doStuff") {
        ...
    }
});

Scheduled Task Messages

Elastic Beanstalk permits configuring scheduled tasks in cron.yaml, which sqsd then posts to your configured route. Consider the following cron.yaml that defines one task 'job1':

version: 1
cron:
  - name: "job1"
    url: "/scheduled"
    schedule: "* * * * *"

The code snippet below shows how to handle this scheduled task using sqsd-handler.

var scheduledTaskHandler = sqsdHandler.create();

scheduledTaskHandler.task("job1", function (msg) {
    console.log("Scheduled task 'job1': ", msg);
});

app.use("/scheduled", scheduledTaskHandler);

It is important that the task name passed to task(taskName, handler) match the name of the job in cron.yaml, and that the scheduledTaskHandler middleware is mounted on the /scheduled route.

Scheduled task messages have some additional properties from sqsd, including the scheduledAt date/time and taskName parameters.

{
  msgid: 'd5475b16-d83f-444f-a440-557ca8f86079',
  receiveCount: '1',
  firstReceivedAt: '2015-06-15T16:12:59Z',
  sentAt: '2015-06-15T16:12:59Z',
  scheduledAt: '2015-06-15T16:13:00Z',
  path: '/scheduled',
  senderId: 'ARHAJ53IC6PWBEW34I4PC:i-fd67490b',
  queue: 'awseb-e-feey68hp6j-stack-AWSEBWorkerQueue-QPOHTMVZGWM',
  taskName: 'job1',
  userAgent: 'aws-sqsd/2.0'
 }

SNS Notification Messages

SNS notifications require slightly different handling, because they contain a nested SNS payload wrapped inside the SQS message that arrives at your worker queue. In the following code snippet, you can see how to handle and access the SNS message content through the sns property.

var sqsdHandler = require("sqsd-handler");
var express = require("express");
var app = express();

var snsHandler = sqsdHandler.sns(function (msg) {
    console.log("Received SNS notification", msg.sns);
});

app.use("/messages", snsHandler);

Logging Messages

You can use an optional logging handler to log messages. The logging handler will be called for all messages posted to the handler's route, after the handling function has been called.

scheduledTaskHandler.log(function (msg) {
    console.log("Logging msgid" + msg.msgid);
});

Promises

Sqsd-handler uses Promises, so you can return a promise from your handler and sqsd-handler will wait for the Promise to settle, then set the response code to 200 if the promise resolves, 500 if it rejects.

var Promise = require("bluebird");

var handler = sqsdHandler.create(function (msg) {
    return Promise.resolve("done!");
});

Demo

Please see the sqsd-handler-demo project for a working Elastic Beanstalk project demonstrating sqsd-handler.

License

MIT