ExAws.Dynamo.Client behaviour
Defines a Dynamo Client
By default you can use ExAws.Dynamo
NOTE: When Mix.env in [:test, :dev] dynamo clients will run by default against Dynamodb local.
Usage
defmodule MyApp.Dynamo do
use ExAws.Dynamo.Client, otp_app: :my_otp_app
end
In your config
config :my_otp_app, :ex_aws,
dynamodb: [], # Dynamo config goes here
You can now use MyApp.Dynamo as the root module for the Dynamo api without needing to pass in a particular configuration. This enables different otp apps to configure their AWS configuration separately.
The alignment with a particular OTP app while convenient is however entirely optional. The following also works:
defmodule MyApp.Dynamo do
use ExAws.Dynamo.Client
def config_root do
Application.get_all_env(:my_aws_config_root)
end
end
ExAws now expects the config for that dynamo client to live under
config :my_aws_config_root
dynamodb: [] # Dynamo config goes here
Default config values can be found in ExAws.Config.
General notes
All options are handled as underscored atoms instead of camelcased binaries as specified
in the Dynamo API. IE IndexName
would be :index_name
. Anywhere in the API that requires
dynamo type annotation ({"S":"mystring"}
) is handled for you automatically. IE
ExAws.Dynamo.scan("Users", expression_attribute_values: [api_key: "foo"])
Transforms into a query of
%{"ExpressionAttributeValues" => %{api_key: %{"S" => "foo"}}, "TableName" => "Users"}
Consult the function documentation to see precisely which options are handled this way.
If you wish to avoid this kind of automatic behaviour you are free to specify the types yourself. IE:
ExAws.Dynamo.scan("Users", expression_attribute_values: [api_key: %{"B" => "Treated as binary"}])
Becomes:
%{"ExpressionAttributeValues" => %{api_key: %{"B" => "Treated as binary"}}, "TableName" => "Users"}
Alternatively, if what’s being encoded is a struct, you’re always free to implement ExAws.Dynamo.Encodable for that struct.
Examples
defmodule User do
@derive [ExAws.Dynamo.Encodable]
defstruct [:email, :name, :age, :admin]
end
alias ExAws.Dynamo
# Create a users table with a primary key of email [String]
# and 1 unit of read and write capacity
Dynamo.create_table("Users", "email", %{email: :string}, 1, 1)
user = %User{email: "bubba@foo.com", name: "Bubba", age: 23, admin: false}
# Save the user
Dynamo.put_item("Users", user)
# Retrieve the user by email and decode it as a User struct.
result = Dynamo.get_item!("Users", %{email: user.email})
|> Dynamo.Decoder.decode(as: User)
assert user == result
http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations.html
Types ↑
table_name :: binary
primary_key :: [{atom, binary}] | %{atom => binary}
exclusive_start_key_vals :: [{atom, binary}] | %{atom => binary}
expression_attribute_names_vals :: %{binary => binary}
expression_attribute_values_vals :: [{atom, binary}] | %{atom => binary}
return_consumed_capacity_vals :: :none | :total | :indexes
select_vals :: :all_attributes | :all_projected_attributes | :specific_attributes | :count
return_values_vals :: :none | :all_old | :updated_old | :all_new | :updated_new
return_item_collection_metrics_vals :: :size | :none
dynamo_type_names :: :blob | :boolean | :blob_set | :list | :map | :number_set | :null | :number | :string | :string_set
key_schema :: [{atom | binary, :hash | :range}, ...]
key_definitions :: [{atom | binary, dynamo_type_names}, ...]
scan_opts :: [exclusive_start_key: exclusive_start_key_vals, expression_attribute_names: expression_attribute_names_vals, expression_attribute_values: expression_attribute_values_vals, filter_expression: binary, index_name: binary, limit: pos_integer, projection_expression: binary, return_consumed_capacity: return_consumed_capacity_vals, segment: non_neg_integer, select: select_vals, total_segments: pos_integer]
query_opts :: [consistent_read: boolean, exclusive_start_key: exclusive_start_key_vals, expression_attribute_names: expression_attribute_names_vals, expression_attribute_values: expression_attribute_values_vals, filter_expression: binary, index_name: binary, key_condition_expression: binary, limit: pos_integer, projection_expression: binary, return_consumed_capacity: return_consumed_capacity_vals, scan_index_forward: boolean, select: select_vals]
batch_get_item_opts :: [{:return_consumed_capacity, return_consumed_capacity_vals}]
get_item :: [consistent_read: boolean, keys: [primary_key]]
write_item :: [[{:delete_request, [{:key, primary_key}]}] | [{:put_request, [{:item, %{}}]}]]
batch_write_item_opts :: [return_consumed_capacity: return_consumed_capacity_vals, return_item_collection_metrics: return_item_collection_metrics_vals]
put_item_opts :: [condition_expression: binary, expression_attribute_names: expression_attribute_names_vals, expression_attribute_values: expression_attribute_values_vals, return_consumed_capacity: return_consumed_capacity_vals, return_item_collection_metrics: return_item_collection_metrics_vals, return_values: return_values_vals]
get_item_opts :: [consistent_read: boolean, expression_attribute_names: expression_attribute_names_vals, projection_expression: binary, return_consumed_capacity: return_consumed_capacity_vals]
update_item_opts :: [condition_expression: binary, expression_attribute_names: expression_attribute_names_vals, expression_attribute_values: expression_attribute_values_vals, return_consumed_capacity: return_consumed_capacity_vals, return_item_collection_metrics: return_item_collection_metrics_vals, return_values: return_values_vals, update_expression: binary]
delete_item_opts :: [condition_expression: binary, expression_attribute_names: expression_attribute_names_vals, expression_attribute_values: expression_attribute_values_vals, return_consumed_capacity: return_consumed_capacity_vals, return_item_collection_metrics: return_item_collection_metrics_vals, return_values: return_values_vals]
Callbacks
Specs:
- batch_get_item(%{table_name => get_item}) :: ExAws.Request.response_t
Get up to 100 items (16mb)
Map of table names to request parameter maps. http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html
Parameters with keys that are automatically annotated with dynamo types are:
[:keys]
Dynamo.batch_get_item(%{
"Users" => [
consistent_read: true,
keys: [
[api_key: "key1"],
[api_key: "api_key2"]
]
],
"Subscriptions" => %{
keys: [
%{id: "id1"}
]
}
})
As you see you’re largely free to use either keyword args or maps in the body. A map is required for the argument itself because the table names are most often binaries, and I refuse to inflict proplists on anyone.
Specs:
- batch_get_item(%{table_name => get_item}, opts :: batch_get_item_opts) :: ExAws.Request.response_t
Specs:
- batch_write_item(%{table_name => [write_item]}) :: ExAws.Request.response_t
Put or delete up to 25 items (16mb)
Map of table names to request parameter maps. http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html
Parameters with keys that are automatically annotated with dynamo types are:
[:keys]
Specs:
- batch_write_item(%{table_name => [write_item]}, opts :: batch_write_item_opts) :: ExAws.Request.response_t
Specs:
- config :: Keyword.t
Returns the canonical configuration for this service
Specs:
- config_root :: Keyword.t
Retrieves the root AWS config for this client
Specs:
- create_table(table_name :: binary, key_schema :: [key_schema], key_definitions :: key_definitions, read_capacity :: pos_integer, write_capacity :: pos_integer) :: ExAws.Request.response_t
- create_table(table_name :: binary, key_schema :: binary | atom, key_definitions :: key_definitions, read_capacity :: pos_integer, write_capacity :: pos_integer) :: ExAws.Request.response_t
Create table
key_schema can be a simple binary or atom indicating a simple hash key
Specs:
- create_table(table_name :: binary, key_schema :: [key_schema], key_definitions :: key_definitions, read_capacity :: pos_integer, write_capacity :: pos_integer) :: ExAws.Request.response_t
- create_table(table_name :: binary, key_schema :: binary | atom, key_definitions :: key_definitions, read_capacity :: pos_integer, write_capacity :: pos_integer) :: ExAws.Request.response_t
Create table
key_schema allows specifying hash and / or range keys IE
[api_key: :hash, something_rangy: :range]
Specs:
- create_table(table_name :: binary, key_schema :: [key_schema], key_definitions :: key_definitions, read_capacity :: pos_integer, write_capacity :: pos_integer, global_indexes :: Keyword.t, local_indexes :: Keyword.t) :: ExAws.Request.response_t
Create table with indices
Specs:
- delete_item(table_name :: table_name, primary_key :: primary_key) :: ExAws.Request.response_t
Delete item in table
Specs:
- delete_item(table_name :: table_name, primary_key :: primary_key, opts :: delete_item_opts) :: ExAws.Request.response_t
Specs:
- delete_table(table :: binary) :: ExAws.Request.response_t
Delete Table
Specs:
- describe_table(name :: binary) :: ExAws.Request.response_t
Describe table
Specs:
- get_item(table_name :: table_name, primary_key :: primary_key) :: ExAws.Request.response_t
Get item from table
Specs:
- get_item(table_name :: table_name, primary_key :: primary_key, opts :: get_item_opts) :: ExAws.Request.response_t
Specs:
- get_item!(table_name :: table_name, primary_key :: primary_key) :: %{}
Get an item from a dynamo table, and raise if it does not exist or there is an error
Specs:
- get_item!(table_name :: table_name, primary_key :: primary_key, opts :: get_item_opts) :: %{}
Specs:
- list_tables :: ExAws.Request.response_t
List tables
Specs:
- put_item(table_name :: table_name, record :: %{}) :: ExAws.Request.response_t
Put item in table
Specs:
- put_item(table_name :: table_name, record :: %{}, opts :: put_item_opts) :: ExAws.Request.response_t
Specs:
- query(table_name :: table_name) :: ExAws.Request.response_t
Query Table
Please read: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html
"Users"
|> Dynamo.stream_query(
limit: 1,
expression_attribute_values: [desired_api_key: "adminkey"],
key_condition_expression: "api_key = :desired_api_key")
|> Enum.to_list
Parameters with keys that are automatically annotated with dynamo types are:
[:exclusive_start_key, :expression_attribute_names]
Specs:
- query(table_name :: table_name, opts :: query_opts) :: ExAws.Request.response_t
Specs:
- request(data :: %{}, action :: atom) :: term
Enables custom request handling.
By default this just forwards the request to the ExAws.Dynamo.Request.request/2
.
However, this can be overriden in your client to provide pre-request adjustments to headers, params, etc.
Specs:
- scan(table_name :: table_name) :: ExAws.Request.response_t
Scan table
Please read http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html
"Users"
|> Dynamo.stream_scan(
limit: 1,
expression_attribute_values: [desired_api_key: "adminkey"],
expression_attribute_names: %{"#asdf" => "api_key"},
filter_expression: "#asdf = :desired_api_key")
|> Enum.to_list
Generally speaking you won’t need to use :expression_attribute_names
. It exists
to alias a column name if one of the columns you want to search against is a reserved dynamo word,
like Percentile
. In this case it’s totally unnecessary as api_key
is not a reserved word.
Parameters with keys that are automatically annotated with dynamo types are:
[:exclusive_start_key, :expression_attribute_names]
Specs:
- scan(table_name :: table_name, opts :: scan_opts) :: ExAws.Request.response_t
Specs:
- service :: atom
Service
Specs:
- stream_query(table_name :: table_name) :: Enumerable.t
Stream records from table
Returns an enumerable which handles pagination automatically in the backend.
{:ok, %{"Items" => items}} = Dynamo.stream_query("Users", filter_expression: "api_key = :api_key", expression_attribute_values: [api_key: "api_key_i_want"])
items |> Enum.to_list #=> Returns every item in the Users table with an api_key == "api_key_i_want".
Specs:
- stream_query(table_name :: table_name, opts :: query_opts) :: Enumerable.t
Specs:
- stream_scan(table_name :: table_name) :: Enumerable.t
Stream records from table
Same as scan/1,2 but the records are a stream which will automatically handle pagination
Dynamo.stream_scan("Users")
|> Enum.to_list #=> Returns every item in the Users table.
Specs:
- stream_scan(table_name :: table_name, opts :: scan_opts) :: Enumerable.t
Specs:
- update_item(table_name :: table_name, primary_key :: primary_key, opts :: update_item_opts) :: ExAws.Request.response_t
Update item in table
For update_args format see http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html
Specs:
- update_table(name :: binary, attributes :: Keyword.t) :: ExAws.Request.response_t
Update Table