Let’s clarify the distinction between POST and PUT in the context of resources and sub-resources, using the Cash Card and Invoice APIs as examples:
- A resource is any entity your API manages (e.g., a Cash Card or Invoice).
- A sub-resource is a child entity nested under a parent resource (e.g., a specific Cash Card under the
/cashcards
collection).
-
How it works:
- The client sends a request to a parent URI (e.g.,
POST /cashcards
). - The server generates a unique ID (e.g.,
101
) and creates a new sub-resource under the parent URI. - The new resource’s URI is determined by the server (e.g.,
/cashcards/101
).
- The client sends a request to a parent URI (e.g.,
-
Example: Cash Card API
- Client sends:
POST /cashcards { "amount": 50 }
- Server responds with:
201 Created Location: /cashcards/101
- The new Cash Card is a sub-resource of
/cashcards
.
- Client sends:
-
Why POST?
The client doesn’t know the final URI upfront—it depends on the server-generated ID. POST is designed for creating sub-resources in a collection.
-
How it works:
- The client sends a request to a specific URI (e.g.,
PUT /invoices/1234-567
). - The server creates or replaces the resource exactly at that URI.
- No new sub-resource is created—the URI is fully specified by the client.
- The client sends a request to a specific URI (e.g.,
-
Example: Invoice API
- Client sends:
PUT /invoices/1234-567 { "total": 100 }
- Server responds with:
201 Created (or 200 OK if updating) Location: /invoices/1234-567
- The Invoice exists at the exact URI provided by the client.
- Client sends:
-
Why PUT?
The client knows the full URI in advance (e.g., using a natural key like an invoice number). PUT is idempotent, meaning repeated requests have the same result (safe for client-controlled URIs).
Action | POST | PUT |
---|---|---|
Target URI | Parent collection (e.g., /cashcards ) |
Specific resource (e.g., /invoices/1234-567 ) |
Who defines the URI? | Server | Client |
Result | Creates a sub-resource (e.g., /cashcards/101 ) |
Creates/replaces resource at the client-specified URI |
Idempotent? | No (multiple POSTs create duplicates) | Yes (multiple PUTs have the same effect) |
-
POST is like adding a new file to a folder:
- You ask the server, "Add this to the
cashcards
folder." - The server names the file (e.g.,
101.json
).
- You ask the server, "Add this to the
-
PUT is like saving a file to an exact path:
- You tell the server, "Save this as
invoices/1234-567.json
." - You control the filename and location.
- You tell the server, "Save this as
-
Use POST when:
- The server generates the resource’s ID/URI (sub-resource creation).
- You’re working within a collection (e.g.,
/cashcards
).
-
Use PUT when:
- The client specifies the full URI (natural key).
- You want idempotent behavior (no duplicates on retries).
This distinction ensures your API follows RESTful principles and behaves predictably.