Start learning free

LESSON 73 OF 173 · BACKEND: APIS WITH A DATABASE

Orders

Practice

The shop's database holds more than products. The table orders has one row per order: its id, the customer_id of the customer who placed it, the date it was placed (ordered) and its status. The customer's name is not in that row: it lives in another table, customers.

A JOIN reads two tables in one query. Its ON condition says which rows belong together, and table.column says which table a column comes from. Here is the idea on two other tables, books and their authors:

SELECT books.title, authors.name AS author
FROM books
JOIN authors ON authors.id = books.author_id

Each book is paired with the one author whose id is the book's author_id. AS author renames the column in the result, so the row object has the key author. A long query can be written in pieces, one string per line in an array: .join(" ") glues them into one string, with a space between them. The type Order, already at the top of your file, describes the row your query gives: one key for each column of the SELECT.

Your route must give these answers:

GET /orders/1   →  200  {"id": 1, "ordered": "2026-03-02", "status": "paid", "customer": "Ana Pop"}
GET /orders/4   →  200  {"id": 4, "ordered": "2026-04-18", "status": "shipped", "customer": "Chloe Ng"}
GET /orders/6   →  200  {"id": 6, "ordered": "2026-05-21", "status": "cancelled", "customer": "Ben Ortiz"}
GET /orders/99  →  404  {"error": "Order not found"}

Your task: add GET /orders/:orderId. It reads the order and its customer's name with one JOIN query and answers them as JSON, or 404 when no order has that id.


Assignment
Follow the Coding Tutorial to add the route /orders/:orderId and its JOIN query.


Hint
Both tables have a column id, so write orders.id or customers.id, never just id. Take the row with .get(orderId) and end the line with as Order | undefined: it gives undefined when no order has that id, as in the /products/:productId route.


STEP 1 OF 8
    Ctrl + Enter to check