---
description: Validating DTOs inside one another.
---

# Nested validation

To validate an entity, the underlying rules must be followed:

* The entity must be an **object**
* The object must have a **single field**, the <mark style="color:blue;">`id`</mark>
* The <mark style="color:blue;">`id`</mark> must be a **positive integer**

Sounds familiar? We already have a structure that meets these requirements: The <mark style="color:blue;">`IdDto`</mark>. Because of that, we can use it to type the <mark style="color:blue;">`categories`</mark> field inside the DTO.

Apart from that, we just need to indicate that the validation used will be from the <mark style="color:blue;">`IdDto`</mark> itself. We can achieve that with the <mark style="color:blue;">`@ValidateNested()`</mark> decorator. Lastly, as it is not a primitive type, we need to explicitly state the type that is being validated with <mark style="color:blue;">`@Type()`</mark>. With that, we should get the following result:

```typescript
@ArrayNotEmpty()
@ArrayUnique()
@ValidateNested()
@Type(() => IdDto)
readonly categories: IdDto[];
```

As a last improvement, we can create the decorator <mark style="color:blue;">`@IsEntity()`</mark> for this specific validation. Let's do so now in <mark style="color:purple;">common</mark>/<mark style="color:purple;">decorators</mark>/<mark style="color:purple;">is-entity.decorator</mark>. Note that, in this case, we need to also add the validator <mark style="color:blue;">`@IsDefined()`</mark> to enforce validation if the field is not present.

```typescript
/** Checks if the value is an object with only a serial id. */
export const IsEntity = (): PropertyDecorator =>
  applyDecorators(
    IsDefined(),
    ValidateNested(),
    Type(() => IdDto),
  );
```

Now, we can use it in this field and whenever necessary.

However, the <mark style="color:blue;">`@ArrayUnique()`</mark> validator will not work now because we are validating objects, which are compared by reference. Fortunately, we can fix this by passing an **identifier function** to the decorator that states how these objects should be compared. The idDtos should be compared by their ids, so let's create this function in <mark style="color:purple;">common</mark>/<mark style="color:purple;">util</mark>/<mark style="color:purple;">id.util</mark>.

```typescript
export const idDtoIdentifier = (dto: IdDto) => dto.id;
```

And then simply pass this function (<mark style="color:red;">not</mark> call it) to the decorator.

<mark style="color:green;">**Commit**</mark> - Implementing product logic and using nested validation
