# 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](/dynamo-easy/api/dynamo-easy-config/configuration.md#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="/pages/-LVx1fIk9xamIAcJancw" %}
[Mapping Concept](/dynamo-easy/api/model/mapping-concept.md)
{% 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://shiftcode.gitbook.io/dynamo-easy/api/model/decorators.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
