The Shop’s REST API
Let’s start with a RESTful HTTP API for the shop. We will keep this short. Here are the endpoints, the HTTP methods they accept, what they do, and who can use them:
| Request | Who | Effect |
|---|---|---|
GET /products |
shopper | List the products for sale |
GET /products/42 |
shopper | Read one product |
POST /products |
merchant | Create a product |
PUT /products/42 |
merchant | Replace name, description, price |
PATCH /products/42 |
merchant | Change some of those fields |
POST /products/42/stock |
merchant | Add or remove stock by an amount |
DELETE /products/42 |
merchant | Delete the product |
POST /carts |
shopper | Create an open cart |
GET /carts/73 |
shopper | Read a cart’s items and total |
PUT /carts/73/items/42 |
shopper | Add the item or set its quantity |
DELETE /carts/73/items/42 |
shopper | Remove the item |
POST /orders |
shopper | Place an order from a cart |
GET /orders/91 |
shopper | Read an order |
DELETE /products/42 soft deletes the product. A request for a deleted product returns the same 404 as a request for an unknown one. Placing an order takes an Idempotency-Key header.
Requests and responses
Reading a product sends this request:
GET /products/42 HTTP/1.1
Host: api.shop.example
The response carries the product’s name, description, price, and stock:
HTTP/1.1 200 OK
Content-Type: application/json
{
"product_id": 42,
"name": "Blue mug",
"description": "Hand-thrown stoneware with a deep blue glaze. Holds 350 ml. Dishwasher safe.",
"price_cents": 1800,
"quantity": 5
}
Reading the cart sends the same kind of request:
GET /carts/73 HTTP/1.1
Host: api.shop.example
The response shows the cart’s representation:
HTTP/1.1 200 OK
Content-Type: application/json
{
"cart_id": 73,
"status": "open",
"items": [
{ "product_id": 42, "quantity": 2 },
{ "product_id": 43, "quantity": 1 },
{ "product_id": 44, "quantity": 1 }
],
"total_cents": 7300
}
The cart holds product identifiers, quantities, and the total. It does not carry a product’s name or price, the way the product representation above does. A client that wants a product’s name or price reads the product separately. The cart’s quantity is how many the shopper wants, not the stock shown on the product.