Identifying records in an adjustment web service

44 views
Skip to first unread message

API Dev

unread,
Oct 10, 2017, 4:36:41 AM10/10/17
to API Craft

Our application allows users to read/add/edit/delete table records through the UI. To prevent concurrent users from editing the same row (stale object scenarios) we use a row identifier and row version field in the table. These operations are now exposed through web services too. In order to reuse code the read api was designed to return the row id and row version values from the database so that the same values could be passed in the adjust api to identify a row in the table. So if a user wants to edit a row in table, he needs to first fetch it using the read api to get the row id & row version. These values need to be then passed to the adjust api call so that the system identifies the right row and perform the edit operation.

 

I understand that there are two issues with such an api design

  1. Internal database details are exposed through API's
  2. Performance - currently the adjust api call needs to be coupled with the read api call.

 

Business wise we do have a concept of key fields in the table which define functional uniqueness. We could use these user defined fields to identify the row but how would we prevent concurrent row updates without row version?

 

Do you have any suggestions on how could the api be designed to cater to the business requirements?


Thanks.

Jørn Wildt

unread,
Oct 10, 2017, 6:33:11 AM10/10/17
to api-...@googlegroups.com
Take a look at ETags for HTTP they do pretty much what you want in a standardized way (without exposing internal database design). At its core it is "read record - then send update data with row version".

See also https://www.w3.org/1999/04/Editing/ for some introduction.

Check also HTTP PATCH for partial updates - and lookup "JSON patch format" (https://tools.ietf.org/html/rfc6902) as well as "JSON merge format" (https://tools.ietf.org/html/rfc7386) .

/Jørn


--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/d/optout.

Przemek Wesołek

unread,
Oct 11, 2017, 4:26:15 AM10/11/17
to API Craft
To see it applied in practice, take a look at CouchDB and their versioning via "_rev" property.


It can be passed in entity body as well as in ETag


Przemek
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.

API Dev

unread,
Oct 13, 2017, 1:17:12 AM10/13/17
to API Craft
Thanks for the replies.

If I understand it correctly, ETag is a standard way (for HTTP based REST API's) of defining the current revision of a resource. This helps the servers implement concurrent updates to a resource. HTTP specification does not specify how the value is generated. It details on the lifecycle of the ETag header value i.e. at what instances should be be generated.

Few follow up questions
1. In the adjustment use case I need a revision number per record returned by the web service. The number of records accepted in the request body could be in thousands. How would 
2. The HTTP specification does not specify what the value would be for this response header. So effectively I could pass the record id & version as the value. How would it resolve the concern of exposing internal database ids? Did I misunderstand the concept?

Thanks.

Jørn Wildt

unread,
Oct 13, 2017, 9:42:42 AM10/13/17
to api-...@googlegroups.com
> 1. In the adjustment use case I need a revision number per record returned by the web service. The number of records accepted in the request body could be in thousands. How would 

I guess you mean "How would I specify ETag for all of those thousands"? I don't know - I haven't seen an ETag solution or similar for batches - only individual resources/entities.

> 2. The HTTP specification does not specify what the value would be for this response header. So effectively I could pass the record id & version as the value. How would it resolve the concern of exposing internal database ids? Did I misunderstand the concept?

No, you didn't misunderstand :-) The actual ETag value (content) is completely irrelevant to the client, so it won't know you have used internal IDs and it won't depend on it being database ID's. All the client knows is that it is a string (without semantics) that it has to supply with its next request. You can replace it with a hash of your IDs, a timestamp, JWT or whatever else.

So, yes, you do "expose" database IDs - but not in a sense that causes trouble as the client won't depend on it being database IDs.

/Jørn



To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+unsubscribe@googlegroups.com.

mca

unread,
Oct 13, 2017, 10:40:09 AM10/13/17
to api-...@googlegroups.com
the most effective ETag is based on the _representation_ (message body) emitted by the server and has nothing to do with the data storage _behind_ the web server. 

i find the most reliable (and, frankly easiest) way to generate ETags is to pass the message body (HTML, XML, HAL, JSON, CSV, etc.) to a function that computes the base64 value of the message body.


API Dev

unread,
Oct 16, 2017, 1:07:30 AM10/16/17
to API Craft
Is the summary of the discussion so far that ETag would not help to resolve the problem I mentioned in the post? Reason - ETag provide a standard way of conveying the revision of the resource but here we are talking about records within the json body and not just one resource.

Just to be on the same page I would like to rephrase the overall problem that I intend to get inputs on - how to design a REST api to adjust records in a table given that the same operation is already supported through the web application UI. Hence an important goal would be to reuse code as much as possible. The adjustment operation has a requirement of preventing concurrent updates for which the software already implements optimistic locking.

Appreciate the responses/thoughts on this problem. Please let me know your suggestions.

Thanks.
Reply all
Reply to author
Forward
0 new messages