Start learning free

LESSON 75 OF 173 · BACKEND: APIS WITH A DATABASE

Place an Order in JavaScript

Practice

So far, clients could only read orders. Now they place them: a POST to /orders with a JSON body that names the customer and lists the items, each with a product_id and a quantity.

One order is saved as several rows: first one row in orders, then one row in order_items per item. Every item row needs the order's id, which the database only gives when the order's row is inserted: result.lastInsertRowid holds it. Here is the idea on two other tables, a reading list and its books:

const result = db.prepare("INSERT INTO lists (owner) VALUES (?)").run("Mia");
const listId = result.lastInsertRowid;
for (const title of ["Dune", "Emma"]) {
  db.prepare("INSERT INTO list_books (list_id, title) VALUES (?, ?)").run(listId, title);
}

The client only chooses the customer and the items. The shop sets the rest itself: the date (SQLite's date('now')), the status 'new', and each item's unit_price, read from products at the moment of the order. With node:sqlite, every run is saved in shop.db right away, so there is no commit to write. An order without items is refused with 400, before anything is written.

Your route must give these answers, in this order:

POST /orders  {"customer_id": 5, "items": [{"product_id": 6, "quantity": 1}, {"product_id": 4, "quantity": 3}]}  →  201  {"id": 8}
GET /orders/8/items  →  200  {"order_id": 8, "items": [{"name": "Teapot", "quantity": 1, "unit_price": 22}, {"name": "Pen", "quantity": 3, "unit_price": 2}], "total": 28}
GET /orders/8        →  200  {"id": 8, "ordered": (today's date), "status": "new", "customer": "Eva Rossi"}
POST /orders  {"customer_id": 1, "items": [{"product_id": 8, "quantity": 2}]}  →  201  {"id": 9}
GET /orders/9/items  →  200  {"order_id": 9, "items": [{"name": "Gift card", "quantity": 2, "unit_price": 50}], "total": 100}
POST /orders  {"customer_id": 2, "items": []}  →  400  {"error": "An order needs at least one item"}

The check also reads shop.db: orders 8 and 9 must be saved, dated today, with the status new and their items, and nothing must be saved for the refused order.

Your task: fill in POST /orders (the route and its data are already there). It inserts the order and one row per item, and answers 201 with the new order's id, or 400 when the list of items is empty.


Assignment
Follow the Coding Tutorial to fill in the POST /orders route.


Hint
Keep result.lastInsertRowid right after the order's INSERT: every item row needs it. Check for an empty data.items right after reading the body, before the first INSERT.


STEP 1 OF 11
    Ctrl + Enter to check

    Db Place Order in JavaScript

    Keep going with JavaScript1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free