Structure for a growing team
As the API grows, NestJS gives every piece a place: controllers speak HTTP, services hold the rules, DTOs validate input, and Nest wires them together with dependency injection. Today you write the service — the heart of the orders feature.
orders.service.ts
import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
import { CreateOrderDto } from "./order.dto";
import { PRICES } from "./prices";
export type Status = "new" | "cooking" | "ready";
export interface Order {
id: number;
dish: string;
qty: number;
total: number;
status: Status;
}
const NEXT: Record<Status, Status | null> = { new: "cooking", cooking: "ready", ready: null };
@Injectable()
export class OrdersService {
private orders: Order[] = [];
create(dto: CreateOrderDto): Order {
const price = PRICES[dto.dish];
if (price === undefined) throw new BadRequestException(`Unknown dish: ${dto.dish}`);
const order: Order = { id: this.orders.length + 1, dish: dto.dish, qty: dto.qty, total: price * dto.qty, status: "new" };
this.orders.push(order);
return order;
}
findAll(status?: Status): Order[] {
return status ? this.orders.filter((o) => o.status === status) : this.orders;
}
findOne(id: number): Order {
const order = this.orders.find((o) => o.id === id);
if (!order) throw new NotFoundException(`Order ${id} not found`);
return order;
}
advance(id: number): Order {
const order = this.findOne(id);
const next = NEXT[order.status];
if (!next) throw new BadRequestException("Order already ready");
order.status = next;
return order;
}
}