0

I have a REST API with a PUT endpoint which looks like this:

api.website.net/resources/resourceId

The controller implementation of this endpoint looks like follows:

@RequestMapping("/resources/{resourceId}") public Resource putResource(@PathVariable(value = "resourceId") String resourceId, @RequestBody(required = false) Resource resource)

There is the case where a user may perform a PUT on this resource, but neglect to provide an object in the body (i.e. resource == null is true).

Which of the following approaches is more RESTful?

  1. Have a PUT on this endpoint simply return the existing Resource object with no changes, or
  2. Make the object required in the request body?

Note that the object exists at the given URL in both cases.

filpa
  • 3,651
  • 8
  • 52
  • 91

2 Answers2

1

From my interpretation of the definition of PUT, it would be more RESTful to require a body because the definition seems to imply an entity exists:

From https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

9.6 PUT

The PUT method requests that the enclosed entity be stored under the supplied Request-URI.

The part which says "the enclosed entity" to me implies an entity actually exists.

I think if you PUT nothing, it would end up being the same as a DELETE. This just makes me think even more that a body should be required for PUT and DELETE should be used for that functionality.

All this being said, it is certainly possible to implement something which accepts PUT requests with no body, though as I said I don't think this would be RESTful.

There is some discussion about this topic here: Is an HTTP PUT request required to include a body?

Community
  • 1
  • 1
Adam
  • 2,214
  • 1
  • 15
  • 26
  • Thank you for your answer. It seems indeed the better choice to include the body in every `PUT` request. – filpa Dec 22 '16 at 12:38
1

There is the case where a user may perform a PUT on this resource, but neglect to provide an object in the body (i.e. resource == null is true).

Intriguing.

The PUT method is mentioned in appendix D of the HTTP/1.0 spec, was included in the HTTP/1.1 specification, and is currently defined within the content and semantics chapter of the 2014 HTTP/1.1 spec.

Its use case lineage is page publishing, taking the representation embedded within the request and writing it into the servers own store.

A PUT request, with no payload, is analogous to a request that you upsert an empty file into a specific location. That's a perfectly reasonable thing for a file system or a key value store to do.

Which of the following approaches is more RESTful?

The applicable constraint of REST is the uniform interface - PUT on this resource should have the same semantics as PUT everywhere else on the web. So it's important that PUT handling is idempotent, and that a successful PUT creates/replaces the state of the resource with the state defined by the representation in the request.

Have a PUT on this endpoint simply return the existing Resource object with no changes Make the object required in the request body?

The second of these, I think, is closer to what you want. You can't force the client to send you a valid representation of your resource, but you can reject any request that doesn't provide a valid representation. So if you find that the provided representation isn't satisfactory, you should be thinking in terms of 400 Bad Request or 409 Conflict.

Note: when sending a 4xx response, you are normally sending a representation of the problem, rather than a representation of the resource.

Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition.

Returning a copy of the current state of the resource isn't useful for telling the client what went wrong.

Community
  • 1
  • 1
VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91
  • Thank you for your answer! It was a tough choice to choose between the two, I wish I could accept both. :) – filpa Dec 22 '16 at 12:39