# RESTful API Design - POST vs PUT vs PATCH

Source: https://tpiros.dev/blog/restful-api-design-post-vs-put-vs-patch

In a previous article, we looked at the [basics of REST API design](https://fullstack-developer.academy/restful-api-design-the-basics/). We mentioned the various HTTP methods but didn't dig into the differences between POST, PUT, and PATCH. This post covers those differences, plus idempotent and safe HTTP methods.

These three methods confuse developers constantly. Let's clear it up with an analogy.

Picture an empty plot of land. We can build multiple houses on it, each placed at a numbered parcel. We're planning which house goes where.

In REST terms, calling `http://domain.com/house` with `HTTP POST` would build a house on parcel 1 (`1` being an auto-generated system ID).

# POST

`POST` creates a resource. To build a house, we need its requirements in JSON:

```json
{
  "front_garden": true,
  "back_garden": true,
  "windows": 3,
  "doors": 2,
  "garage": true
}
```

Sending that payload to `http://domain.com/house` places a house with those properties at parcel 1 (the parcel number acts as the system-generated ID).

Want another house? Create another payload (same or different) and hit `http://domain.com/house` again. It lands at parcel 2.

The key point: no matter how many times you call POST, it always creates a new house at a different location with a unique system ID.

# PUT

Now let's fire a `PUT` request. We still need a payload, but several things can happen. Let's send this to `http://domain.com/house/1`:

```json
{
  "front_garden": true,
  "back_garden": true,
  "windows": 13,
  "doors": 3,
  "garage": false
}
```

We're telling the server to `PUT` this house at parcel 1.

We already have a house there from our earlier POST. What happens? PUT replaces the entire resource with the payload.

So if we send only this:

```json
{
  "windows": 8
}
```

the result is a house with only a `windows` property. Everything else is gone, because PUT overwrites the full resource with the new payload.

> With PUT, always define the entire resource. Otherwise you'll end up with missing data.

What if we PUT to a resource that doesn't exist? It gets created. Send a payload to `http://domain.com/house/5` and that house appears at parcel 5.

# PATCH

`HTTP PATCH` applies a partial update. Whatever's in the payload gets merged into the existing resource.

Say we have this house:

```json
{
  "front_garden": true,
  "back_garden": true,
  "windows": 13,
  "doors": 3,
  "garage": false
}
```

and we send this PATCH:

```json
{
  "windows": 8
}
```

The result:

```json
{
  "front_garden": true,
  "back_garden": true,
  "windows": 8,
  "doors": 3,
  "garage": false
}
```

If the payload contains a property that doesn't exist on the resource, PATCH adds it.

> Calling `HTTP PATCH` on a resource that doesn't exist should fail. The resource should not be created. That's a significant difference from how PUT behaves.

# Idempotent

The term "idempotent" comes up a lot when discussing REST APIs.

> Idempotence is a mathematical property used in both computer science and mathematics. It means that applying an operation N times always produces the same end result.

With that definition, we can sort HTTP methods into idempotent and non-idempotent.

`HTTP GET` is idempotent. The same GET request always returns the same resource.

`HTTP POST` is not idempotent. Each POST creates a new resource with a unique ID. Five identical POST requests produce five different resources.

`HTTP PUT` is idempotent. Updating a resource always yields the same outcome: either a new resource gets created (if it didn't exist) or the existing one gets replaced. The result stays the same each time.

`HTTP PATCH` is tricky. Generally, it's not idempotent, though implementation can change that. Consider a PATCH to `/employee` that changes salary from 10 to 15. After the first request, any subsequent request saying "change salary where salary is 10" fails because the resource has already changed.

> `PATCH` can be made idempotent using the `ETag` and `If-Modified-Since` HTTP headers.

# Safe Methods

In RESTful APIs, we also talk about safe HTTP methods. A safe method never modifies a resource.

# Summary of Safe and Idempotent HTTP methods

| HTTP Method | Idempotent | Safe |
|-------------|------------|------|
| GET         | yes        | yes  |
| POST        | no         | no   |
| PUT         | yes        | no   |
| PATCH       | no*        | no   |
| DELETE      | yes        | no   |
| OPTIONS     | yes        | yes  |
| HEAD        | yes        | yes  |

> - `PATCH` can be made idempotent; please see above how.

# Summary

We walked through the differences between HTTP POST, PUT, and PATCH using a house-building analogy. We also examined which HTTP methods are idempotent and which are safe.
