Skip to content

PUT, PATCH & DELETE

These three methods cover the “U” and “D” of CRUD. The subtle one is the difference between PUT and PATCH — get it right and updates stay predictable.

PUT replaces the resource at a URI with the representation in the body. Send the whole resource; any field you omit is, semantically, being set to absent. Because the result of PUT-ing the same body twice is identical to once, PUT is idempotent.

PUT /articles/42 HTTP/1.1
Content-Type: application/json
{ "title": "Updated title", "body": "Full new body" }

PATCH applies a partial modification. Two common formats:

  • JSON Merge Patch (application/merge-patch+json): send only the fields to change; null means “remove this field”.
  • JSON Patch (application/json-patch+json): send an array of explicit operations (add, remove, replace, …).

PATCH is not guaranteed idempotent in general (an op like “append to a list” is not), though many merge-patch updates happen to be.

DELETE removes the resource. It is idempotent: deleting an already-deleted resource still leaves it deleted. Return 204 No Content (or 200 OK with a body) on success; a second DELETE may return 204 or 404 depending on your policy — pick one and be consistent.

JavaScript

Using PUT for a partial update Symptom:

  • PUT /users/\{id\} sends only { "name": "New Name" } — every other field resets to null
  • PUT requires the full resource — anything missing becomes null/default
  • Use PATCH for partial updates

A DELETE that isn’t idempotent Symptom:

  • DELETE /users/\{id\} returns 200 the first time, 500 (server error) the second time
  • It should return 404 or 204 the second time, not 500
  • Deleting an already-gone resource should consistently return 404 or 204

💡 Real-world examples

GitHub API:

  • PATCH /repos/\{owner\}/\{repo\} — edit some repo settings
  • DELETE /repos/\{owner\}/\{repo\} — delete a repo (idempotent — 404 on the second call)

Stripe API:

  • PATCH for updating customer info
  • No true DELETE for a charge — use a refund instead (keeps an audit trail)

Sources: GitHub REST API — repos, Stripe API — refunds

What does PUT do to fields omitted from the request body?
In JSON Merge Patch, what does a field set to null mean?
Why is DELETE considered idempotent?