npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@susovan87/rds-data-client

v0.1.1

Published

A lightweight wrapper on @aws-sdk/client-rds-data that simplifies working with the Amazon Aurora Serverless Data API

Downloads

2

Readme

RDS Data Client

A lightweight wrapper on @aws-sdk/client-rds-data that simplifies working with the Amazon Aurora Serverless Data API. This library is inspired by jeremydaly/data-api-client. Here are the key benifits of using this library over others.

  • Simplified input params & output records: It enhances functionality of AWS SDK Javascript v3 library @aws-sdk/client-rds-data by abstracting away the notion of field values. It ease supplying named params in native JavaScript types and also converts return records in native JavaScript types. See the examples below for more details.
  • Custom retries for DB connection failures: Custom retry strategy to handle DB connect timeout. This is extremely useful cater infrequest uses pattern (pause compute capacity on inactivity to save cost). Find the details on the issue aws/aws-sdk-js-v3 #3425.
  • [TBD] Proactive wakeup request: Support for proactive wakeup-request to RDS to minimize waiting time when RDS is paused due to inactivity. It could save compute time & cost. (TDB #1)
  • Extended functionality without any overlapping: The library let you access every feature of @aws-sdk/client-rds-data, while extended few essential funcationality without overlapping. So, no restriction on advance use-cases. That means you can still pass the parameters or parameterSets as query options to send named parameters in native AWS SDK format and get records as output. Though the library will accept additional query option params for simplified named parameter in native Javascript types and inject fields like recordObjects or generatedIds inside query output. Find more on examples below
  • Typescript support: So, you will get hint on what each method accepts and output.
  • Recommended option injection: Automatically inject continueAfterTimeout: true option for DML queries as recommended by AWS. Though you many override this via query options.

Installation

npm i @susovan87/rds-data-client

Simple Examples

You can simply instantiate the DBClient with required configuration and use query() method to execute SQL queries.

import {DBClient} from '@susovan87/rds-data-client'
const dbClient = new DBClient({
  secretArn: 'arn:aws:secretsmanager:us-east-1:XXXXXXXXXXXX:secret:mySecret',
  resourceArn: 'arn:aws:rds:us-east-1:XXXXXXXXXXXX:cluster:my-cluster-name',
  database: 'myDatabase' // default database
});

// Simple SELECT
const data = await dbClient.query('SELECT * FROM myTable');
console.log(data.recordObjects)

// SELECT with named parameters
const resultParams = await dbClient.query(
  `SELECT * FROM myTable WHERE id = :id`,
  { params: { id: 2 } }
);
console.log(resultParams.recordObjects)
// Output: [ { id: 2, name: 'Mike', age: 52 } ]

// INSERT with named parameters
const insert = await dbClient.query(
  `INSERT INTO myTable (name,age,has_curls) VALUES(:name,:age,:curls)`,
  { params: { name: 'Greg', age: 18, curls: false } }
)
console.log(insert.generatedIds)
// Output: [ 4 ]

// BATCH INSERT with named parameters
const batchInsert = await dbClient.query(
  `INSERT INTO myTable (name,age,has_curls) VALUES(:name,:age,:curls)`,
  {
    params: [
      { 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 }
    ]
  }
)
console.log(batchInsert.generatedIds)
// Output: [ 5, 6, 7, 8, 9 ]

// Update with named parameters
const update = await dbClient.query(
  `UPDATE myTable SET age = :age WHERE id = :id`,
  { params: { age: 13, id: 5 } }
)
console.log(update.numberOfRecordsUpdated)
// Output: 1

// Delete with named parameters
const remove = await dbClient.query(
  `DELETE FROM myTable WHERE name = :name`,
  { params: { name: 'Jan' } }
)
console.log(update.numberOfRecordsUpdated)
// Output: 1

// A slightly more advanced example
let custom = await dbClient.query(`SELECT * FROM myOtherTable WHERE isActive = :isActive`,
  {
    params: { isActive: true },
    database: 'myOtherDatabase',
    continueAfterTimeout: true
  })
console.log(custom.recordObjects);
// Output: [
//  { id: 1, name: 'Marcia', DOB: null, weight: 81.8, bio: 'I am a Teacher', isActive: true, createdAt: '2022-03-29 04:41:33' },
//  { id: 2, name: 'Peter', DOB: '2008-07-04', weight: null, bio: 'I am a Student', isActive: true, createdAt: '2022-03-29 04:41:33' }
//]

How it is better than vanilla AWS SDK?

The RDSDataClient requires you to specify data types when passing in parameters. The basic INSERT example above would look like this using this

import { RDSDataClient } from '@aws-sdk/client-rds-data'
const client = new RDSDataClient({ region: 'us-east-1' })

// INSERT with named parameters
let insert = await client.send({
  secretArn: 'arn:aws:secretsmanager:us-east-1:XXXXXXXXXXXX:secret:mySecret',
  resourceArn: 'arn:aws:rds:us-east-1:XXXXXXXXXXXX:cluster:my-cluster-name',
  database: 'myDatabase',
  sql: 'INSERT INTO myTable (name,age,has_curls) VALUES(:name,:age,:curls)',
  parameters: [
    { name: 'name', value: { stringValue: 'Cousin Oliver' } },
    { name: 'age', value: { longValue: 10 } },
    { name: 'curls', value: { booleanValue: false } }
  ]
)

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:

{ // id field
  "longValue": 9
},
{ // name field
  "stringValue": "Cousin Oliver"
},
{ // age field
  "longValue": 10
},
{ // has_curls field
  "booleanValue": false
}

Not only are there no column names, but you have to pull the value from the data type field. Lots of extra work this library automatically handles for you.

Transaction Support

Generate a transactionId by calling startTransaction() and pass the transactionId into every query() options that are part of same transaction. And the just call commit() or rollback() method with the same transactionId to either commit or rollback the transaction.

let transactionId;
try {
  transactionId = await dbClient.startTransaction()

  const insert = await dbClient.query(
    `INSERT INTO myTable (name,age,has_curls) VALUES(:name,:age,:curls)`,
    { params: { name: 'Smith', age: 18, curls: false } },
    transactionId
  )
  console.log(`Successfully inserted with generatedIds: ${insert?.generatedIds}`)

  const update = await dbClient.query(
    `UPDATE myTable SET age = :age WHERE name = :name`,
    { params: { name: 'Smith', age: 81 } },
    transactionId
  )
  const status = await dbClient.commit(transactionId)
  console.log('Commit transaction status:', status)

} catch (error) {
  console.error(error)
  const status = await dbClient.rollback(transactionId)
  console.log('Rollback transaction status:', status)
}

Contributions

Contributions, ideas and bug reports are welcome and greatly appreciated. Please add issues for suggestions and bug reports or create a pull request.