7/12/18 by Dan

Query DynamoDB Table from a Lambda Function with NodeJS and Apex Up

In this blog post I cover setting up a Lambda Function with Apex Up and querying a DynamoDB table.

I recently built an Indoor Environmental Sensor Pack that collects office conditions and logs them to DynamoDB through AWS IoT core. For more on that, check out this post.

One of the elements of that project was querying the data in DynamoDB to display it on our office dashboard and our site. To do this I wrote a NodeJS lambda function that queries DynamoDB and returns a JSON payload.

I used Apex Up to deploy the lambda function. Up makes deploying and managing apps on AWS lambda much easier.

I put together the steps I took to do this. I hope it helps!


Install Apex Up and set up your AWS account. Follow the Up docs.

Next, create a new directory and add a app.js.

mkdir hello
cd hello


const http = require('http')
const { PORT = 3000 } = process.env

http.createServer((req, res) => {
  res.end('Hello World\n')

Next deploy it with:



Test your function!

$ curl `up url`
Hello World

Query DynamoDB

Next lets query DynamoDB and return the results.

// Use NodeJS's built in http server
var http = require('http');

// Up specifies the port at runtime
const {PORT = 3000} = process.env;

// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');

// Set the region
AWS.config.update({region: 'us-east-1'});

// Create DynamoDB service object
var dynamo = new AWS.DynamoDB({apiVersion: '2012-08-10'});

  .createServer(function(req, res) {
    // Set CORS headers
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Request-Method', '*');
    res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
    res.setHeader('Access-Control-Allow-Headers', '*');
    if (req.method === 'OPTIONS') {

    // Set up query parameters
    var params = {
      TableName: 'MyTableName',
      Limit: 10,
      // Set ScanIndexForward to false to display most recent entries first
      ScanIndexForward: false,
      KeyConditionExpression: 'MyPartitionKey = :MyPartitionKey',
      ExpressionAttributeValues: {
        ':MyPartitionKey': {
          S: 'MyPartitionValue',

    dynamo.query(params, function(err, data) {
      if (err) {
        //write a response to the client
        res.write('Internal Server Error');
      } else {
        // Format results for JSON payload
        let response = data.Items.map(item => ({
          timestamp: item.timestamp.S,
          payload: {
            temp: item.payload.M.temp.N,

        // Return results

Be sure to replace "MyTable", "MyPartitionKey" and "MyPartitionValue", etc with your actual DynamoDB values!

Grant Lambda Function Access to Dynamo

Next we need to grant the lambda access to the DynamoDB table. Up provides configuration section in up.json for defining policies:

  ... other settings
  "lambda": {
    "role": "arn:aws:iam::[SOME NUMBERS]:role/[MY PROJECT]_lambda_function",
    "policy": [
        "Effect": "Allow",
        "Resource": "arn:aws:dynamodb:us-east-1:[SOME NUMBERS]:table/[MY Table]",
        "Action": [

Deploy again to apply the policy.

At this point, you can run

$ curl `up url` | jq "." 

(if you don't have jq installed, install it with brew install jq. It is a JSON formatter for the commandline).

And get your DynamoDB JSON payload.

For example: results

You can also visit your up url in the browser to see your data.

You can debug the function with

up logs 

Happy hacking!

By: Dan

Dan is an engineer with a background in software development. He graduated from GVSU with BSEE in 2011 and has been building ever since. His tools of choice are C, JavaScript, Elixir and everything that AWS offers.

Like what you see?

About Us

DEB Associates helps companies through the entire electronics design process. Our team is smart, reliable, and deeply knowledgeable about the intricacies of circuit design, PCB layout, and EMC.

DEB Associates 2018