Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

data-api-client

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

data-api-client - npm Package Compare versions

Comparing version 1.3.0 to 2.0.0-beta.0

85

index.js

@@ -11,3 +11,3 @@ 'use strict'

* @author Jeremy Daly <jeremy@jeremydaly.com>
* @version 1.2.0
* @version 2.0.0-beta
* @license MIT

@@ -18,3 +18,10 @@ */

// outside of a Lambda execution environment, it must be manually installed.
const AWS = require('aws-sdk')
const {
RDSDataClient,
ExecuteStatementCommand,
BatchExecuteStatementCommand,
BeginTransactionCommand,
CommitTransactionCommand,
RollbackTransactionCommand
} = require('@aws-sdk/client-rds-data')

@@ -432,4 +439,4 @@ // Require sqlstring to add additional escaping capabilities

let result = await (isBatch
? config.RDS.batchExecuteStatement(params).promise()
: config.RDS.executeStatement(params).promise())
? config.methods.batchExecuteStatement(params)
: config.methods.executeStatement(params))

@@ -440,5 +447,5 @@ // Format and return the results

if (this && this.rollback) {
let rollback = await config.RDS.rollbackTransaction(
let rollback = await config.methods.rollbackTransaction(
pick(params, ['resourceArn', 'secretArn', 'transactionId'])
).promise()
)

@@ -466,3 +473,3 @@ this.rollback(e, rollback)

formatOptions: parseFormatOptions(config, args), // add formatOptions
RDS: config.RDS // reference the RDSDataService instance
methods: config.methods // pass the methods
})

@@ -496,5 +503,5 @@

// Start a transaction
const { transactionId } = await config.RDS.beginTransaction(
const { transactionId } = await config.methods.beginTransaction(
pick(config, ['resourceArn', 'secretArn', 'database'])
).promise()
)

@@ -513,5 +520,5 @@ // Add transactionId to the config

// Commit our transaction
const { transactionStatus } = await txConfig.RDS.commitTransaction(
const { transactionStatus } = await txConfig.methods.commitTransaction(
pick(config, ['resourceArn', 'secretArn', 'transactionId'])
).promise()
)

@@ -545,5 +552,2 @@ // Add the transaction status to the results

* @param {boolean} [params.formatOptions.treatAsLocalDate=false]
* @param {boolean} [params.keepAlive] DEPRECATED
* @param {boolean} [params.sslEnabled=true] DEPRECATED
* @param {string} [params.region] DEPRECATED
*

@@ -565,7 +569,2 @@ */

// Disable ssl if wanted for local development
if (params.sslEnabled === false) {
options.sslEnabled = false
}
// Set the configuration for this instance

@@ -606,5 +605,34 @@ const config = {

// TODO: Put this in a separate module for testing?
// Create an instance of RDSDataService
RDS: params.AWS ? new params.AWS.RDSDataService(options) : new AWS.RDSDataService(options)
client: params.wrapper ? params.wrapper(new RDSDataClient(options)) : new RDSDataClient(options),
// Create simplified v3 RDSDataClient method
methods: {
executeStatement: async (args) => {
const command = new ExecuteStatementCommand(
mergeConfig(pick(config, ['resourceArn', 'secretArn', 'database']), args)
)
return await config.client.send(command)
},
batchExecuteStatement: async (args) => {
const command = new BatchExecuteStatementCommand(
mergeConfig(pick(config, ['resourceArn', 'secretArn', 'database']), args)
)
return await config.client.send(command)
},
beginTransaction: async (args) => {
const command = new BeginTransactionCommand(
mergeConfig(pick(config, ['resourceArn', 'secretArn', 'database']), args)
)
return await config.client.send(command)
},
commitTransaction: async (args) => {
const command = new CommitTransactionCommand(mergeConfig(pick(config, ['resourceArn', 'secretArn']), args))
return await config.client.send(command)
},
rollbackTransaction: async (args) => {
const command = new RollbackTransactionCommand(mergeConfig(pick(config, ['resourceArn', 'secretArn']), args))
return await config.client.send(command)
}
}
} // end config

@@ -619,15 +647,4 @@

// Export promisified versions of the RDSDataService methods
batchExecuteStatement: (args) =>
config.RDS.batchExecuteStatement(
mergeConfig(pick(config, ['resourceArn', 'secretArn', 'database']), args)
).promise(),
beginTransaction: (args) =>
config.RDS.beginTransaction(mergeConfig(pick(config, ['resourceArn', 'secretArn', 'database']), args)).promise(),
commitTransaction: (args) =>
config.RDS.commitTransaction(mergeConfig(pick(config, ['resourceArn', 'secretArn']), args)).promise(),
executeStatement: (args) =>
config.RDS.executeStatement(mergeConfig(pick(config, ['resourceArn', 'secretArn', 'database']), args)).promise(),
rollbackTransaction: (args) =>
config.RDS.rollbackTransaction(mergeConfig(pick(config, ['resourceArn', 'secretArn']), args)).promise()
// Export simplified v3 RDSDataClient methods
...config.methods
}

@@ -634,0 +651,0 @@ } // end exports

{
"name": "data-api-client",
"version": "1.3.0",
"version": "2.0.0-beta.0",
"description": "A lightweight wrapper that simplifies working with the Amazon Aurora Serverless Data API",

@@ -28,10 +28,9 @@ "main": "index.js",

"devDependencies": {
"aws-sdk": "^2.811.0",
"eslint": "^8.12.0",
"eslint-config-prettier": "^8.5.0",
"jest": "^27.5.1",
"prettier": "^2.6.2",
"rewire": "^6.0.0"
},
"dependencies": {
"@aws-sdk/client-rds-data": "^3.58.0",
"sqlstring": "^2.3.2"

@@ -38,0 +37,0 @@ },

251

README.md

@@ -7,4 +7,6 @@ ![Aurora Serverless Data API Client](https://user-images.githubusercontent.com/2053544/79285017-44053500-7e8a-11ea-8515-998ccf9c2d2e.png)

The **Data API Client** is a lightweight wrapper that simplifies working with the Amazon Aurora Serverless Data API by abstracting away the notion of field values. This abstraction annotates native JavaScript types supplied as input parameters, as well as converts annotated response data to native JavaScript types. It's basically a [DocumentClient](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html) for the Data API. It also promisifies the `AWS.RDSDataService` client to make working with `async/await` or Promise chains easier AND dramatically simplifies **transactions**.
## v2.0 BETA with support for AWS SDK v3
The **Data API Client** is a lightweight wrapper that simplifies working with the Amazon Aurora Serverless Data API by abstracting away the notion of field values. This abstraction annotates native JavaScript types supplied as input parameters, as well as converts annotated response data to native JavaScript types. It's basically a [DocumentClient](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html) for the Data API. It also exposes simplified versions of the native AWS SDK v3 `RDSDataClient` methods to make working with `async/await` or Promise chains easier AND dramatically simplifies **transactions**.
For more information about the Aurora Serverless Data API, you can review the [official documentation](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html) or read [Aurora Serverless Data API: An (updated) First Look](https://www.jeremydaly.com/aurora-serverless-data-api-a-first-look/) for some more insights on performance.

@@ -37,30 +39,27 @@

// SELECT with named parameters
let resultParams = await data.query(
`SELECT * FROM myTable WHERE id = :id`,
{ id: 2 }
)
let resultParams = await data.query(`SELECT * FROM myTable WHERE id = :id`, {
id: 2
})
// { records: [ { id: 2, name: 'Mike', age: 52 } ] }
// INSERT with named parameters
let insert = await data.query(
`INSERT INTO myTable (name,age,has_curls) VALUES(:name,:age,:curls)`,
{ name: 'Greg', age: 18, curls: false }
)
let insert = await data.query(`INSERT INTO myTable (name,age,has_curls) VALUES(:name,:age,:curls)`, {
name: 'Greg',
age: 18,
curls: false
})
// BATCH INSERT with named parameters
let batchInsert = await data.query(
`INSERT INTO myTable (name,age,has_curls) VALUES(:name,:age,:curls)`,
[
[{ name: 'Marcia', age: 17, curls: false }],
[{ name: 'Peter', age: 15, curls: false }],
[{ name: 'Jan', age: 15, curls: false }],
[{ name: 'Cindy', age: 12, curls: true }],
[{ name: 'Bobby', age: 12, curls: false }]
]
)
let batchInsert = await data.query(`INSERT INTO myTable (name,age,has_curls) VALUES(:name,:age,:curls)`, [
[{ name: 'Marcia', age: 17, curls: false }],
[{ name: 'Peter', age: 15, curls: false }],
[{ name: 'Jan', age: 15, curls: false }],
[{ name: 'Cindy', age: 12, curls: true }],
[{ name: 'Bobby', age: 12, curls: false }]
])
// Update with named parameters
let update = await data.query(
`UPDATE myTable SET age = :age WHERE id = :id`,
{ age: 13, id: 5 }
)
let update = await data.query(`UPDATE myTable SET age = :age WHERE id = :id`, {
age: 13,
id: 5
})

@@ -78,6 +77,3 @@ // Delete with named parameters

database: 'myOtherDatabase',
parameters: [
{ id: 123},
{ name: 'isActive', value: { booleanValue: true } }
]
parameters: [{ id: 123 }, { name: 'isActive', value: { booleanValue: true } }]
})

@@ -87,12 +83,10 @@ ```

## Why do I need this?
The [Data API](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html) requires you to specify data types when passing in parameters. The basic `INSERT` example above would look like this using the native `AWS.RDSDataService` class:
The [Data API](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html) requires you to specify data types when passing in parameters. The basic `INSERT` example above would look like this using the native `RDSDataClient` class:
```javascript
const AWS = require('aws-sdk')
const data = new AWS.RDSDataService()
const { RDSDataClient, ExecuteStatementCommand } = require('@aws-sdk/client-rds-data')
const client = new RDSDataClient({ region: 'us-east-1' })
/*** Assuming we're in an async function ***/
// INSERT with named parameters
let insert = await data.executeStatement({
const params = {
secretArn: 'arn:aws:secretsmanager:us-east-1:XXXXXXXXXXXX:secret:mySecret',

@@ -107,6 +101,16 @@ resourceArn: 'arn:aws:rds:us-east-1:XXXXXXXXXXXX:cluster:my-cluster-name',

]
).promise()
}
const command = new ExecuteStatementCommand(params)
// async/await.
try {
const data = await client.send(command)
// process data.
} catch (error) {
// error handling.
}
```
Specifying all of those data types in the parameters is a bit clunky. In addition to requiring types for parameters, it also returns each field as an object with its value assigned to a key that represents its data type, like this:
Specifying all of those data types in the parameters and writing all that SDK code is a bit clunky. In addition to requiring types for parameters, it also returns each field as an object with its value assigned to a key that represents its data type, like this:

@@ -127,5 +131,7 @@ ```javascript

```
Not only are there no column names, but you have to pull the value from the data type field. Lots of extra work that the **Data API Client** handles automatically for you. 😀
## Installation and Setup
```

@@ -141,17 +147,15 @@ npm i data-api-client

| Property | Type | Description | Default |
| -------- | ---- | ----------- | ------- |
| AWS | `AWS` | A custom `aws-sdk` instance | |
| resourceArn | `string` | The ARN of your Aurora Serverless Cluster. This value is *required*, but can be overridden when querying. | |
| secretArn | `string` | The ARN of the secret associated with your database credentials. This is *required*, but can be overridden when querying. | |
| database | `string` | *Optional* default database to use with queries. Can be overridden when querying. | |
| engine | `mysql` or `pg` | The type of database engine you're connecting to (MySQL or Postgres). | `mysql` |
| hydrateColumnNames | `boolean` | When `true`, results will be returned as objects with column names as keys. If `false`, results will be returned as an array of values. | `true` |
| ~~keepAlive~~ (deprecated) | `boolean` | See [Connection Reuse](#connection-reuse) below. | |
| ~~sslEnabled~~ (deprecated) | `boolean` | Set this in the `options` | `true` |
| options | `object` | An *optional* configuration object that is passed directly into the RDSDataService constructor. See [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/RDSDataService.html#constructor-property) for available options. | `{}` |
| ~~region~~ (deprecated) | `string` | Set this in the `options` | |
| formatOptions | `object` | Formatting options to auto parse dates and coerce native JavaScript date objects to MySQL supported date formats. Valid keys are `deserializeDate` and `treatAsLocalDate`. Both accept boolean values. | Both `false` |
| Property | Type | Description | Default |
| ------------------ | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| resourceArn | `string` | The ARN of your Aurora Serverless Cluster. This value is _required_, but can be overridden when querying. | |
| secretArn | `string` | The ARN of the secret associated with your database credentials. This is _required_, but can be overridden when querying. | |
| database | `string` | _Optional_ default database to use with queries. Can be overridden when querying. | |
| engine | `mysql` or `pg` | The type of database engine you're connecting to (MySQL or Postgres). | `mysql` |
| hydrateColumnNames | `boolean` | When `true`, results will be returned as objects with column names as keys. If `false`, results will be returned as an array of values. | `true` |
| options | `object` | An _optional_ configuration object that is passed directly into the v3 RDSDataClient constructor. Use this to set `region`, `tls`, etc. See [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-rds-data/interfaces/rdsdataclientconfig.html) for available options. | `{}` |
| formatOptions | `object` | Formatting options to auto parse dates and coerce native JavaScript date objects to MySQL supported date formats. Valid keys are `deserializeDate` and `treatAsLocalDate`. Both accept boolean values. | Both `false` |
| wrapper | `function` | A custom wrapper around `@aws-sdk/client-rds-data` used to enable AWS X-Ray. | |
### Connection Reuse
It is recommended to enable connection reuse as this dramatically decreases the latency of subsequent calls to the AWS API. This can be done by setting an environment variable

@@ -162,3 +166,3 @@ `AWS_NODEJS_CONNECTION_REUSE_ENABLED=1`. For more information see the [AWS SDK documentation](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/node-reusing-connections.html).

The **Data API Client** wraps the [RDSDataService Class](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/RDSDataService.html), providing you with a number of convenience features to make your workflow easier. The module also exposes **promisified** versions of all the standard `RDSDataService` methods, with your default configuration information already merged in. 😉
The **Data API Client** wraps the AWS SDK v3 [RDSDataClient Class](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-rds-data/index.html), providing you with a number of convenience features to make your workflow easier. The module also exposes simplified versions of all the native `RDSDataClient` methods, with your default configuration information already merged in. 😉

@@ -177,2 +181,3 @@ To use the Data API Client, require the module and instantiate it with your [Configuration options](#configuration-options). If you are using it with AWS Lambda, require it **OUTSIDE** your main handler function. This will allow you to reuse the initialized module on subsequent invocations.

### Running a query
Once initialized, running a query is super simple. Use the `query()` method and pass in your SQL statement:

@@ -185,4 +190,5 @@

By default, this will return your rows as an array of objects with column names as property names:
```javascript
[
;[
{ id: 1, name: 'Alice', age: null },

@@ -197,3 +203,4 @@ { id: 2, name: 'Mike', age: 52 },

```javascript
let result = await data.query(`
let result = await data.query(
`
SELECT * FROM myTable WHERE id = :id AND created > :createDate`,

@@ -204,13 +211,11 @@ { id: 2, createDate: '2019-06-01' }

The Data API Client will automatically convert your parameters into the correct Data API parameter format using native JavaScript types. If you prefer to use the clunky format, or you need more control over the data type, you can just pass in the `RDSDataService` format:
The Data API Client will automatically convert your parameters into the correct Data API parameter format using native JavaScript types. If you prefer to use the clunky format, or you need more control over the data type, you can just pass in the `RDSDataClient` format:
```javascript
let result = await data.query(
`SELECT * FROM myTable WHERE id = :id AND created > :createDate`,
[ // An array of objects is totally cool, too. We'll merge them for you.
{ id: 2 },
// Data API Client just passes this straight on through
{ name: 'createDate', value: { blobValue: new Buffer('2019-06-01') } }
]
)
let result = await data.query(`SELECT * FROM myTable WHERE id = :id AND created > :createDate`, [
// An array of objects is totally cool, too. We'll merge them for you.
{ id: 2 },
// Data API Client just passes this straight on through
{ name: 'createDate', value: { blobValue: new Buffer('2019-06-01') } }
])
```

@@ -225,24 +230,22 @@

database: 'someOtherDatabase', // override default database
schema: 'mySchema', // RDSDataService config option
continueAfterTimeout: true, // RDSDataService config option (non-batch only)
includeResultMetadata: true, // RDSDataService config option (non-batch only)
schema: 'mySchema', // RDSDataClient config option
continueAfterTimeout: true, // RDSDataClient config option (non-batch only)
includeResultMetadata: true, // RDSDataClient config option (non-batch only)
hydrateColumnNames: false, // Returns each record as an arrays of values
transactionId: 'AQC5SRDIm...ZHXP/WORU=' // RDSDataService config option
transactionId: 'AQC5SRDIm...ZHXP/WORU=' // RDSDataClient config option
}
```
Sometimes you might want to have *dynamic identifiers* in your SQL statements. Unfortunately, the `RDSDataService` doesn't do this, but the **Data API Client** does! We're using the [sqlstring](https://github.com/mysqljs/sqlstring) module under the hood, so as long as [NO_BACKSLASH_ESCAPES](https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_backslash_escapes) SQL mode is disabled (which is the default state for Aurora Serverless), you're good to go. Use a double colon (`::`) prefix to create *named identifiers* and you can do cool things like this:
Sometimes you might want to have _dynamic identifiers_ in your SQL statements. Unfortunately, the `RDSDataClient` doesn't do this, but the **Data API Client** does! We're using the [sqlstring](https://github.com/mysqljs/sqlstring) module under the hood, so as long as [NO_BACKSLASH_ESCAPES](https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_backslash_escapes) SQL mode is disabled (which is the default state for Aurora Serverless), you're good to go. Use a double colon (`::`) prefix to create _named identifiers_ and you can do cool things like this:
```javascript
let result = await data.query(
`SELECT ::fields FROM ::table WHERE id > :id`,
{
fields: ['id','name','created'],
table: 'table_' + someScaryUserInput, // someScaryUserInput = 123abc
id: 1
}
)
let result = await data.query(`SELECT ::fields FROM ::table WHERE id > :id`, {
fields: ['id', 'name', 'created'],
table: 'table_' + someScaryUserInput, // someScaryUserInput = 123abc
id: 1
})
```
Which will produce a query like this:
```sql

@@ -252,5 +255,6 @@ SELECT `id`, `name`, `created` FROM `table_123abc` WHERE id > :id LIMIT 10

You'll notice that we leave the *named parameters* alone. Anything that Data API and the `RDSDataService` Class currently handles, we defer to them.
You'll notice that we leave the _named parameters_ alone. Anything that Data API and the `RDSDataClient` Class currently handles, we defer to them.
### Type-Casting
The Aurora Data API can sometimes give you trouble with certain data types, such as uuid, unless you explicitly cast them. While you can certainly do this manually in your SQL string, the Data API Client offers a really easy way to handle this for you.

@@ -285,17 +289,15 @@

### Batch Queries
The `RDSDataService` Class provides a `batchExecuteStatement` method that allows you to execute a prepared statement multiple times using different parameter sets. This is only allowed for `INSERT`, `UPDATE` and `DELETE` queries, but is much more efficient than issuing multiple `executeStatement` calls. The Data API Client handles the switching for you based on *how* you send in your parameters.
The `RDSDataClient` Class provides a `batchExecuteStatement` method that allows you to execute a prepared statement multiple times using different parameter sets. This is only allowed for `INSERT`, `UPDATE` and `DELETE` queries, but is much more efficient than issuing multiple `executeStatement` calls. The Data API Client handles the switching for you based on _how_ you send in your parameters.
To issue a batch query, use the `query()` method (either by passing an object or using the two arity form), and provide multiple parameter sets as nested arrays. For example, if you wanted to update multiple records at once, your query might look like this:
```javascript
let result = await data.query(
`UPDATE myTable SET name = :newName WHERE id = :id`,
[
[ { id: 1, newName: 'Alice Franklin' } ],
[ { id: 7, newName: 'Jan Glass' } ]
]
)
let result = await data.query(`UPDATE myTable SET name = :newName WHERE id = :id`, [
[{ id: 1, newName: 'Alice Franklin' }],
[{ id: 7, newName: 'Jan Glass' }]
])
```
You can also use *named identifiers* in batch queries, which will update and escape your SQL statement. **ONLY** parameters from the first parameter set will be used to update the query. Subsequent parameter sets will only update *named parameters* supported by the Data API.
You can also use _named identifiers_ in batch queries, which will update and escape your SQL statement. **ONLY** parameters from the first parameter set will be used to update the query. Subsequent parameter sets will only update _named parameters_ supported by the Data API.

@@ -305,5 +307,7 @@ Whenever a batch query is executed, it returns an `updateResults` field. Other than for `INSERT` statements, however, there is no useful feedback provided by this field.

### Retrieving Insert IDs
The Data API returns a `generatedFields` array that contains the value of auto-incrementing primary keys. If this value is returned, the Data API Client will parse this and return it as the `insertId`. This also works for batch queries as well.
## Transaction Support
Transaction support in the Data API Client has been dramatically simplified. Start a new transaction using the `transaction()` method, and then chain queries using the `query()` method. The `query()` method supports all standard query options. Alternatively, you can specify a function as the only argument in a `query()` method call and return the arguments as an array of values. The function receives two arguments, the result of the last query executed, and an array containing all the previous query results. This is useful if you need values from a previous query as part of your transaction.

@@ -324,6 +328,9 @@

```javascript
let results = await mysql.transaction()
let results = await mysql
.transaction()
.query('INSERT INTO myTable (name) VALUES(:name)', { name: 'Tiger' })
.query((r) => [ 'UPDATE myTable SET age = :age WHERE id = :id', { age: 4, id: r.insertId } ])
.rollback((e,status) => { /* do something with the error */ }) // optional
.query((r) => ['UPDATE myTable SET age = :age WHERE id = :id', { age: 4, id: r.insertId }])
.rollback((e, status) => {
/* do something with the error */
}) // optional
.commit() // execute the queries

@@ -338,3 +345,4 @@ ```

The Data API Client exposes *promisified* versions of the five RDSDataService methods. These are:
The Data API Client exposes simplified versions of the five `RDSDataClient` methods. These are:
- `batchExecuteStatement`

@@ -358,22 +366,13 @@ - `beginTransaction`

## Custom AWS instance
## Custom SDK Wrapper
`data-api-client` allows for introducing a custom `AWS` as a parameter. This parameter is optional. If not present - `data-api-client` will fall back to the default `AWS` instance that comes with the library.
`data-api-client` allows you to wrap the instance of `RDSDataClient` to enable additional features like AWS X-Ray. You can specify a function using the optional `wrapper` paramenter. The function will receive one parameter which contains an instantiated `RDSDataClient` instance.
```javascript
// Instantiate data-api-client with a custom AWS instance
const data = require('data-api-client')({
AWS: customAWS,
...
})
```
// Import X-Ray
const AWSXRay = require('aws-xray-sdk');
Custom AWS parameter allows to introduce, e.g. tracing Data API calls through X-Ray with:
```javascript
const AWSXRay = require('aws-xray-sdk')
const AWS = AWSXRay.captureAWS(require('aws-sdk'))
// Instantiate data-api-client with the AWSXRay.captureAWSv3Client wrapper
const data = require('data-api-client')({
AWS: AWS,
wrapper: AWSXRay.captureAWSv3Client,
...

@@ -384,7 +383,9 @@ })

## Data API Limitations / Wonkiness
The first GA release of the Data API has *a lot* of promise, unfortunately, there are still quite a few things that make it a bit wonky and may require you to implement some workarounds. I've outlined some of my findings below.
The first GA release of the Data API has _a lot_ of promise, unfortunately, there are still quite a few things that make it a bit wonky and may require you to implement some workarounds. I've outlined some of my findings below.
### You can't send in an array of values
The GitHub repo for RDSDataService mentions something about `arrayValues`, but I've been unable to get arrays (including TypedArrays and Buffers) to be used for parameters with `IN` clauses. For example, the following query will **NOT** work:
The GitHub repo for RDSDataClient mentions something about `arrayValues`, but I've been unable to get arrays (including TypedArrays and Buffers) to be used for parameters with `IN` clauses. For example, the following query will **NOT** work:
```javascript

@@ -405,5 +406,7 @@ let result = await data.executeStatement({

### ~~Named parameters MUST be sent in order~~
~~Read that again if you need to. So parameters have to be **BOTH** named and *in order*, otherwise the query **may** fail. I stress **may**, because if you send in two fields of compatible type in the wrong order, the query will work, just with your values flipped. 🤦🏻‍♂️ Watch out for this one.~~ 👈This was fixed!
~~Read that again if you need to. So parameters have to be **BOTH** named and _in order_, otherwise the query **may** fail. I stress **may**, because if you send in two fields of compatible type in the wrong order, the query will work, just with your values flipped. 🤦🏻‍♂️ Watch out for this one.~~ 👈This was fixed!
### You can't parameterize identifiers
If you want to use dynamic column or field names, there is no way to do it automatically with the Data API. The `mysql` package, for example, lets you use `??` to dynamically insert escaped identifiers. Something like the example below is currently not possible.

@@ -427,7 +430,8 @@

### Batch statements do not give you updated record counts
### Batch statements do not give you updated record counts
This one is a bit frustrating. If you execute a standard `executeStatement`, then it will return a `numberOfRecordsUpdated` field for `UPDATE` and `DELETE` queries. This is handy for knowing if your query succeeded. Unfortunately, a `batchExecuteStatement` does not return this field for you.
## Enabling Data API
In order to use the Data API, you must enable it on your Aurora Serverless Cluster and create a Secret. You also must grant your execution environment a number of permission as outlined in the following sections.

@@ -439,3 +443,3 @@

You need to modify your Aurora Serverless cluster by clicking “ACTIONS” and then “Modify Cluster”. Just check the Data API box in the *Network & Security* section and you’re good to go. Remember that your Aurora Serverless cluster still runs in a VPC, even though you don’t need to run your Lambdas in a VPC to access it via the Data API.
You need to modify your Aurora Serverless cluster by clicking “ACTIONS” and then “Modify Cluster”. Just check the Data API box in the _Network & Security_ section and you’re good to go. Remember that your Aurora Serverless cluster still runs in a VPC, even though you don’t need to run your Lambdas in a VPC to access it via the Data API.

@@ -448,3 +452,2 @@ ### Set up a secret in the Secrets Manager

Next we give it a name, this is important, because this will be part of the arn when we set up permissions later. You can give it a description as well so you don’t forget what this secret is about when you look at it in a few weeks.

@@ -463,20 +466,22 @@

**YAML:**
```yaml
Statement:
- Effect: "Allow"
- Effect: 'Allow'
Action:
- "rds-data:ExecuteSql"
- "rds-data:ExecuteStatement"
- "rds-data:BatchExecuteStatement"
- "rds-data:BeginTransaction"
- "rds-data:RollbackTransaction"
- "rds-data:CommitTransaction"
Resource: "*"
- Effect: "Allow"
- 'rds-data:ExecuteSql'
- 'rds-data:ExecuteStatement'
- 'rds-data:BatchExecuteStatement'
- 'rds-data:BeginTransaction'
- 'rds-data:RollbackTransaction'
- 'rds-data:CommitTransaction'
Resource: '*'
- Effect: 'Allow'
Action:
- "secretsmanager:GetSecretValue"
Resource: "arn:aws:secretsmanager:{REGION}:{ACCOUNT-ID}:secret:{PATH-TO-SECRET}/*"
- 'secretsmanager:GetSecretValue'
Resource: 'arn:aws:secretsmanager:{REGION}:{ACCOUNT-ID}:secret:{PATH-TO-SECRET}/*'
```
**JSON:**
```javascript

@@ -504,8 +509,4 @@ "Statement" : [

## Sponsors
## Contributions
[![New Relic](https://user-images.githubusercontent.com/2053544/96728664-55238700-1382-11eb-93cb-82fe7cb5e043.png)](https://ad.doubleclick.net/ddm/trackclk/N1116303.3950900PODSEARCH.COM/B24770737.285235234;dc_trk_aid=479074825;dc_trk_cid=139488579;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;tfua=;gdpr=${GDPR};gdpr_consent=${GDPR_CONSENT_755})
<IMG SRC="https://ad.doubleclick.net/ddm/trackimp/N1116303.3950900PODSEARCH.COM/B24770737.285235234;dc_trk_aid=479074825;dc_trk_cid=139488579;ord=[timestamp];dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;tfua=;gdpr=${GDPR};gdpr_consent=${GDPR_CONSENT_755}?" BORDER="0" HEIGHT="1" WIDTH="1" ALT="Advertisement">
## Contributions
Contributions, ideas and bug reports are welcome and greatly appreciated. Please add [issues](https://github.com/jeremydaly/data-api-client/issues) for suggestions and bug reports or create a pull request. You can also contact me on Twitter: [@jeremy_daly](https://twitter.com/jeremy_daly).
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc