Bragg SNS Middleware

raw JSON →
2.0.0 verified Thu Apr 23 auth: no javascript

bragg-sns is a specialized middleware designed for the `bragg` micro-framework, facilitating the processing of AWS SNS (Simple Notification Service) events as if they were conventional HTTP requests. This package abstracts the underlying SNS message structure, allowing developers to define routes for specific SNS topics using a `sns:TopicName` prefix within `bragg-router`. The core message content is then made available through `ctx.request.body`. The current stable version is 2.0.0, which notably enhanced functionality by adding support for SNS message attributes. The package integrates tightly with `bragg` and `bragg-router`, making it a suitable choice for building event-driven, serverless applications, particularly in AWS Lambda environments. It also provides topic name mapping capabilities, allowing for flexible event routing and consolidation via object or function-based transformations.

error Error: No handler found for path 'MyTopic'
cause The SNS route was defined without the required 'sns:' prefix.
fix
Change the route definition from router.post('MyTopic', ...) to router.post('sns:MyTopic', ...).
error TypeError: app.use is not a function
cause The `bragg` application instance (`app`) or `bragg-router` instance (`router`) was not correctly initialized by calling the required module as a function (e.g., `require('bragg')()` instead of `require('bragg')`).
fix
Ensure app and router are initialized with parentheses: const app = require('bragg')(); and const router = require('bragg-router')();.
error ReferenceError: require is not defined in ES module scope
cause Attempting to use `require()` syntax within an ECMAScript Module (ESM) file (e.g., a file ending in `.mjs` or when `"type": "module"` is set in `package.json`).
fix
If possible, rename your file to .cjs or configure your package.json with "type": "commonjs". Alternatively, use dynamic import() for CJS modules within ESM, or consider a bundling step.
gotcha The `sns:` prefix is mandatory when defining routes for SNS topics with `bragg-router`. Routes defined without this prefix will not be matched by `bragg-sns`.
fix Ensure all SNS event routes are prefixed, e.g., `router.post('sns:YourTopicName', ...)`.
gotcha Version 2.0.0 introduced support for SNS message attributes. While this is an additive feature, if your application previously assumed `ctx.request.body` would *only* contain the raw SNS message, the presence of message attributes might subtly change the structure or parsing needs, particularly if message attributes are encoded within the message payload.
fix Review how `ctx.request.body` is consumed in your handlers to ensure it correctly parses messages that may now include attribute data or have a slightly altered structure due to attribute handling in v2.0.0.
gotcha This package, and the underlying `bragg` framework, are primarily designed for CommonJS (`require()`) environments. While Node.js has robust interoperability, direct usage in modern ESM (`import`) modules might require specific configurations or transpilation, potentially leading to 'require is not defined' errors.
fix For ESM projects, consider using a CommonJS wrapper, configuring your build system to handle CJS modules, or sticking to `require()` within a CJS-compatible file.
npm install bragg-sns
yarn add bragg-sns
pnpm add bragg-sns

This quickstart demonstrates setting up `bragg` with `bragg-sns` and `bragg-router` to handle SNS events, including a simple topic mapping and local simulation for testing.

const app = require('bragg')();
const router = require('bragg-router')();
const sns = require('bragg-sns');

// Basic handler for SNS events from 'MyTopic'
router.post('sns:MyTopic', ctx => {
    console.log('Received SNS event from MyTopic:', ctx.request.body);
    ctx.body = { status: 'Success', message: 'Event processed' };
});

// Example of topic mapping: Events from 'DevTopic' are routed to 'MyTopic' handler
app.use(sns({
    DevTopic: 'MyTopic'
}));

// Apply the router middleware
app.use(router.routes());

// This function can be exported as an AWS Lambda handler
exports.handler = app.listen();

// For local testing (optional, not part of typical Lambda setup)
if (require.main === module) {
    // Simulate an SNS event for testing
    const simulateSnsEvent = async (topicName, message) => {
        const context = {}; // Lambda context object
        const event = {
            Records: [{
                Sns: {
                    TopicArn: `arn:aws:sns:us-east-1:123456789012:${topicName}`,
                    Message: JSON.stringify(message),
                    MessageAttributes: {}
                }
            }]
        };
        console.log(`Simulating SNS event for ${topicName}...`);
        await exports.handler(event, context);
        console.log('Simulation complete.');
    };
    
    simulateSnsEvent('MyTopic', { data: 'hello world from MyTopic' });
    simulateSnsEvent('DevTopic', { environment: 'development', payload: 'test data' });
}