Documentation ¶
Overview ¶
Dynago is a DynamoDB client API for Go.
Dynago differs from other Dynamo clients for Go in that it tries to mirror DynamoDB's core API closely: Most methods, attributes, and names are made following Dynamo's own naming conventions. This allows it to be clear which API is being accessed and allows finding complementary docs on Amazon's side easier.
Filter Chaining ¶
A key design concept is the use of chaining to build filters and conditions, similar to some ORM frameworks. This makes using sub-features like conditional puts, expression post-filtering, and so on to be clearer, because this means a conditional put is simply a PutItem with a condition expression tacked on.
query := client.Query("Table").Limit(40).Desc() result, err := query.Execute()
All the various item-based query actions are evaluated when you call the Execute() method on a filter chain.
Type Marshaling ¶
Dynago tries to marshal to/from Go types where possible:
- Strings use golang `string`
- Numbers can be input as `int` or `float64` but always are returned as `dynago.Number` to not lose precision.
- Maps can be either `map[string]interface{}` or `dynago.Document`
- Opaque binary data can be put in `[]byte`
- String sets, number sets, binary sets are supported using `dynago.StringSet` `dynago.NumberSet` `dynago.BinarySet`
- Lists are supported using `dynago.List`
Query Parameters ¶
Nearly all the operations on items allow using DynamoDB's expression language to do things like query filtering, attribute projection, and so on. In order to provide literal values, queries are parametric, just like many SQL engines:
SET Foo = Foo + :incr DELETE Person.#n
DynamoDB has two fields it uses for parameters: ExpressionAttributeNames for name aliases, and ExpressionAttributeValues for parametric values. For simplicity, in the Dynago library both of those are serviced by Param. This is okay because parameters and aliases are non-ambiguous in that the former are named e.g. ":foo" and the latter "#foo".
So a conditional PutItem might look like:
client.PutItem(table, item). ConditionExpression("Foo.#n = :fooName"). Param("#n", "Name").Param(":fooName", "Bob"). Execute()
In this case, we only execute the query if the value at document path Foo.Name was the string value "Bob". Note we used the "Param" helper for setting both values.
Example (AtomicUpdateItem) ¶
package main import ( "fmt" "github.com/underarmour/dynago" ) var client dynago.Client func main() { key := dynago.HashKey("id", 12345) result, err := client.UpdateItem("products", key). ReturnValues(dynago.ReturnUpdatedNew). UpdateExpression("SET SoldCount = SoldCount + :numSold"). Param(":numSold", 5). Execute() if err != nil { // TODO error handling } fmt.Printf("We have now sold %d frobbers", result.Attributes["SoldCount"]) }
Output:
Example (Query) ¶
package main import ( "fmt" "github.com/underarmour/dynago" ) var endpoint, accessKey, secretKey, table string func main() { client := dynago.NewClient(endpoint, accessKey, secretKey) query := client.Query(table). FilterExpression("NumViews > :views"). Param(":views", 50). Desc() result, err := query.Execute() if err != nil { // do something } for _, row := range result.Items { fmt.Printf("Name: %s, Views: %d", row["Name"], row["NumViews"]) } }
Output:
Index ¶
- Variables
- type AmazonError
- type BatchWrite
- type BatchWriteResult
- type BatchWriteTableEntry
- type BatchWriteTableMap
- type BinarySet
- type CapacityDetail
- type Client
- func (c *Client) BatchWrite() *BatchWrite
- func (c *Client) CreateTable(req *schema.CreateRequest) (*schema.CreateResponse, error)
- func (c *Client) GetItem(table string, key Document) *GetItem
- func (c *Client) PutItem(table string, item Document) *PutItem
- func (c *Client) Query(table string) *Query
- func (c *Client) UpdateItem(table string, key Document) *UpdateItem
- type Document
- type Error
- type Executor
- type GetItem
- type GetItemResult
- type List
- type Number
- type NumberSet
- type Param
- type PutItem
- func (p PutItem) ConditionExpression(expression string) *PutItem
- func (p *PutItem) Execute() (res *PutItemResult, err error)
- func (p PutItem) Param(key string, value interface{}) *PutItem
- func (p PutItem) Params(params ...interface{}) *PutItem
- func (p PutItem) ReturnValues(returnValues ReturnValues) *PutItem
- type PutItemResult
- type Query
- func (q Query) ConsistentRead(strong bool) *Query
- func (q Query) Desc() *Query
- func (q *Query) Execute() (result *QueryResult, err error)
- func (q Query) FilterExpression(expression string, params ...interface{}) *Query
- func (q Query) KeyConditionExpression(expression string) *Query
- func (q Query) Limit(limit uint) *Query
- func (q Query) Param(key string, value interface{}) *Query
- func (q Query) Params(params ...interface{}) *Query
- func (q Query) ProjectionExpression(expression string) *Query
- type QueryResult
- type ReturnValues
- type Select
- type StringSet
- type UpdateItem
- func (u *UpdateItem) ConditionExpression(expression string) *UpdateItem
- func (u *UpdateItem) Execute() (res *UpdateItemResult, err error)
- func (u UpdateItem) Param(key string, value interface{}) *UpdateItem
- func (u UpdateItem) Params(params ...interface{}) *UpdateItem
- func (u *UpdateItem) ReturnValues(returnValues ReturnValues) *UpdateItem
- func (u *UpdateItem) UpdateExpression(expression string) *UpdateItem
- type UpdateItemResult
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var AmazonErrors = []amazonErrorConfig{ {"ConditionalCheckFailedException", 400, ErrorConditionFailed}, {"ResourceNotFoundException", 400, ErrorNotFound}, {"InternalFailure", 500, ErrorInternalFailure}, {"InternalServerError", 500, ErrorInternalFailure}, {"IncompleteSignature", 400, ErrorAuth}, {"InvalidParameterCombination", 400, ErrorInvalidParameter}, {"InvalidParameterValue", 400, ErrorInvalidParameter}, {"InvalidQueryParameter", 400, ErrorInvalidParameter}, {"ItemCollectionSizeLimitExceededException", 400, ErrorCollectionSizeExceeded}, {"MalformedQueryString", 404, ErrorInvalidParameter}, {"MissingAction", 400, ErrorInvalidParameter}, {"MissingAuthenticationToken", 403, ErrorAuth}, {"MissingParameter", 400, ErrorInvalidParameter}, {"OptInRequired", 403, ErrorAuth}, {"ProvisionedThroughputExceededException", 400, ErrorThroughputExceeded}, {"RequestExpired", 400, ErrorAuth}, {"ServiceUnavailable", 503, ErrorServiceUnavailable}, {"ValidationError", 400, ErrorInvalidParameter}, }
This variable is mostly exposed so that we can document how errors are mapped
Functions ¶
This section is empty.
Types ¶
type AmazonError ¶
type AmazonError int
const ( ErrorUnknown AmazonError = iota ErrorConditionFailed // When a conditional put/update fails due to condition not being met ErrorCollectionSizeExceeded // Item collection (local secondary index) too large ErrorThroughputExceeded // We exceeded our provisioned throughput for this table or shard ErrorNotFound // Resource referenced by key not found ErrorInternalFailure // Internal server error ErrorAuth // Encapsulates various authorization errors ErrorInvalidParameter // Encapsulates many forms of invalid input errors ErrorThrottling )
type BatchWrite ¶
type BatchWrite struct {
// contains filtered or unexported fields
}
func (BatchWrite) Delete ¶
func (b BatchWrite) Delete(table string, keys ...Document) *BatchWrite
Add some number of deletes for a table.
func (*BatchWrite) Execute ¶
func (b *BatchWrite) Execute() (*BatchWriteResult, error)
func (BatchWrite) Put ¶
func (b BatchWrite) Put(table string, items ...Document) *BatchWrite
Add some number of puts for a table.
type BatchWriteResult ¶
type BatchWriteResult struct {
UnprocessedItems BatchWriteTableMap
}
type BatchWriteTableEntry ¶
type BatchWriteTableEntry struct { DeleteRequest *batchDelete `json:",omitempty"` PutRequest *batchPut `json:",omitempty"` }
func (*BatchWriteTableEntry) SetDelete ¶
func (e *BatchWriteTableEntry) SetDelete(key Document)
Set this table entry as a delete request
func (*BatchWriteTableEntry) SetPut ¶
func (e *BatchWriteTableEntry) SetPut(item Document)
type BatchWriteTableMap ¶
type BatchWriteTableMap map[string][]*BatchWriteTableEntry
type CapacityDetail ¶
type CapacityDetail string
const ( CapacityIndexes CapacityDetail = "INDEXES" CapacityTotal CapacityDetail = "TOTAL" CapacityNone CapacityDetail = "NONE" )
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func NewClient ¶
Create a new dynamo client.
region is the AWS region, e.g. us-east-1. accessKey is your amazon access key ID. secretKey is your amazon secret key ID.
func NewClientExecutor ¶
Create a new client with a custom executor.
This is mainly used for unit test and mock scenarios.
func (*Client) BatchWrite ¶
func (c *Client) BatchWrite() *BatchWrite
Compose a batch write.
Batch writes can compose a number of put or delete, even across multiple tables, in a single operation.
func (*Client) CreateTable ¶
func (c *Client) CreateTable(req *schema.CreateRequest) (*schema.CreateResponse, error)
Create a table.
func (*Client) GetItem ¶
Compose a GetItem on a dynamo table.
key should be a Document containing enough attributes to describe the primary key.
You can use the HashKey or HashRangeKey helpers to help build a key:
client.GetItem("foo", dynago.HashKey("Id", 45)) client.GetItem("foo", dynago.HashRangeKey("UserId", 45, "Date", "20140512"))
func (*Client) PutItem ¶
Compose a PutItem on a dynamo table.
item should be a document representing the record and containing the attributes for the primary key.
Like all the other requests, you must call `Execute()` to run this.
func (*Client) Query ¶
Compose a Query on a dynamo table.
This returns a new Query struct which you can compose via chaining to build the query you want. Then finish the chain by calling Execute() to run the query.
func (*Client) UpdateItem ¶
func (c *Client) UpdateItem(table string, key Document) *UpdateItem
Compose an UpdateItem on a dynamo table.
type Document ¶
type Document map[string]interface{}
Represents an entire document structure composed of keys and dynamo value
func HashRangeKey ¶
func HashRangeKey(hashName string, hashVal interface{}, rangeName string, rangeVal interface{}) Document
Helper to build a hash-range key.
func (Document) MarshalJSON ¶
func (*Document) UnmarshalJSON ¶
type Error ¶
type Error struct { Type AmazonError // Parsed and mapped down type AmazonRawType string // Raw error type from amazon Exception string // Exception from amazon Message string // Raw message from amazon Response *http.Response // If available, HTTP response ResponseBody []byte // If available, raw response body bytes }
Encapsulates errors coming from amazon/dynamodb
type Executor ¶
type Executor interface { GetItem(*GetItem) (*GetItemResult, error) PutItem(*PutItem) (*PutItemResult, error) Query(*Query) (*QueryResult, error) UpdateItem(*UpdateItem) (*UpdateItemResult, error) CreateTable(*schema.CreateRequest) (*schema.CreateResponse, error) BatchWriteItem(*BatchWrite) (*BatchWriteResult, error) }
This interface defines how all the various queries manage their internal execution logic.
Executor is primarily provided so that testing and mocking can be done on the API level, not just the transport level.
func NewAwsExecutor ¶
Create an AWS executor with a specified endpoint and AWS parameters.
type GetItem ¶
type GetItem struct {
// contains filtered or unexported fields
}
func (GetItem) ConsistentRead ¶
Set up this get to be a strongly consistent read.
func (*GetItem) Execute ¶
func (p *GetItem) Execute() (result *GetItemResult, err error)
Execute the get item.
func (GetItem) ProjectionExpression ¶
Set the ProjectionExpression for this GetItem (which attributes to get)
type GetItemResult ¶
type GetItemResult struct { Item Document ConsumedCapacity interface{} // TODO }
The result from executing a GetItem.
type PutItem ¶
type PutItem struct {
// contains filtered or unexported fields
}
func (PutItem) ConditionExpression ¶
Set a ConditionExpression to do a conditional PutItem.
func (*PutItem) Execute ¶
func (p *PutItem) Execute() (res *PutItemResult, err error)
Actually Execute this putitem.
PutItemResult will be nil unless ReturnValues or ReturnConsumedCapacity is set.
func (PutItem) ReturnValues ¶
func (p PutItem) ReturnValues(returnValues ReturnValues) *PutItem
Set ReturnValues.
type PutItemResult ¶
type PutItemResult struct {
Attributes Document
}
type Query ¶
type Query struct {
// contains filtered or unexported fields
}
func (Query) ConsistentRead ¶
If strong is true, do a strongly consistent read. (defaults to false)
func (*Query) Execute ¶
func (q *Query) Execute() (result *QueryResult, err error)
Execute this query and return results.
func (Query) FilterExpression ¶
Set a post-filter expression for the results we scan.
func (Query) KeyConditionExpression ¶
Set a condition expression on the key to narrow down what we scan
func (Query) ProjectionExpression ¶
Set a Projection Expression for controlling which attributes are returned.
type QueryResult ¶
type QueryResult struct { Items []Document Count int // The total number of items (for pagination) }
The result returned from a query.
type ReturnValues ¶
type ReturnValues string
const ( ReturnNone ReturnValues = "NONE" ReturnAllOld ReturnValues = "ALL_OLD" ReturnUpdatedOld ReturnValues = "UPDATED_OLD" ReturnAllNew ReturnValues = "ALL_NEW" ReturnUpdatedNew ReturnValues = "UPDATED_NEW" )
type UpdateItem ¶
type UpdateItem struct {
// contains filtered or unexported fields
}
func (*UpdateItem) ConditionExpression ¶
func (u *UpdateItem) ConditionExpression(expression string) *UpdateItem
Set a condition expression for conditional update.
func (*UpdateItem) Execute ¶
func (u *UpdateItem) Execute() (res *UpdateItemResult, err error)
Execute this UpdateItem and return the result.
func (UpdateItem) Param ¶
func (u UpdateItem) Param(key string, value interface{}) *UpdateItem
Quick-set a single parameter
func (UpdateItem) Params ¶
func (u UpdateItem) Params(params ...interface{}) *UpdateItem
Set multiple parameters at once.
func (*UpdateItem) ReturnValues ¶
func (u *UpdateItem) ReturnValues(returnValues ReturnValues) *UpdateItem
If set, then we will get return values of either updated or old fields (see ReturnValues const)
func (*UpdateItem) UpdateExpression ¶
func (u *UpdateItem) UpdateExpression(expression string) *UpdateItem
Set an update expression to update specific fields and values.
type UpdateItemResult ¶
type UpdateItemResult struct {
Attributes Document
}