8

I have implemented optimistic locking for my REST resources that have 1-to-1 mapping to database tables by passing back a version number which was in the GET back through to the PUT call. If the version number changed in the database between the time I did the GET and the PUT, then an optimistic lock exception has occurred. Pretty simple design.

Now, how do I do the same for composite REST resources that map to multiple database tables? I'd like to not have to pass back multiple version fields (one for each data table that relates to the composite resource). A simplistic example of a composite resource would be /FooBar where /Foo and /Bar are non-composite resources.

I'm basically looking for an example of the REST implemetation of Fowler's Coarse Grained Locking pattern: http://martinfowler.com/eaaCatalog/coarseGrainedLock.html

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
BestPractices
  • 12,738
  • 29
  • 96
  • 140
  • In your REST service can you just collect the versions and put them into a a Map that is keyed by a uniquely generated id that represents the version? Then send that to the client and have them send it back to you after an edit? Then you can use that one id to get the versions for the graph of entities. – robert_difalco Feb 03 '13 at 22:07

1 Answers1

5

This is what the ETag header was designed for. A very common way to implement it is to produce your response payload, make a hash of it (it doesn't have to be secure, just low-collision), and then use that hash as the value of the ETag. Note that this approach is ignorant of how many sources are involved in producing the response.

The client then sends the received ETag back in an If-Match header, which the server can use to check the freshness of the request.

Community
  • 1
  • 1
fumanchu
  • 14,419
  • 6
  • 31
  • 36
  • And if it is not "fresh" enough, the HTTP server sends a [409 (conflict) status code](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10). – Aurélien Bénel Feb 15 '13 at 07:47
  • 412 actually. See http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-21#section-3.1 – fumanchu Feb 15 '13 at 16:04
  • Hmm, interesting. The specification is lenient then, since the example in 409 is quite explicit : "For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request". – Aurélien Bénel Feb 15 '13 at 17:24
  • 1
    Yes, but you'll notice that ETag and If-Match are not mentioned there. 409 is for any conflicts which are not codified by an ETag. Note that that approach allows one to PUT an update which changes one part of a document, and if it is not the same portion which the earlier request changed, then the server can proceed to merge them without erroring. You can't do that with ETag/If-Match, which is a "whole document" sledgehammer. – fumanchu Feb 15 '13 at 23:57