Listing and Fetching Orders
Listing and Fetching Orders
Now that checkout can turn an open cart into a pending order, we need a way to actually see what was created. This lesson focuses on the two most common “read” operations in any backend: listing many resources (a collection) and fetching one resource (a single record).
You’ll implement and understand the two Orders endpoints our project exposes: GET /api/orders for paginated lists and GET /api/orders/:id for order details. Along the way, you’ll see how query params and route params are validated at the route layer, while the service layer handles defaults, caps, and “not found” behavior consistently.
Previously: From Cart to Order
In the previous lesson, we implemented checkout as a transactional workflow that snapshots cart items into order items, creates an order with status pending, and marks the cart as checked_out so it can’t be edited anymore. That gave us reliable order records in the database—now we’re building the read side so clients can browse and inspect those records.
Orders Retrieval: Collections vs. Single Resources
There are two ways clients typically access orders:
- Listing orders (collection): show a page of results, usually newest first.
- Fetching one order (resource): show details for a specific order, including its items.
In this project, those map to two Next.js route handlers:
src/app/api/orders/route.ts→GET /api/orderssrc/app/api/orders/[id]/route.ts→GET /api/orders/:id
Both routes follow the same overall pattern: validate inputs early, call a service function, and return a consistent API envelope using success(...) and error(...).
Listing Orders with Pagination
The list endpoint must be safe and scalable. Even a small shop can quickly accumulate thousands of orders, so we never want to return “all orders” in one response. Instead, we paginate using page and pageSize query parameters.
Route: parse and validate query parameters
This code lives in src/app/api/orders/route.ts. Its job is to read query params from the URL, validate them, then delegate to the service layer.
req.nextUrl.searchParamsis the Next.js-friendly way to access query parameters in route handlers. It gives us aURLSearchParamsobject, which is exactly what our validation helper expects.parseOptionalIntParam(...)does the heavy lifting of converting string values into numbers and enforcing bounds. Themin: 1forpageprevents invalid pages like0or-3, which would make pagination math nonsensical.pageSizeis capped with{ max: 100 }, which protects the database and API from extremely expensive requests. Even if a client tries?pageSize=100000, this route will reject it with a 400 instead of attempting the query.- After validation, the route passes clean numbers into
listOrdersService. The route doesn’t implement pagination rules itself beyond basic validation—those defaults and caps are enforced in the service too, so any caller (not just HTTP) stays safe. - The route returns consistent response envelopes using
success(...)for OK results anderror(...)for failures. That keeps your frontend/client code simple because responses are always shaped the same way.
