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.
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.
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.
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.