> 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/extra-module-5-advanced-querying/pagination/querying-structure.md).

# Querying structure

A structure to encapsulate and organize these functionalities, as we're already used to.

We can further improve pagination:

* In the <mark style="color:blue;">`PaginationDto`</mark>, send the <mark style="color:blue;">`page`</mark> directly and then calculate the <mark style="color:blue;">`offset`</mark>
* Set max values for <mark style="color:blue;">`limit`</mark> and <mark style="color:blue;">`page`</mark>, as to prevent a bottleneck
* Apart from the records, also return a <mark style="color:blue;">`meta`</mark> field including:
  * <mark style="color:blue;">`itemsPerPage`</mark> - Amount of items per page
  * <mark style="color:blue;">`totalItems`</mark> - Total amount of items
  * <mark style="color:blue;">`currentPage`</mark> - Number of the current page
  * <mark style="color:blue;">`totalPages`</mark> - Total amount of pages
  * <mark style="color:blue;">`hasNextPage`</mark> - Existence of a next page
  * <mark style="color:blue;">`hasPreviousPage`</mark> - Existence of a previous page

> Some fields' names were obtained from the package [nestjs-paginate](https://www.npmjs.com/package/nestjs-paginate).

Well, before delving deeper, let's first create a structure to house everything related to **pagination**/**filtering**/**sorting**. As data related to this is generally received as **query params**, I'll create a folder inside <mark style="color:purple;">src</mark> called <mark style="color:purple;">querying</mark>.

After that, let's relocate here what already exists related to this context. So, relocate the <mark style="color:purple;">pagination.dto</mark> file into <mark style="color:purple;">querying</mark>/<mark style="color:purple;">dto</mark>. Let's also relocate the <mark style="color:blue;">`DefaultPageSize`</mark> constant to <mark style="color:purple;">querying</mark>/<mark style="color:purple;">util</mark>/<mark style="color:purple;">querying.constants</mark> with **Right click** -> **Refactor** -> **Move to file**.

<mark style="color:green;">**Commit**</mark> - Relocating querying structure

Let's then begin. Back in the <mark style="color:blue;">`PaginationDto`</mark>, alter the name of <mark style="color:blue;">`offset`</mark> to <mark style="color:blue;">`page`</mark>. While using the <mark style="color:blue;">`offset`</mark>, we did not need to worry about it not being sent. However, if the <mark style="color:blue;">`page`</mark> is not sent, it should have a **default value**, as the <mark style="color:blue;">`offset`</mark> will be calculated from it. As it will no longer be an optional property in the class, just remember to add <mark style="color:blue;">`@ApiPropertyOptional()`</mark> over it.

```typescript
readonly page: number = 1;
```

{% hint style="info" %}
Sending the <mark style="color:blue;">`page`</mark> directly prevents the possibility of sending an <mark style="color:blue;">`offset`</mark> that is inconsistent with the <mark style="color:blue;">`limit`</mark> (should be a **multiple** of it).
{% endhint %}

Let's also set **max values** for <mark style="color:blue;">`limit`</mark> and <mark style="color:blue;">`page`</mark>, preventing the possibility of requesting a <mark style="color:blue;">`page`</mark> with **huge size** and **too far ahead**. We do this because this is a limitation of the **offset-based pagination**: without these precautions, it may be very **costly** and **inefficient** if both values are too big. In practice, a customer would not commonly reach these limits. Let's then add them to the <mark style="color:purple;">querying.constants</mark> file.

```typescript
export const MAX_PAGE_SIZE = 100;
export const MAX_PAGE_NUMBER = 25;
```

We may then, in the <mark style="color:blue;">`PaginationDto`</mark>, set the max value to <mark style="color:blue;">`limit`</mark>...

```typescript
@Max(MAX_PAGE_SIZE)
```

...and to <mark style="color:blue;">`page`</mark>.

```typescript
@Max(MAX_PAGE_NUMBER)
```

<mark style="color:green;">**Commit**</mark> - Sending page directly and max values in pagination dto

We may then proceed. Let's create a **module** to hold **services** related to **querying**, beginning with a service for **pagination**.

```sh
nest g mo querying
nest g s querying/pagination --flat
```

{% hint style="info" %}
Remember to **export** the service, and **import** the module in the <mark style="color:blue;">`ProductsModule`</mark>.
{% endhint %}

With this structure, we may start the metadata generation.
