Need some guidance on best practices for building a RESTful API in node.js
Let's say I have a person record like so:
{
id: 1,
name: 'Jon',
age: 25,
recordVersion: 1
}
If I need to increment the recordVersion every time a value gets changed, would I still use a HTTP PUT to update this record? I've researched on how PUT should be idempotent and should contain the newly-updated representation of the original resource, so I am no sure of what to do.
I could increment the recordVersion property on the first PUT call and send an error on the second PUT call with the same versionNumber of 1 (because it would have incremented to 2 at that point), but does this follow RESTful API standards?
The resources sent over the wire are a representation of the state, not the actual state.
It's perfectly fine to remove the recordVersion and to update it behind the scenes - however if you do that, it would be best to remove it from the representation returned by a GET to that resource as well. To understand why: idempotency is all about what would happen if you applied the operation multiple times in a row (it isn't guaranteed if other operations happen in between...), and about observable side effects.
Idempotent, because the resource representation has not changed as a result of calling PUT twice, even though the internal entity state has changed - no observable side effects.
See http://restcookbook.com/HTTP%20Methods/idempotency/ for a bit more detail.
As you note, you could use inspect the version and throw an error if it has changed - and in fact this is very RESTful, and in my opinion the best way to approach PUT as it helps avoid (often inexplicable) concurrency errors. If you detect this case, it would be appropriate to return a 409 Conflict http status code.
How this would work is:
v1 != v2
This is idempotent, because there have been no observable side effects as a result of calling the operation twice.
The client should, in response to a 409, do another GET to get the latest version code, and possibly offer to the user the opportunity to merge their changes with whatever else has changed in the meantime.
Often people confuse idempotency with thinking that the response to the operation must be the same as a result of multiple calls, but that is not the case - it is about there being no observable side effects as a result of multiple sequential calls.