Your shop reads its products from shop.db. Now clients can add one: they send a POST to /products, the same path as the list, with the new product in the JSON body. Your route saves it with an INSERT statement.
Here is an INSERT on another table, a list of newsletter subscribers:
var cmd = db.CreateCommand();
cmd.CommandText = "INSERT INTO subscribers (email) VALUES ($email)";
cmd.Parameters.AddWithValue("$email", "sam@example.com");
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT last_insert_rowid()";
Console.WriteLine(cmd.ExecuteScalar()); // the id the database chose for the new row
Three things matter. Each placeholder gets its own value, so whatever text the client sends stays a value and never becomes SQL. You leave the id out: the database picks the next free number, and SELECT last_insert_rowid() tells you which. And ExecuteNonQuery() runs SQL that gives no rows back: here the new row is saved at once, since you didn't start a transaction.
Starting from the shop's 8 products, your code must answer:
POST /products {"name": "Vase", "price": 18, "category": "home"} → 201 {"id": 9}
GET /products/9 → 200 {"id": 9, "name": "Vase", "price": 18, "category": "home", "stock": 0}
POST /products {"name": "Candle", "price": 6} → 201 {"id": 10}
GET /products?max_price=6 → 200 [{"id": 4, "name": "Pen", …}, {"id": 10, "name": "Candle", "price": 6, "category": null, "stock": 0}]
Your task: add the route POST /products. Insert the name, the price and the category (which may be missing) from the JSON body with placeholders, and answer the new id with the status 201.
Assignment
Follow the Coding Tutorial to add the POST /products route, which saves a new product in the database.
Hint
Read the category with data.TryGetProperty: the Candle has none, and DBNull.Value is stored as NULL. Set the status with statusCode: 201 in Results.Json.
Free plan: 30 tutor messages. PRO is unlimited.
