Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/brabster/dynamodb-expressions

Better DynamoDB expressions with Clojure
https://github.com/brabster/dynamodb-expressions

Last synced: 1 day ago
JSON representation

Better DynamoDB expressions with Clojure

Awesome Lists containing this project

README

        

* dynamodb-expressions

[[https://travis-ci.org/brabster/dynamodb-expressions][https://img.shields.io/travis/brabster/dynamodb-expressions.svg]]
[[https://github.com/brabster/dynamodb-expressions/releases/latest][https://img.shields.io/github/release/brabster/dynamodb-expressions.svg]]

[[http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.Modifying.html][DynamoDB Update Expressions]] in Clojure, designed for use with [[https://github.com/mcohen01/amazonica][Amazonica]].

Get the latest version on [[https://clojars.org/dynamodb-expressions][Clojars]]

* Why?

DynamoDB's native update expression syntax requires placeholders be
specified for all values and, under some circumstances, for names
too. That typically means (in my experience, anyway) verbose, brittle
and hard-to-read code.

The nested-map structure also makes these values hard to manipulate in
a threading-friendly way.

Contrived, worst-case example: we want to update a customer document,
primary key "customer-id", adding 1 to the ~auth-attempts~ key, and
setting the nested ~call.at~ key to "today".

Because ~auth-attempts~ includes a hyphen, and both ~call~ and ~at~
are DynamoDB reserved words, we must set name placeholders for
them. We might write something like this:

#+BEGIN_SRC clojure
{:key {:customer-id "foo"}
:update-expression "ADD #auth_attempts :auth_attempts_val SET #call.#at = :call_at_value"
:expression-attribute-names {"#auth_attempts" "auth-attempts"
"#call" "call"
"#at" "at"}
:expression-attribute-values {":auth_attempts_val" 1
":call_at_value" "today"}}
#+END_SRC

I don't think that expresses what I'm trying to do very clearly. This
library allows you to write instead:

#+BEGIN_SRC clojure
(require '[dynamodb-expression.core :as dx])

(->
(dx/update-expr {:customer-id "foo"})
(dx/add :auth-attempts 1)
(dx/set [:call :at] "today")
dx/expr)
#+END_SRC

Which produces something like the following, applying placeholders for
all names. Some indication of where the placeholder came from is
retained to help debugging:

#+BEGIN_SRC clojure
{:update-expression
"ADD #nauth_attempts_21478 :vauth_attempts_21478 SET #ncall_21479.#ncall_at_21480 = :vcall_at_21480"
:key {:customer-id "foo"}
:expression-attribute-names {"#nauth_attempts_21478" "auth-attempts"
"#ncall_at_21480" "at"
"#ncall_21479" "call"},
:expression-attribute-values {":vauth_attempts_21478" 1
":vcall_at_21480" "today"}}
#+END_SRC

* Unsupported Functionality

The following update expression features are not supported
(yet!). Raise an issue and/or submit a PR if you need these.

** array syntax

There's no way to access array elements right now.

** functions

Nor can you use functions like ~list_append~.

* dynamodb Grammar

To test condition expressions without nasty string hacking, there's a
grammar for condition expressions, based on the documentation.

* License

Copyright © 2016 Paul Brabban

Distributed under the Eclipse Public License either version 1.0 or (at
your option) any later version.