Skip to main content

Getting Started

The @ptc-org/nestjs-query-rest package creates documented REST CRUD controllers on top of a QueryService. It provides DTO decorators, generated controllers, filtering, offset paging, hooks, authorization, and CSV export.

Installation

See the installation guide.

This example uses the TypeORM adapter, so install it and TypeORM alongside the REST package (plus the TypeORM driver for your database):

npm i @ptc-org/nestjs-query-typeorm @nestjs/typeorm typeorm

Define the DTOs

The response DTO declares the fields returned by the API and which fields clients may filter on. Separate create and update DTOs keep writable fields explicit.

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

export class TodoItemDTO {
@IDField()
id!: number

@FilterableField()
title!: string

@FilterableField()
completed!: boolean
}
todo-item-input.dto.ts
import { Field } from '@ptc-org/nestjs-query-rest'

export class TodoItemInputDTO {
@Field({ maxLength: 100 })
title!: string

@Field()
completed!: boolean
}
todo-item-update.dto.ts
import { Field } from '@ptc-org/nestjs-query-rest'

export class TodoItemUpdateDTO {
@Field({ nullable: true, maxLength: 100 })
title?: string

@Field({ nullable: true })
completed?: boolean
}

Register an endpoint

Register the persistence module and describe the endpoint in NestjsQueryRestModule.forFeature. basePath is optional; without it, the path is derived from and pluralized from the DTO class name (TodoItemDTO becomes /todo-item-dtos).

todo-item.module.ts
import { Module } from '@nestjs/common'
import { NestjsQueryRestModule } from '@ptc-org/nestjs-query-rest'
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'

import { TodoItemDTO } from './dto/todo-item.dto'
import { TodoItemInputDTO } from './dto/todo-item-input.dto'
import { TodoItemUpdateDTO } from './dto/todo-item-update.dto'
import { TodoItemEntity } from './todo-item.entity'

@Module({
imports: [
NestjsQueryRestModule.forFeature({
imports: [NestjsQueryTypeOrmModule.forFeature([TodoItemEntity])],
endpoints: [
{
DTOClass: TodoItemDTO,
EntityClass: TodoItemEntity,
CreateDTOClass: TodoItemInputDTO,
UpdateDTOClass: TodoItemUpdateDTO,
basePath: 'todo-items'
}
]
})
]
})
export class TodoItemModule {}

This creates the following endpoints:

MethodPathDescription
GET/todo-itemsFilter and page records
GET/todo-items/:idFind one record
POST/todo-itemsCreate one record
PUT/todo-items/:idUpdate one record
DELETE/todo-items/:idDelete one record
GET/todo-items/exportExport matching records as CSV

Enable request transformation and validation

The generated query and body DTOs use class-transformer and class-validator. Enable Nest's ValidationPipe so query strings such as limit=10 are converted and validated.

main.ts
import { ValidationPipe } from '@nestjs/common'
import { NestFactory } from '@nestjs/core'

import { AppModule } from './app.module'

async function bootstrap() {
const app = await NestFactory.create(AppModule)
app.useGlobalPipes(
new ValidationPipe({
transform: true,
whitelist: true
})
)
await app.listen(3000)
}

void bootstrap()

Continue with DTOs, controllers, or the query endpoint examples.