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.