> For the complete documentation index, see [llms.txt](https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/core-module-backend-development-with-nestjs/remaining-domain/logic/entity-validation/nested-validation.md).

# 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
