No announcement yet.
  • Filter
  • Time
Clear All
new posts

  • Record versionning


    I have a REST API that uses server-side record versioning validations ...

    Whenever I do a PUT to update a record, the client provides the current version of the record in my payload and the server
    makes sure that this is still the latest version before proceeding with the actual update.

    If the version has been updated by somebody else before I perform my PUT, the server returns an HTTP301 which I can
    intercept. I currently handle this in my transformResponse() method (that part is fine) ...

    Here's what I would like :

    1) display a warning message to the user (that I already achieve by adding an entry to dsResponse.errors)

    2) perform a fetch (GET) to reload the updated version of the record and have my dynamic form / values manager
    display the latest values, ready for the user to re-do his changes and click save again.

    For #2, I tried doing a fetch() and issuing an updateCaches() call directly from within my datasource.transformResponse()
    but that didn't work.

    Any idea how this should be handled ? Anything already built-in the ISC framework to handle record versioning ?


  • #2
    Funny, we actually just this past week created a wiki article on how to do this.

    The sample code shown is SmartGWT, and the approach is value comparison rather than a separate version number field, but you should be able to follow it.

    As far as updateCaches(), we wouldn't recommend just wiping out the user's data. As the article shows, we recommend giving the user a choice about how to proceed.


    • #3
      That's an interesting approach. You guys have used a pessimistic approach where you do a GET before issuing
      the PUT ...

      I'm using a more optimistic approach, where I issue my PUT and want to handle the specific case where the version
      may have changed (99% of the time it doesn't) ...

      I can understand where your pessimistic approach is the only way possible to achieve this, when you don't have a record version
      number built into your backend infrastructure.

      Since I do have that infrastructure, I'd rather use an optimistic route as it is more efficient ... A more specific question would be :

      When I do my PUT and get the error, within my transformResponse() I re-issue a GET to obtain the
      latest version of the record ... How can I do both:

      a) set dsResponse.errors (OK that's easy, I already do that ...)
      b) set with the updated record obtained from the nested GET (fetch) ?

      My challenge is around b) since the GET call is asynchronous and I'm already inside an asynchronous PUT call ? Any ideas ?

      Thanks for the example,


      • #4
        Don't re-issue the GET inside transformResponse, instead add server logic to return the data along with the error, then you don't have the synchronous/asynchronous mismatch. This is orthogonal to whether a version number is available and optimistic / pessimistic approach.


        • #5

          Modifying the PUT's response payload was not possible. This would have introduced a security breach
          in our REST API, where doing a PUT on something (with a bogus version) which you might not have fully
          access to, could have returned the full entity ...

          What I did instead, is set { willHandleError : true } in my saveData() 's request properties and handle
          this specific case by re-issuing a fetchData() following my initial failed saveData().

          Works for me and I've wrapped this logic in one of my base class so it's inherited in every single screen I have.

          It also remains optimistic which I believe is preferred since version conflicts don't happen that often.

          I do like your merging strategy, which I'll most probably implement at a later time.