Possible contribution: Allowing PATCH on resource endpoints

8 views
Skip to first unread message

Jeremy Solbrig

unread,
Sep 18, 2018, 1:24:17 PM9/18/18
to Eve REST Framework
I am considering making a contribution to Python-eve, but am hoping to get a bit of feedback before putting in the work.  I'd hate to put work in on this only to find that it is not wanted or that I am going about this the wrong way.

My colleagues have need of the ability to perform a mass update (i.e. update_many).  I can add this functionality via a custom endpoint, but that seems clumsy when I can just add the functionality to the resource endpoints themselves.  This would involve allowing operators in update documents (currently defaults to "$set" on all fields in eve/io/mongo.py) and allowing queries in updates.  To do this, I would do the following:

  1. eve/flaskapp.py
    1. Add "PATCH" to `supported_resource_methods`.
  2. eve/endpoints.py
    1. Edit collections_endpoint to call `update` for `PATCH` requests.
  3. eve/io/mongo.py
    1. Modify `update()` to:
      1. If no operator is present in the first layer of the document, add the "$set" operator (this is currently done in all cases).
      2. If operators are present in the first layer of the document, just pass the document as is.
  4. eve/io/validation.py
    1. Add handling for operators to `Validate.validate_update()`.  
I have mapped out how to add handling for operators to `Validate.validate_update()`, but am unsure if my approach is the best approach.  Maybe I can make better use of cerberus for this, but I am not sure how to do so.  To do this, I would attempt to make the best use of cerberus that I can.  

There are several things that need to be done to prepare the document for validation through cerberus.  There are a few different cases that need to be handled (including some that I am avoiding for now).  To handle these, a new document would be constructed for validation as though the $set operation is being performed.
  1. Scalar operators
    1. $inc, $min, $max, $mul, $set, $setOnInsert: 
      1. Remove the operator
      2. Move the field and value up a level
      3. Validate the field and value as if they are going to be used in a $set operation
      4. {"$min": {"field1": 1}} becomes {"field1": 1} for validation.
    2. $currentDate: Leave unhandled for now, until I have a better understanding of cerberus.Validator.
  2. Array Operators
    1. $addToSet, $push, $pull, $pullAll: 
      1. Remove the operator
      2. Move the field and value up a level
      3. Turn any scalars into arrays
      4. Validate the field and value as if they are going to be used in a $set operation
      5. {"$push": {"field1": 1}} becomes {"field1": [1]}
      6. {"$pullAll": {"field1": [1, 2, 3, ...]}} becomes {"field1": [1, 2, 3, ...]}}
    2. $pop:
      1. Check that the value is either 1 or -1
      2. Remove from the document prior to validation
  3. Operators to skip for now, but which need to be handled later:
    1. Scalar Operators: $currentDate
    2. Array Operators: $, $[], $[<identifier>]
    3. Modifiers: $each, $position, $slice, $sort, $bit
I think this is the full set of required modifications and would be very happy to hear some feedback on this.
Reply all
Reply to author
Forward
0 new messages