CodingNic

REST API Design

CRUD and HTTP Methods

REST API Design 12 min read

CRUD and HTTP Methods

Objectives

By the end of this lesson, you should be able to:

  • Map each CRUD operation to its correct HTTP method
  • Explain the difference between PUT (full replacement) and PATCH (partial update)
  • Return the correct status code for each CRUD operation, including 204 No Content

💡 Why this matters: Module 5 already used GET, POST, PUT, and DELETE, this lesson makes the mapping explicit and complete, adds PATCH, and fixes a genuinely common mistake, using PUT when the intent is actually a partial update.

⚠️ A note on verification: every snippet and every response shown below was actually run and tested with real HTTP requests.

The Full CRUD Mapping

Operation HTTP Method Example Typical status
Create POST POST /products 201 Created
Read (collection) GET GET /products 200 OK
Read (single) GET GET /products/5 200 OK
Update (full) PUT PUT /products/5 200 OK
Update (partial) PATCH PATCH /products/5 200 OK
Delete DELETE DELETE /products/5 204 No Content

PUT: Full Replacement

javascript
app.put('/products/:id', (req, res) => {
  const index = products.findIndex(p => p.id === Number(req.params.id));
  if (index === -1) return res.status(404).json({ error: 'Not Found' });
  products[index] = { id: Number(req.params.id), ...req.body };
  res.json(products[index]);
});
bash
curl -X PUT http://localhost:4501/products/2 -H "Content-Type: application/json" -d '{"name":"Ultra Monitor","price":300}'
text
{"id":2,"name":"Ultra Monitor","price":300}
bash
curl http://localhost:4501/products/2
text
{"id":2,"name":"Ultra Monitor","price":300}

The original products[1] had a category: 'displays' field, sending a PUT request without it removed it entirely, PUT replaces the whole resource with exactly what’s sent, this is the defining, and most commonly misunderstood, behavior of PUT.

PATCH: Partial Update

javascript
app.patch('/products/:id', (req, res) => {
  const product = products.find(p => p.id === Number(req.params.id));
  if (!product) return res.status(404).json({ error: 'Not Found' });
  Object.assign(product, req.body);
  res.json(product);
});
bash
curl -X PATCH http://localhost:4501/products/2 -H "Content-Type: application/json" -d '{"price":199}'
text
{"id":2,"name":"Monitor","price":199,"category":"displays"}

PATCH, using Object.assign(product, req.body) (Module 2), merges only the fields sent into the existing resource, category stays untouched here, only price changed, this is the correct method whenever a client only wants to change part of a resource, updating just a product’s price shouldn’t require resending its entire name and category too.

DELETE and 204 No Content

javascript
app.delete('/products/:id', (req, res) => {
  const index = products.findIndex(p => p.id === Number(req.params.id));
  if (index === -1) return res.status(404).json({ error: 'Not Found' });
  products.splice(index, 1);
  res.status(204).send();
});
bash
curl -i -X DELETE http://localhost:4501/products/3
text
HTTP/1.1 204 No Content

204 No Content means success, with deliberately no response body, res.status(204).send() with nothing passed to send() sends an empty body, this is the conventional status for a successful DELETE, there’s nothing meaningful left to return once a resource is gone.

Try It

  1. Build PUT and PATCH routes for the same resource, and demonstrate the difference: send a PUT request omitting a field, and confirm it disappears, then send a PATCH request with the same partial body, and confirm the rest of the resource is untouched.
  2. Add a DELETE route returning 204 No Content on success, and 404 if the resource doesn’t exist, test both with curl -i.
  3. Build a full CRUD set (POST, GET collection, GET single, PUT, PATCH, DELETE) for one resource, and test every operation with curl.
  4. Explain, in your own words, a real situation where using PUT instead of PATCH would cause a client to accidentally lose data.

Recap

  • POST creates, GET reads, PUT fully replaces, PATCH partially updates, DELETE removes, this is the complete CRUD-to-HTTP-method mapping.
  • PUT replaces a resource entirely, any field left out of the request body is removed, PATCH merges only the fields sent, leaving the rest untouched.
  • 204 No Content (no response body) is the conventional status for a successful DELETE.

Next lesson: resource design, naming and structuring URLs consistently.