Categorygithub.com/edwardsmatt/dynamocity
modulepackage
2.0.0+incompatible
Repository: https://github.com/edwardsmatt/dynamocity.git
Documentation: pkg.go.dev

# README

dynamocity

import "github.com/edwardsmatt/dynamocity"

Package dynamocity provides helpful types for using dynamodb; however, the OverrideEndpointResolver theoretically supports creating a client for any AWS service client using AWS Go SDK V2

The core reason dynamocity exits is to provide a convenient implementation of dynamodbattribute.Marshaler and dynamodbattribute.Unmarshaller which enforces fixed timestamp precision when marshalling for DynamoDB, making it safe for using time.Time as a DynamoDB range key in a string type.

Background

From the standard go library time.RFC3339Nano documentation

The RFC3339Nano format removes trailing zeros from the seconds field and thus may not sort correctly once formatted.

Given the existing AWS Go SDK V2 uses time.RFC3339Nano, it is not suitable to use time.Time as a Dynamo DB Sort Key in a string attribute type.

Designing an efficient Dynamo Single Table design which leverages a generic composite key structure can often use string attribute types; and for correct sortability in this case truncating trailing zeros would be detrimental.

As an aside please I highly recommend the Dynamo DB Book from Alex DeBrie if you're interested in some top shelf DynamoDB learning resources

Why dynamocity?

Well to be honest, I was working with a chap, let's call him JimmyD. We were working through designing a dynamo table schema for a few different components. Whilst wrapping his head around the schema and patterns, JimmyD refered to the Dynamo schema as a monstrosity and then the Dynamo Monstricity, and afterwards - it became affectionately known as Dynamocity.

And that's it. Thanks JimmyD

Index

Types

All of the below Time types implement fixed precision when marshalled to strings, and are therefore sortable as an index type in Dynamo, or anywhere that a string representation needs to be string sortable. Also, all of the following types implement:

  • dynamodbattribute.Marshaler
  • dynamodbattribute.Unmarshaller
  • fmt.Stringer
  • json.Unmarshaler
  • json.Marshaler

Implementing these types make them safe for JSON, string, or dynamo (un)marshalling.

NanoTime

NanoTime represents a sortable strict RFC3339 Timestamp with fixed nanosecond precision. Example Usage:

dynamocity.NanoTime(time.Date(2020, time.April, 1, 14, 0, 0, 999000000, time.UTC)),

MillisTime

MillisTime represents a sortable strict RFC3339 Timestamp with fixed millisecond precision. Example Usage:

dynamocity.MillisTime(time.Date(2020, time.April, 1, 14, 0, 0, 999000000, time.UTC)),

SecondsTime

SecondsTime represents a sortable strict RFC3339 Timestamp with fixed second precision. Example Usage:

dynamocity.SecondsTime(time.Date(2020, time.April, 1, 14, 0, 0, 999000000, time.UTC)),

OverrideEndpointResolver

The OverrideEndpointResolver can be used to provide a simple Client factory function. For example, creating a *dynamodb.Client with overrides could be as follows:

// Dynamo is a utility function to return a *dynamodb.Client
func Dynamo(overrides map[string]string) (*dynamodb.Client, error) {
    awsConfig, err := external.LoadDefaultAWSConfig()
    if err != nil {
        return nil, err
    }

    awsConfig.EndpointResolver = dynamocity.MakeEndpointResolver(overrides)

    client := dynamodb.New(awsConfig)

    return client, nil
}

However, as previously mentioned this pattern could theoretically be used for any AWS Service AWS Go SDK V2 - For example:

// Lambda is a utility function to return a *lambda.Client
func Lambda(overrides map[string]string) (*lambda.Client, error) {
    awsConfig, err := external.LoadDefaultAWSConfig()
    if err != nil {
        return nil, err
    }

    awsConfig.EndpointResolver = dynamocity.MakeEndpointResolver(overrides)

    client := lambda.New(awsConfig)

    return client, nil
}

Prerequisites

Getting Started

Execute the following to provide an explanation of tasks that are commonly used for development.

make help

The output explains the common make targets and what they do:

Perform common development tasks
Usage: make [TARGET]
Targets:
    clean     Clean removes the vendor directory, go.mod, and go.sum files
    prepare   Sets up a go.mod, go.sum and downloads all vendor dependencies
    test      Starts a dynamo local dynamo container and runs unit and integration tests

# Functions

BetweenEndInc will return true if this time.Time is after the start and before or equal to the end.
BetweenExclusive will return true if this time.Time is after the start and before to the end.
BetweenInclusive will return true if this time.Time is after or equal to the start and before or equal to the end.
BetweenStartInc will return true if this time.Time is after or equal to the start and before the end.
MakeEndpointResolver is a factory function for creating an aws.EndpointResolver.
ParseDate will attempt to parse any RFC3339 Timestamp or date with format YYYY-MM-DD to a dynamocity.Date.

# Constants

FlexibleNanoFmt is the standard library time.RFC3339Nano, which applies a flexible compatible nanosecond precision marshalling and unmarshalling capability.
StrictDateFmt is a representation of the Date portion of a time.RFC3339 format.
StrictMillisFmt applies a strict millisecond precision marshalling of a dynamocity.NanoTime.
StrictNanoFmt applies a strict nanosecond precision marshalling of a dynamocity.NanoTime.
StrictSecondsFmt is the standard library time.RFC3339, which applies a strict second precision marshalling and unmarshalling capability.

# Structs

OverrideEndpointResolver is an endpoint resolver for providing overridden endpoints for AWS services Overriding the endpoints for services is helpful for testing, including running dynamodb-local.

# Type aliases

Date represents a sortable Date with fixed date precision.
MillisTime represents a sortable strict RFC3339 Timestamp with fixed millisecond precision, making it string sortable.
NanoTime represents a sortable strict RFC3339 Timestamp with fixed nanosecond precision, making it string sortable.
SecondsTime represents a sortable strict RFC3339 Timestamp with fixed second precision, making it string sortable.