I've introduced API fencing into django-bananas to handle the "lost update problem", that is dealing with the issue of "simultaneous" edits from multiple admins overwriting each other's changes.
It would be nice to build automatic support for this into django-bananas.js. There are now two builtin fences in django-bananas: allow_if_unmodified_since rejects updates when the given If-Unmodified-Since header is less than the stored date_modified on the model, and allow_if_match rejects updates when the given If-Match header does not contain the version of the stored model (version can be a stored or a computed value). Fences are exposed as in-header arguments in the OpenAPI schema and should be discoverable.
I'm thinking we preferably want to build in support so that these work out of the box given the resource exposes the respective fields, but with support for overriding (or composing) the source of the tokens. In the case of allow_if_unmodified_since we want to use the exposed date_modified field by default and if it exists. For allow_if_match we want to use the exposed version field by default and if it exists.
It's also possible to compose arbitrary fences that are not shipped by default (e.g. for If-Match or whatever) and we should try and build in corresponding composable building blocks into the client.
In Python composing a fence looks like this:
allow_if_not_modified_since = Fence(
# Function that takes a request and returns the If-Modified-Since header
# as a parsed datetime object.
get_token=header_date_parser("If-Modified-Since"),
# Function for comparing the header value with the stored value to
# determine whether to allow or reject the request.
compare=operator.gt,
# function that takes a model instance and returns its date_modified
get_version=parse_date_modified,
openapi_parameter=openapi.Parameter(...),
# Specifies status code of rejected requests
rejection=NotModified("The resource is unmodified"),
)
What do you think? Is this feasible to build automatic support for? If we need to prioritize I think automatic discovery and support for the two builtin fences should be supported, but it'd be really nice to get composability for arbitrary fences from the get-go.
I'd be happy to write this if no-one else bites, but I'd probably need some pointers to understand where something like this could be plugged in.
I've introduced API fencing into django-bananas to handle the "lost update problem", that is dealing with the issue of "simultaneous" edits from multiple admins overwriting each other's changes.
It would be nice to build automatic support for this into django-bananas.js. There are now two builtin fences in django-bananas:
allow_if_unmodified_sincerejects updates when the givenIf-Unmodified-Sinceheader is less than the storeddate_modifiedon the model, andallow_if_matchrejects updates when the givenIf-Matchheader does not contain the version of the stored model (version can be a stored or a computed value). Fences are exposed as in-header arguments in the OpenAPI schema and should be discoverable.I'm thinking we preferably want to build in support so that these work out of the box given the resource exposes the respective fields, but with support for overriding (or composing) the source of the tokens. In the case of
allow_if_unmodified_sincewe want to use the exposeddate_modifiedfield by default and if it exists. Forallow_if_matchwe want to use the exposedversionfield by default and if it exists.It's also possible to compose arbitrary fences that are not shipped by default (e.g. for
If-Matchor whatever) and we should try and build in corresponding composable building blocks into the client.In Python composing a fence looks like this:
What do you think? Is this feasible to build automatic support for? If we need to prioritize I think automatic discovery and support for the two builtin fences should be supported, but it'd be really nice to get composability for arbitrary fences from the get-go.
I'd be happy to write this if no-one else bites, but I'd probably need some pointers to understand where something like this could be plugged in.