22

I am working on designing a resource for this service which has a set of mutable properties and a set of immutable ones (for example, status which is generated by the service and not something the client may change).

I need to include this in responses to GET requests for the resource but am not sure what to do if someone then sends the resource with a PUT request.

Forcing the caller to know which properties are immutable feels wrong, but silently discarding updates also feels incorrect. Responding with the updated resource to the PUT request might solve the issue, but it's imperfect since the caller shouldn't have to do a diff of its request and the service's response to find out if a property was accepted.

Any thoughts on the right way forward?

P.S. I looked at How should I update a REST resource? but it's different from this question and promotes an overly-chatty API design.

Community
  • 1
  • 1
ehdv
  • 4,483
  • 7
  • 32
  • 47

4 Answers4

12

I would suggest following the guidelines at http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10. The definition of HTTP 409 includes the following:

1) The request could not be completed due to a conflict with the current state of the resource.

2) The response body SHOULD include enough information for the user to recognize the source of the conflict.

Thus as changes to immutable properties are a problem with the state of the resource, HTTP 409 seems to apply.

As for how to communicate the issue to the client, the guidance seems to be to include details in the response body.

You could also communicate mutability of properties in the representation itself (on the GET). For example.

<MyObject>
   <Foo>17</Foo>
   <Bar readOnly="true">22</Bar>
   ....
EJK
  • 12,332
  • 3
  • 38
  • 55
  • 1
    I think this is probably the way to go: If they attempt to change the immutable property then it's a 409; if they leave it alone then we accept it back from them and silently discard it. The end state matches their expectations, and the property stays read-only. – ehdv Dec 12 '13 at 19:55
3

You could design your API's responses so that the read-only properties are actually separate from the mutable ones. For example:

{
    id: 42,
    status: "terrific",
    properties: {
        // mutable properties here
    }
}

I have both written and consumed APIs that do this, and it's worked out just fine.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 9
    I'd be concerned about this approach since it puts a trait of the property into the hierarchy. Also, mutability could change, such as if part of a resource was temporarily locked for some reason. – ehdv Dec 12 '13 at 19:58
1

Use HTTP PATCH with JSON-Patch documents - this allows you to pin-point exactly the properties you want to modify. See https://www.rfc-editor.org/rfc/rfc6902.

But there is nothing wrong about PUT'ing both immutable and mutable elements back. The server is free to ignore what ever it doesn't want to make changes to. I wrote an in-depth discussion on this topic here: http://soabits.blogspot.dk/2013/01/http-put-patch-or-post-partial-updates.html

Community
  • 1
  • 1
Jørn Wildt
  • 4,274
  • 1
  • 21
  • 31
  • 1
    _"[HTTP PATCH] allows you to pin-point exactly the properties you want to modify."_ Sure, but that doesn't help the client know which properties are modifiable and which are not, and I really don't think your blog post makes a compelling argument that it's okay to ignore whatever it does not want to change. I'm not saying you're wrong, I just think you have not necessarily justified some claims. – Matt Ball Dec 12 '13 at 13:23
  • Patching in itself doesn't tell the client which fields it can modify. This would require a hypermedia element in the initial representation: a "form" element explaining which fields are immutable and which are not. If the set of immutable fields changes at runtime then that is the only solution I can see. If the set of immutable fields are fixed then I don't see any problem with the client being hard coded with that knowledge. On a larger scale though, hypermedia is the way to go: this will loosen up client-server coupling and allow the server to evolve over time without breaking the clients. – Jørn Wildt Dec 12 '13 at 14:42
  • And if we add hypermedia elements to the response then PUT'ing everything back becomes even stranger. I mean, why should form (and link) elements be PUT back to the server (they are certainly immutable)? Which, I would argue, speaks in favor of PATCH (as well as traditional POST with x-www-form-urlencoded key/value pairs or JSON ... but then NULL handling becomes an issue as I argued in the blog post). – Jørn Wildt Dec 12 '13 at 15:47
1

Another solution is to send the read-only fields back as HTTP headers. That way you can keep the GET and PUT resources identical.

This probably makes most sense if the read-only fields are primarily "technical" fields such as createTime, updateTime, etc. Status could be regarded as a technical field as well ?

Foumpie
  • 1,465
  • 1
  • 14
  • 10