1 | dynalite
|
2 | --------
|
3 |
|
4 | [![Build Status](https://secure.travis-ci.org/mhart/dynalite.png?branch=master)](http://travis-ci.org/mhart/dynalite)
|
5 |
|
6 | An implementation of Amazon's DynamoDB, focussed on correctness and performance, and built on LevelDB
|
7 | (well, [@rvagg](https://github.com/rvagg)'s awesome [LevelUP](https://github.com/rvagg/node-levelup) to be precise).
|
8 |
|
9 | This project aims to match the live DynamoDB instances as closely as possible
|
10 | (and is tested against them in various regions), including all limits and error messages.
|
11 |
|
12 | NB: Schema changes in v2.x
|
13 | --------------------------
|
14 |
|
15 | If you've been using v1.x or v0.x or with a saved path on your filesystem, you
|
16 | should note that key schema may have changed with the move from
|
17 | `level-sublevel` to `subleveldown`. The safest way to deal with this is to
|
18 | export your DB to JSON using Scans, then upgrade and import with BatchWrites
|
19 | into the new version.
|
20 |
|
21 | Why not Amazon's DynamoDB Local?
|
22 | --------------------------------
|
23 |
|
24 | Good question! These days it's actually pretty good, and considering it's now probably
|
25 | used by countless AWS devs, it'll probably be well supported going forward. Unless you
|
26 | specifically can't, or don't want to, use Java, or you're having problems with it,
|
27 | you'll probably be better off sticking with it! Originally, however, DynamoDB Local
|
28 | didn't exist, and when it did, differed a lot from the live instances in ways that caused
|
29 | my company issues. Most of those issues have been addressed in time, but DynamoDB Local
|
30 | does still differ in a number of ways from the live DynamoDB instances –
|
31 | ([see below](#problems-with-amazons-dynamodb-local-updated-2016-04-19)) for details.
|
32 |
|
33 | Example
|
34 | -------
|
35 |
|
36 | ```sh
|
37 | $ dynalite --help
|
38 |
|
39 | Usage: dynalite [--port <port>] [--path <path>] [options]
|
40 |
|
41 | A DynamoDB http server, optionally backed by LevelDB
|
42 |
|
43 | Options:
|
44 | --help Display this help message and exit
|
45 | --port <port> The port to listen on (default: 4567)
|
46 | --path <path> The path to use for the LevelDB store (in-memory by default)
|
47 | --ssl Enable SSL for the web server (default: false)
|
48 | --createTableMs <ms> Amount of time tables stay in CREATING state (default: 500)
|
49 | --deleteTableMs <ms> Amount of time tables stay in DELETING state (default: 500)
|
50 | --updateTableMs <ms> Amount of time tables stay in UPDATING state (default: 500)
|
51 | --maxItemSizeKb <kb> Maximum item size (default: 400)
|
52 |
|
53 | Report bugs at github.com/mhart/dynalite/issues
|
54 | ```
|
55 |
|
56 | Or programmatically:
|
57 |
|
58 | ```js
|
59 | // Returns a standard Node.js HTTP server
|
60 | var dynalite = require('dynalite'),
|
61 | dynaliteServer = dynalite({path: './mydb', createTableMs: 50})
|
62 |
|
63 | // Listen on port 4567
|
64 | dynaliteServer.listen(4567, function(err) {
|
65 | if (err) throw err
|
66 | console.log('Dynalite started on port 4567')
|
67 | })
|
68 | ```
|
69 |
|
70 | Once running, here's how you use the [AWS SDK](https://github.com/aws/aws-sdk-js) to connect
|
71 | (after [configuring the SDK](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html)):
|
72 |
|
73 | ```js
|
74 | var AWS = require('aws-sdk')
|
75 |
|
76 | var dynamo = new AWS.DynamoDB({endpoint: 'http://localhost:4567'})
|
77 |
|
78 | dynamo.listTables(console.log.bind(console))
|
79 | ```
|
80 |
|
81 | Installation
|
82 | ------------
|
83 |
|
84 | With [npm](http://npmjs.org/) do:
|
85 |
|
86 | ```sh
|
87 | $ npm install -g dynalite
|
88 | ```
|
89 |
|
90 | TODO
|
91 | ----
|
92 |
|
93 | - Implement DynamoDB Streams
|
94 | - Implement `ReturnItemCollectionMetrics` on all remaining endpoints
|
95 | - Implement size info for tables and indexes
|
96 | - Add ProvisionedThroughput checking
|
97 | - See [open issues on GitHub](https://github.com/mhart/dynalite/issues) for any further TODOs
|
98 |
|
99 | Problems with Amazon's DynamoDB Local (UPDATED 2016-04-19)
|
100 | -------------------------------------
|
101 |
|
102 | Part of the reason I wrote dynalite was due to the existing mock libraries not exhibiting the same behaviour as the
|
103 | live instances. Amazon then released their DynamoDB Local Java, but the early versions were still very different.
|
104 | The latest version I checked (2016-04-19) is much better, but still has a few differences.
|
105 |
|
106 | [Some of these are documented](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.UsageNotes.html#DynamoDBLocal.Differences),
|
107 | but most aren't - the items below are a rough list of the issues found, vaguely in order of importance:
|
108 |
|
109 | - Does not return nested attributes correctly for `UpdateItem`
|
110 | - Does not calculate size limits accurately for `BatchGetItem`/`Query`/`Scan` result sets
|
111 | - Does deal with `ALL_ATTRIBUTES` correctly for global index on `Query`/`Scan`
|
112 | - Does not prevent primary keys in `QueryFilter` and `FilterExpression` for `Query`
|
113 | - Does not detect duplicate values in `AttributesToGet`
|
114 | - Does not return `LastEvaluatedKey` when size just over limit for `Query`/`Scan`
|
115 | - Does not return `ConsistentRead` property in `UnprocessedKeys` in `BatchGetItem` even if requested
|
116 | - Doesn't return `ConsumedCapacity` (documented - but makes it very hard to calculate expected usage)
|
117 | - Often returns 500 instead of 400 (or similarly appropriate status)
|
118 | - Different serialization and validation error messages from live instances (makes it hard to debug)
|
119 | - Does not return `application/json` if `application/json` is requested
|
120 | - Does not return `Query`/`Scan` items in same order when using hash key or hash `GlobalSecondaryIndex` (shouldn't rely on this anyway)
|