# Decorators

To get started with defining a model add the [@Model()](https://shiftcode.github.io/dynamo-easy/modules/_decorator_impl_model_model_decorator_.html) decorator to your typescript class.

{% embed url="<https://shiftcode.github.io/dynamo-easy/modules/decorators.html>" %}
technical api docs
{% endembed %}

## Model Decorators

### @Model

Use the `@Model` decorator to make it 'mappable' for the dynamo-easy mapper.\
You can optionally pass an object containing the table name if you don't want the default table name.\
The default table name is built with `${kebabCase(modelName)}s`

{% code title="my-model.snippet.ts" %}

```typescript
import { Model } from '@shiftcoders/dynamo-easy'

@Model({ tableName: 'my-model-table-name' })
export class MyModel {

}
```

{% endcode %}

{% hint style="info" %}
To use different table names on different stages the [tableNameResolver](https://shiftcode.gitbook.io/dynamo-easy/dynamo-easy-config/configuration#tablenameresolver) is the right choice.
{% endhint %}

{% hint style="info" %}
If you need to read the metadata by hand for some purpose, use the `metadataForModel` function to read the informations.
{% endhint %}

## Key Decorators

### Primary Key

* `PartitionKey`
* `PartitionKeyUUID`which generates an id using the [uuid package](https://www.npmjs.com/package/uuid) (peer dependency)
* `SortKey`

{% code title="my-model-with-sort-key.snippet.ts" %}

```typescript
import { Model, PartitionKey, SortKey } from '@shiftcoders/dynamo-easy'

@Model()
export class MyModel {
  @PartitionKey()
  myPartitionKey: string

  @SortKey()
  mySortKey: number
}
```

{% endcode %}

### Global Secondary Index

We provide two decorators to work with global secondary indexes:

* `GSIPartitionKey`
* `GSISortKey`

{% hint style="info" %}
You can use multiple GSI on the same model and also use the same property for different Indexes
{% endhint %}

{% code title="my-model-with-gsi.snippet.ts" %}

```typescript
import { Model, GSIPartitionKey, GSISortKey } from '@shiftcoders/dynamo-easy'

const MY_MODEL_GSI = 'NameOfGSI' 

@Model()
class MyModel {
  @GSIPartitionKey(MY_MODEL_GSI)
  myGsiPartitionKey: string

  @GSISortKey(MY_MODEL_GSI)
  myGsiSortKey: number
}

```

{% endcode %}

### Local Secondary Index

{% code title="my-model-with-lsi.snippet.ts" %}

```typescript
import { Model, LSISortKey, PartitionKey, SortKey } from '@shiftcoders/dynamo-easy'

@Model()
class MyModel {
  @PartitionKey()
  myPartitionKey: string

  @SortKey()
  mySortKey: number

  @LSISortKey('NameOfLSI')
  myLsiSortKey: number
}
```

{% endcode %}

## Type Decorators

### @Property(options)

#### options

`name: string` define a different name (than the property name) for DynamoDB.

`mapper: MapperForType` define a custom mapper (e.g if you want to use a complex object as PartitionKey or SortKey)

### @CollectionProperty(options)

The CollectionProperty decorator is used for arrays and sets. It defines if the values should be mapped to \[L]ist or \[(N|S|B)S]et and stores the information how the Attributes should be parsed.

#### options

`itemType: ModelConstructor` provide the class of the items inside the collection if they have decorators (this ItemClass also needs the `@Model` decorator)

`itemMapper: MapperForType` provide a custom mapper to map the complex items of your collection to \[S]tring, \[N]umber or \[B]inary. This is mainly useful if you want to store them in a \[S]et.&#x20;

`sorted: boolean` the collection will be stored as \[L]ist (\[S]et does not preserve the order) no matter if the javascript type is a `Set` or an `Array` .

`name: string` define a different name (than the property name) for DynamoDB.

{% hint style="info" %}
it does not make sense to provide both, the itemType and an itemMapper. An Error would be thrown.
{% endhint %}

> further information how arrays and sets are mapped:

{% content-ref url="mapping-concept" %}
[mapping-concept](https://shiftcode.gitbook.io/dynamo-easy/api/model/mapping-concept)
{% endcontent-ref %}

### @DateProperty(options)

The DateProperty decorator is just syntactic sugar for `@Property({mapper: dateMapper})`\
all properties decorated with it will be mapped with the default dateMapper or the one you define with `updateDynamoEasyConfig({dateMapper: MapperForType})`.

{% hint style="info" %}
dynamo-easy provides two date mappers:\
\- dateToStringMapper *(default)* which maps to ISO string`{ S: date.toISOString() }`\
\- dateToNumberMapper which maps to unix timestamp ``{ N: `${date.toTime()}` }``
{% endhint %}

#### options

`name: string` define a different name (than the property name) for DynamoDB.

## Other

### @Transient

The `@Transient` decorator can be used to ignore a property when the object is mapped.

{% hint style="info" %}
We map all properties (`Object.getOwnPropertyNames(objectToMap)`) by default. Use the [@Transient](https://shiftcode.gitbook.io/dynamo-easy/~/edit/drafts/-LYRfBDOu4fbNeiERleF/api/model/decorators#transient) decorator to prevent a property from being mapped.
{% endhint %}

{% code title="my-model-with-transient.snippet.ts" %}

```typescript
import { Model, Transient } from '@shiftcoders/dynamo-easy'

@Model()
class MyModel {
    @Transient()
    myPropertyToIgnore: any
}
```

{% endcode %}
