2

In following a tutorial, I am trying to set up an AWS Lambda function that will pass a SQL query to an AWS RDS Aurora Serverless MySQL database using the Data API and return the query results (presumably as a JSON).

The code I used is below (where the params are stored as environment variables):

const AWS = require('aws-sdk')
const RDS = new AWS.RDSDataService()

exports.handler = async (event, context) => {
    console.log(JSON.stringify(event, null, 2))  // Log the entire event passed in

    // Get the sqlStatement string value
    // TODO: Implement a more secure way (e.g. "escaping") the string to avoid SQL injection
    var sqlStatement = event.sqlStatement;

    // The Lambda environment variables for the Aurora Cluster Arn, Database Name, and the AWS Secrets Arn hosting the master credentials of the serverless db
    var DBSecretsStoreArn = process.env.DBSecretsStoreArn;
    var DBAuroraClusterArn = process.env.DBAuroraClusterArn;
    var DatabaseName = process.env.DatabaseName;

    const params = {
      awsSecretStoreArn: DBSecretsStoreArn,
      dbClusterOrInstanceArn: DBAuroraClusterArn,
      sqlStatements: sqlStatement,
      database: DatabaseName
    }

    try {
      let dbResponse = await RDS.executeSql(params)
      console.log(JSON.stringify(dbResponse, null, 2))

      return JSON.stringify(dbResponse)

    } catch (error) {
        console.log(error)
      return error
    }
}

I run the following test from the Lambda console (where "Bonds" is the name of an existing table in my database):

{
    "sqlStatement": "SELECT * FROM Bonds"
}

My test is logged as a success, with a blank output {} and the following error information logged:

INFO    TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Request'
    |     property 'response' -> object with constructor 'Response'
    --- property 'request' closes the circle
    at JSON.stringify (<anonymous>)
    at Runtime.exports.handler (/var/task/index.js:25:24)END

Does anyone know how I can successfully retrieve data with this method, and/or what the above error means?

OJT
  • 887
  • 1
  • 10
  • 26
  • You can't convert `circular object` to string using `JSON.stringify`, to check response you can console directly the `dbResponse` – Vibha Chosla Nov 27 '19 at 08:14
  • You can check on https://stackoverflow.com/questions/11616630/how-can-i-print-a-circular-structure-in-a-json-like-format for reference to convert into json string – Vibha Chosla Nov 27 '19 at 08:18

1 Answers1

4

RDS.executeSql(params) does not return a promise that you can await. It simply constructs a request object for you.

Replace it instead with await RDS.executeSql(params).promise() so you can get the value that you want.

References:

Noel Llevares
  • 15,018
  • 3
  • 57
  • 81
  • Thank you! That seemed to do the trick (for that error) -- I now get errors related to permissions for the lambda role -- I need it to be able to perform SELECT queries on the RDS database and pass on the results as JSON -- any insight into how this might be done? – OJT Nov 29 '19 at 22:31
  • *SELECT queries only... no database modifications. – OJT Nov 29 '19 at 22:37
  • @OJT For that you will need to give your Lambda IAM permissions to use `executeSql`. See this page for details: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html – Noel Llevares Dec 02 '19 at 01:38