1

In a proper REST API implementation, imagine I'm writing an API to let the user modify a uri slug, such as changing /acme/first to be /acme/second.

Depending if I'm submitting a partial record (patch) or the whole record (put) that currently represents first, should the uri vary?

For example:

PUT /acme/second
{ [...], "current-slug": "first", "color": "blue" }

Put against the new uri because put means "this goes here."

vs.

PATCH /acme/first
{ "new-slug": "second", "color": "blue" }

Patch against the old uri because patch means "modify the thing that's here."

I suspect this is an edge case, but interesting because virtually all documentation happens to show the same uri for a put vs patch action, though obviously post is generally a different uri.

Devin Burke
  • 13,642
  • 12
  • 55
  • 82

1 Answers1

2

This is definitely a little bit of an edge case. One obvious HTTP method to do this, is actually just the HTTP MOVE method. This method comes from WebDAV, but it should work everywhere.

MOVE /acme/first HTTP/1.1
Destination: /acme/second

This would be my top recommendation, because it fits the problem so well.

What's weird with either PATCH or PUT is that they are both expecting to update the resource at the target uri, but the result of the operation is more similar to DELETE because it removes the resource (and creates a new one somewhere else).

Because of this, I would be inclined to suggest to use neither for this case. This is enough of an edge case to warrant a special POST request.

But yea... MOVE is perfect. Any HTTP client or server that doesn't deeply understand MOVE semantics should treat it similar to POST (unsafe, not idempotent).

Community
  • 1
  • 1
Evert
  • 93,428
  • 18
  • 118
  • 189
  • 1
    Using WebDAV's `move` is an interesting idea. I deliberately added `color` above though to invalidate it. Theoretically, I want to change two properties: `id` / `slug` and `color`. Move makes sense, but efficiency says this is one continuous operation as it's filled out in one user-facing form (let's say). I think your suggestion of `post` (as a "generic CRUD operations that aren't clearly something else") is probably the only viable option. – Devin Burke Apr 25 '19 at 19:20