Skip to main content

Hooks

Hooks transform generated endpoint arguments before the query service is called. REST currently exposes BeforeCreateOne, BeforeUpdateOne, and BeforeQueryMany. A hook can be an inline function or an injectable class.

Mutation hooks​

Decorate the create or update DTO when a value should be derived from the HTTP request rather than accepted from the client.

todo-item-input.dto.ts
import { Request } from 'express'
import { BeforeCreateOne, CreateOneInputType, Field } from '@ptc-org/nestjs-query-rest'

type AuthenticatedRequest = Request & {
user: { id: string }
}

@BeforeCreateOne((args: CreateOneInputType<TodoItemInputDTO>, request: AuthenticatedRequest) => ({
input: {
...args.input,
ownerId: request.user.id
}
}))
export class TodoItemInputDTO {
@Field()
title!: string

ownerId!: string
}

The function must return the complete wrapper ({ input } for create and { update } for update), not only the inner DTO.

todo-item-update.dto.ts
import { BeforeUpdateOne, UpdateOneInputType } from '@ptc-org/nestjs-query-rest'

@BeforeUpdateOne((args: UpdateOneInputType<TodoItemUpdateDTO>, request: AuthenticatedRequest) => ({
update: {
...args.update,
updatedById: request.user.id
}
}))
export class TodoItemUpdateDTO {
updatedById?: string
}

Query hooks​

BeforeQueryMany receives the built core query and can add filters, sorting, or other query properties. It is also the place to interpret the optional search term enabled by enableSearch.

todo-item.dto.ts
import { mergeFilter } from '@ptc-org/nestjs-query-core'
import { BeforeQueryMany, FilterableField, RestQuery } from '@ptc-org/nestjs-query-rest'

@BeforeQueryMany((query: RestQuery<TodoItemDTO>) => {
if (!query.query) {
return query
}

return {
...query,
filter: mergeFilter(query.filter ?? {}, {
title: { like: `%${query.query}%` }
})
}
})
export class TodoItemDTO {
@FilterableField()
title!: string
}

The same query hook runs for collection and CSV export requests.

Injectable hooks​

Use a class when a hook needs injected services:

import { Injectable } from '@nestjs/common'
import { BeforeCreateOneHook, CreateOneInputType } from '@ptc-org/nestjs-query-rest'

@Injectable()
export class SetOwnerHook implements BeforeCreateOneHook<TodoItemInputDTO, AuthenticatedRequest> {
run(args: CreateOneInputType<TodoItemInputDTO>, request: AuthenticatedRequest) {
return {
input: { ...args.input, ownerId: request.user.id }
}
}
}

@BeforeCreateOne(SetOwnerHook)
export class TodoItemInputDTO {}

When DTOs are listed in endpoints or dtos, NestjsQueryRestModule discovers and registers their hook providers automatically.