Skip to content

Commit 702b66f

Browse files
docs(readme): update the readme
1 parent 9b57ed1 commit 702b66f

File tree

2 files changed

+70
-149
lines changed

2 files changed

+70
-149
lines changed

README.md

Lines changed: 68 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,14 @@
66
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
77
[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg)](#contributors)
88

9-
Built with :heart: by the crew from [https://www.shiftcode.ch](shiftcode).
9+
Abstracts away the complexity of the low level aws dynamosdk. Provides an easy to use fluent api to for requests and supports typescript decorators,
10+
to define some metadata for your models. You don't need to care about the mapping of javascript types to their dynamo types any more. We got you covered.
1011

11-
## Purpose
12+
Checkout the full technical api documentation [here](https://shiftcode.github.io/dynamo-easy/).
1213

13-
The official Amazon Dynamo SDK for javascript has a pretty low level api, where some deeper knowledge about all the possible options is required.
14-
This Library provides an easy to use, descriptive, chainable api to execute dynamoDb requests. It also provides decorators to define how a type should be mapped
15-
to dynamodb. Supporting simple types like String, Number, Boolean, Binary to more complex types like custom classes, momentJs dates.
16-
17-
Checkout the full api documentation [https://shiftcode.github.io/dynamo-easy/](here).
18-
19-
# What this library does not provide
20-
API to setup tables (we use cloudformation on our side for infrastructur setup, so this was not a need for us)
14+
Built with :heart: by the crew from [shiftcode](https://www.shiftcode.ch).
2115

2216
# Get Started
23-
Usage with Angular (>4) checkout our angular-service. [TODO](TODO)
24-
25-
Basic Example:
2617
```
2718
@Model()
2819
class Person{
@@ -58,126 +49,87 @@ dynamoStore.scan()
5849
5950
```
6051

61-
# Decorators
62-
Decorators define how on object should be mapped to dynamodb also defining indexes and properties which are used as partition keys
63-
Use the class <MetadataHelper> to read the informations defined by decorators.
64-
65-
Checkout the full [https://shiftcode.github.io/dynamo-easy/](documentation).
66-
67-
-----
68-
69-
To map an js object into the attribute map required by dynamodb requests, we implement our very oppinionated custom mapper.
70-
We use the DynamoDB Document Mapper to map all «default» types to dynamodb attribute values.
71-
72-
There are some custom requirements for these cases:
73-
74-
- MomentJs Dates
75-
- Use ES6 Map, Set types
76-
77-
Mapper Strategy:
78-
79-
-> To DB
80-
1) check if we have some property metadata
81-
82-
YES NO
83-
84-
isCustomType document client can map (check with typeof propertyValue for additional security)
85-
86-
YES NO
87-
88-
custom mapping document client can map
89-
90-
-> From DB
91-
92-
-----
93-
52+
Want to use this library with Angular (>4) [checkout our angular-service](TODO).
9453

95-
Decorators are used to add some metadata to our model classes required by the mapper for some special cases.
54+
# Decorators
55+
Decorators are used to add some metadata to our model classes, relevant to our javascript-to-dynamo mapper.
9656

97-
This is an experimental feature and requires to set the
57+
This is an experimental feature and requires to set the following typescript compiler options:
9858

9959
- "experimentalDecorators": true
10060
- "emitDecoratorMetadata": true
10161

102-
typescript compiler options.
103-
10462
Additionally we rely on the reflect-metadata (https://www.npmjs.com/package/reflect-metadata) library for reflection api.
10563

106-
To get started with decorators just add a @Model() Decorator to any ts class. By default this enables the custom mapping functionality
107-
and will get you started to work with Dynamo DB and simple types (like String, Number, Boolean etc. but no custom classes for example)
64+
To get started with decorators just add a [@Model()](https://shiftcode.github.io/dynamo-easy/modules/_decorator_impl_model_model_decorator_.html) Decorator to any typescript class.
65+
66+
If you need to read the metadata by hand for some purpose, use the [MetadataHelper](https://shiftcode.github.io/dynamo-easy/classes/_decorator_metadata_metadata_helper_.metadatahelper.html) to read the informations.
10867

10968
We make heavy usage of compile time informations about our models and the property types.
11069
Here is a list of the types that can be retrieved from compile time information for the key design:type. (The metadata will only be added if at least one decorator is
11170
present on a property)
11271

113-
String
114-
Number
115-
Boolean
116-
Array (no generics)
117-
Custom Types
118-
119-
Map / Set will be Object
72+
- String
73+
- Number
74+
- Boolean
75+
- Array (no generics)
76+
- Custom Types
77+
- ES6 types like Set, Map will be mapped to Object when calling for the type via Reflect.get(design:type), so we need some extra info.
12078

12179
Generic information is never available due to some serialization limitations at the time of writing.
12280

123-
ES6 types like Set, Map will be mapped to Object when calling for the type via Reflect.get(design:type), so we need some extra info.
81+
## A word on Collections (Array & Set)
12482

125-
##### Collections
126-
127-
#Array
83+
###Array
12884
Javascript Arrays with a a items of type String, Number or Binary will be mapped to a S(et) type, by default all other types are mapped to L(ist) type.
12985
If an item of an Array has a complex type the type can be defined using the @TypedArray() Decorator.
13086

131-
#Set
132-
es6 Set types will be marshalled to dynamoDb set type if the type of the set is supported, if the type is not supported it will be
87+
###Set
88+
ES6 Set types will be marshalled to dynamoDb set type if the type of the set is supported, if the type is not supported it will be
13389
marshalled to an dynamoDB List.
13490

13591
When one of the following decorators is added, the value is marshalled to a List type.
136-
@SortedSet(), @TypedSet(complexType?)
92+
@SortedSet(itemType?: ModelClazz), @TypedSet(itemType?: ModelClazz)
93+
94+
## Model
13795

138-
##Model
96+
###Custom TableName
13997
Here is the rule how a table name is built `${kebabCase(modelName)}s` so for a model called Product the table will be named products, this is a default implementation.
140-
To Provide your own logic you can implement a TableNameResolver function and give it to the DynamoStore class when implementing a new instance.
14198

99+
There are two possibilities to change the name:
142100

143-
**Custom TableName**
144-
@Model({tableName: tableName})
101+
- override the name using the tableName parameter @Model({tableName: tableName})
102+
- provide a TableNameResolver function when instantiating a DynamoStore. This method will receive the default table name
103+
(either resolved using the model name or custom value when a tableName was provided in @Model decorator)
145104

105+
# Mapper
146106

147-
#### Types
107+
## Types
148108

149-
Simple Type (no decorators requried to work)
109+
We do the mapping from javascript objects to dynamodb types for you in requests and responses
110+
111+
Simple Type (no decorators required to work)
150112
- String
151113
- Number
152114
- Boolean
153115
- Null
154116
- Array
155-
156-
- Date (moment) is mapped by convention (see TODO:addLink Dates)
117+
- Date (we only support MomentJS)
157118

158119
Complex Types (properties with these types need some decorators to work properly)
159120
- Set<simpleType | complexType>
160121
- Map
161122
- Array<complexType>
162123

163-
##### Date #####
164-
Two Date types are supported. Default JS Date and moment dates.
124+
## Date
125+
Right now we only support (MomentJS)[http://momentjs.com/] Dates.
165126

166-
The type defines how a value will be mapped. Types can be defined using decorators (for complex types) or we use one of the following methods:
167-
fromDB -> use default for DynamoDB type (see type table)
168-
toDB -> use property value to resolve the type
169-
170-
design:type
171-
String, Number, Boolean, Undefined, Object
172-
173-
unsupported
174-
Set, Map, Date, moment.Moment
127+
If you want to explicitly mark a property to be a Date use the @Date() decorator. If we find a moment value we automatically map it to a String (using ISO-8601 format).
128+
When coming from db we do a regex test for ISO-8601 format and map it back to a moment object.
175129

176130
# Requests API
177-
178-
To start making requests create an instance of [TODO add link](DynamoStore) and execute the desired operation using the provided api.
179-
We support all the common dynamodb operations
180-
See for a the [TODO add link](full documentation).
131+
To start making requests create an instance of [DynamoStore](https://shiftcode.github.io/dynamo-easy/classes/_dynamo_dynamo_store_.dynamostore.html) and execute the desired operation using the provided api.
132+
We support all the common dynamodb operations.
181133

182134
The request api has support for the following operations:
183135

@@ -195,9 +147,9 @@ need some more info.
195147
There is always the possibility to access the Params object directly to add values which are not covered with our api.
196148

197149
# Authentication
198-
In a real world scenario you'll have some kind of authentication to protect your dynamodb ressources. You can customize on how to authenticate when giving a custom
199-
SessionValidityEnsurer function to the dynamo store when creating a new instance.
200-
The default implementation is a no-op.
150+
In a real world scenario you'll have some kind of authentication to protect your dynamodb ressources. You can customize on how to authenticate when providing a custom
151+
SessionValidityEnsurer function to the DynamoStore when creating a new instance.
152+
The default implementation is a no-op function.
201153

202154
## Session Validity Ensurer
203155
Here is an example of an implementation using amazon cognito
@@ -225,64 +177,39 @@ function sessionValidityEnsurer(): Observable<>{
225177
}
226178
```
227179

228-
### Expressions ([http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.html](Official Doc))
229-
230-
When working with expressions there is an important point to remember, an expression looks like this (Scan Filter Expression):
231-
232-
```
233-
{
234-
FilterExpression: '#name = :name'
235-
ExpressionAttributeNames: {'#name': 'name'}
236-
ExpressionAttributeValues: {':name': {S: 'peter'}}
237-
}
238-
```
239-
240-
The usage of ExpressionAttributeNames is not required, but due to the fact that there are a lot of keywords which could not be used in an expression (blacklist)[http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html],
241-
we replace the attribute names always with a variable (starting with the '#' sign)
242-
243-
244-
----
245-
246-
247-
By default we create a substitution placeholder for all the attributes, just to not implement a blacklist with reserved words in the context of aws dynamodb.
180+
## Expressions ([AWS Doc](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.html))
181+
By default we create a substitution placeholder for all the attributes, just to not implement a [blacklist](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) with reserved words in the context of aws dynamodb.
248182

249183
attributename: age
250184

185+
```
186+
expression: '#age = :age'
251187
attributeExpressionNames: {'#age': 'age'}
252188
attributeExpressionValues: {':age': {N: '10'}}
253-
expression: '#age = :age'
189+
```
254190

255191
this works seemlesly for top level attribtues, but if we wanna build an expression for where the attribute needs to be accessed with a document path, we need some special logic
256192
nested attribute: person.age
257193

194+
```
258195
attributeExpressionNames: {'#person':'person', '#age': 'age'}
259196
attributeExpressionValues: {':age': {N: '10'}}
260197
expression: '#person.#age = :age'
198+
```
261199

262-
we can't use #personAge: 'person.age' because if the dot is part of an attribute name it is not treated as a metacharacter compared to when using directly in expression, so
200+
we can't use #personAge as a placeholder for 'person.age' because if the dot is part of an attribute name it is not treated as a metacharacter compared to when using directly in expression, so
263201
the above solution needs to be used
264202

265203
these are the accessor rules for nested attribute types
266-
- [n]for list elements
267-
- . (dot)for map elements
204+
- [n]for list elements
205+
- . (dot)for map elements
268206

269-
### Pagination
207+
## Pagination
270208
TODO
271209

272-
### Primary Key
273-
274-
To be clear about the used naming for keys, here is how we use it (same as in the official aws documentation):
275-
276-
DynamoDb has two key types **Partition Key** (hashkey - dynamodb internally uses a hash function to evenly distribute data items across partitions) and **Sort Key** (rangekey)
277-
The primary key can either be simple (only a partition key) or composite (combination of partition and sort key)
278-
279-
280-
## Contribution
281-
282-
## Development
283-
284-
### NPM scripts
210+
# Development
285211

212+
## NPM scripts
286213
- `npm t`: Run test suite
287214
- `npm start`: Runs `npm run build` in watch mode
288215
- `npm run test:watch`: Run test suite in [interactive watch mode](http://facebook.github.io/jest/docs/cli.html#watch)
@@ -291,34 +218,28 @@ The primary key can either be simple (only a partition key) or composite (combin
291218
- `npm run lint`: Lints code
292219
- `npm run commit`: Commit using conventional commit style ([husky](https://github.com/typicode/husky) will tell you to use it if you haven't :wink:)
293220

294-
### Automatic releases
295-
296-
We use automatic releases with Semantic Versioning, follow these simple steps.
297-
298-
semantic-release setup
299-
300-
From now on, you'll need to use `npm run commit`, which is a convenient way to create conventional commits.
221+
## Automatic releases
222+
Use the npm comand `npm run commit`, which is a convenient way to create conventional commits. Those messages are used to run [semantic releases](https://github.com/semantic-release/semantic-release),
223+
which publishes our code automatically on github and npm, plus generates automatically a changelog. This setup is highly influenced by [Kent C. Dodds course on egghead.io](https://egghead.io/courses/how-to-write-an-open-source-javascript-library)
301224

302-
Automatic releases are possible thanks to [semantic release](https://github.com/semantic-release/semantic-release), which publishes our code automatically on github and npm, plus generates automatically a changelog. This setup is highly influenced by [Kent C. Dodds course on egghead.io](https://egghead.io/courses/how-to-write-an-open-source-javascript-library)
225+
## Git Hooks
226+
We use 2 git hooks:
303227

304-
### Git Hooks
228+
`precommit`
229+
- to format the code with Prettier :nail_care: before sending it to the git repo.
230+
- to check if the commit message follows a [conventional commit message](https://github.com/conventional-changelog/conventional-changelog)
305231

306-
There is already set a `precommit` hook for formatting your code with Prettier :nail_care:
307232

308-
By default, there are 2 disabled git hooks. They're set up when you run the `npm run semantic-release-prepare` script. They make sure:
309-
- You follow a [conventional commit message](https://github.com/conventional-changelog/conventional-changelog)
310-
- Your build is not gonna fail in [Travis](https://travis-ci.org) (or your CI server), since it's runned locally before `git push`
311-
312-
This makes more sense in combination with [automatic releases](#automatic-releases)
233+
`prepush`
234+
- if the code can be built running npm run build
235+
- if all the tests pass
313236

314237
## Credits
315-
316238
[https://github.com/alexjoverm/typescript-library-starter](https://github.com/alexjoverm/typescript-library-starter) For the awesome project which helps to scaffold, develop and build a typescript library project
317239
[https://github.com/ryanfitz/vogels](https://github.com/ryanfitz/vogels) - To get an idea on how to build the chainable api
318240
[http://densebrain.github.io/typestore/](http://densebrain.github.io/typestore/) - Thats where the base idea on how to implement the model decorators came came from
319241

320242
## Contributors
321-
322243
Made with :heart: by [@michaelwittwer](https://github.com/michaelwittwer) and all these wonderful contributors ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)):
323244

324245
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "dynamo-easy",
33
"version": "0.0.1-alpha.1",
4-
"description": "",
4+
"description": "Use the power of typescript to define your object mapping when using dynamodb. This library also provides a fluent api for easy interaction with dynamodb.",
55
"keywords": [
66
"aws",
77
"dynamo",
@@ -10,7 +10,7 @@
1010
"mapper",
1111
"orm",
1212
"typescript",
13-
"typescript-decorator",
13+
"typescript-decorators",
1414
"fluent-api"
1515
],
1616
"main": "dist/dynamo-easy.umd.js",

0 commit comments

Comments
 (0)