Real World Example

Order History in a Food Delivery App

The "Your Orders" screen in Zomato or Swiggy is an infinite list with filters (delivered, cancelled) and date ranges. The API combines a filter DTO with cursor pagination and returns a nextCursor the app sends back when the user scrolls.

src/orders/orders.controller.ts

import { Controller, Get, Query } from '@nestjs/common';
import { Type } from 'class-transformer';
import { IsEnum, IsInt, IsISO8601, IsOptional, IsString, Max, Min } from 'class-validator';
import { CurrentUser } from '../auth/current-user.decorator';

export class OrderHistoryQuery {
  @IsOptional() @IsEnum(['DELIVERED', 'CANCELLED', 'ACTIVE']) status?: 'DELIVERED' | 'CANCELLED' | 'ACTIVE';
  @IsOptional() @IsISO8601() from?: string;
  @IsOptional() @IsString() cursor?: string;
  @IsOptional() @Type(() => Number) @IsInt() @Min(1) @Max(50) limit: number = 10;
}

@Controller('orders')
export class OrdersController {
  constructor(private readonly orders: OrdersService) {}

  @Get('history')
  history(@CurrentUser('id') userId: number, @Query() query: OrderHistoryQuery) {
    return this.orders.history(userId, query);
  }
}

Example

curl -H "Authorization: Bearer <token>" "http://localhost:3000/orders/history?status=DELIVERED&limit=2"

Example output

{"data":[{"id":"ORD-7781","restaurant":"Meghana Foods","total":"642.00","deliveredAt":"2026-01-15T14:02:11.000Z"},{"id":"ORD-7702","restaurant":"Empire Restaurant","total":"389.00","deliveredAt":"2026-01-12T20:41:37.000Z"}],"nextCursor":"WyIyMDI2LTAxLTEyVDIwOjQxOjM3LjAwMFoiLCJPUkQtNzcwMiJd"}