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

rest-on-dynamo

v0.1.2

Published

Light weight wapper around DynamoDB client for easy restful usage

Downloads

6

Readme

Rest on Dynamo

A lightweight lib to facilitate building RESTful service on top of DynamoDB.

Introduction

AWS DynamoDB being a fully managed key-value storage is easy to use and has very little operational burden.

rest-on-dynamo is created to help map REST paradigm on to DynamoDB concepts and speed up the development cycle.

Usage

Initiate Client

import { RestOnDynamoClient } from 'rest-on-dynamo';

const client: RestOnDynamoClient = new RestOnDynamoClient('table-name');

An optional DynamoDB client can also be supplied as the second parameter of the constructor

import { DynamoDB } from 'aws-sdk';
import { RestOnDynamoClient } from 'rest-on-dynamo';

const dynamodb = new DynamoDB({
  // your dynamoDb config options
})

const client: RestOnDynamoClient = new RestOnDynamoClient('table-name', dynamodb);

Rest calls

Like javascript AWS SDK, you can choose to use callback or promise.

Use Promise (Recommended)

client.get({ id: 'test-id' }).promise().then(...).catch(...);

or pass in callback function as a optional last argument

client.get({
  id: 'test-id'
}, (e: Err, d: Ok) => {
  // do things with e or d
})

Methods Signatures

Result Signature

All rest calls returns a Result<T> that wraps the promise inside

Result<T> implements interface IResult<T> defined as such

interface IResult<T> {
  /**
   * return the promise that wraps the type T data
   */
  promise(): Promise<T>
}

Optional Callback Signature

type RestOnDynamoCallback = (error?: Err, data?: Ok<object | void>) => void;

// Err and Ok implement interfaces IErr and IOk respectively

interface IErr {
  /**
   * Indicator of whether the error derives from DynamoDB service
   */
  readonly isAwsError: boolean;

  /**
   * The original AWSError if isAwsError is true
   * see https://github.com/aws/aws-sdk-js/blob/master/lib/error.d.ts#L4
   */
  readonly awsError?: AWSError;

  /**
   * Recommended default http status code mapping
   */
  readonly defaultStatusCode: ErrorType; // ErrorType is a number enum (e.g. 400, 409, 500, etc.)

  /**
   * Error message
   * Note that the message will be the same as the message from AWSError if the isAwsError is true
   */
  readonly message: string;

  /**
   * Error status code range
   */
  readonly errorStatusCodeRange: ErrorStatusCodeRange; // number enum of 400 or 500
}

interface IOk<T> {
  /**
   * Data wrapped
   */
  readonly data?: T;

  /**
   * Recommended default http status code mapping
   */
  readonly defaultStatusCode: SuccessType; // SuccessType is a number enum (e.g. 200, 201, 204)
}

Id

The id in REST paradigm is mapped to the key schema on a dynamodb table schema. Think of the object that has partition key and optional sort key attribute name to value mapping as an identifier.

Id is defined as below

type Id = DocumentClient.Key;

// and DocumentClient.Key is defined as below
// see https://github.com/aws/aws-sdk-js/blob/master/lib/dynamodb/document_client.d.ts#L1237
type Key = {[key: string]: AttributeValue};

Rest Calls Signatures

Note promise rejection cannot be typed but the the promise rejection from a Result will be an Err

client.get({...}).promise().then((d: Ok) => {
  // ...
}).catch(e => {
  // e here will be an Err
})

GET

get(id: Id, callback?: RestOnDynamoCallback): Result<Ok<object>>

POST

post(id: Id, data: object, callback?: RestOnDynamoCallback): Result<Ok<object>>

PUT

put(id: Id, data: object, callback?: RestOnDynamoCallback): Result<Ok<object>>

DELETE

delete(id: Id, callback?: RestOnDynamoCallback): Result<Ok<void>>

PATCH

Note patch() does NOT perform deep merge

patch(id: Id, data: object, callback?: RestOnDynamoCallback): Result<Ok<object>>

HEAD

head(id: Id, callback?: RestOnDynamoCallback): Result<Ok<void>>

FAQ

It's clear that a GET /resource-name/:id should map to a get(), what about a GET /resource-name?<query params...>

Because DynamoDB is a key value store, and due to its design, it's only efficient to use get operation or query operation within the partition key. The scan operation is generally discouraged because it could consume massive table capacity when table size gets bigger. Thus, this library is designed and implemented with DynamoDB best practices in mind. For a GET /resource-name?<query params...> endpoint, it's recommended to use other AWS offering in junction with DynamoDB.

e.g.

DynamoDB -> DynamoDB Stream -> Lambda function -> ElasticSearch

then expose the GET /resource-name?<query params...> endpoint through ElasticSearch