Search code examples
pythoneve

what is the reason that python-eve drops lookup parameters on POST operations?


I would like to make use of query parameters in POST and other modification methods. This could apply to regular query parameters or to those extracted by url rules with variables. But I am noticing that Eve specifically drops these parameters for POST calls. I can easily make the changes necessary to preserve them, but since they are being intentionally dropped, I'm wondering if there is some downside to having them around. What is the reason for this design decision?

Example Usecase

Perhaps there is a question why would someone ever want to use query parameters like this. The API I have in mind uses query parameters in POST and DELETE calls. One example of why this might be convenient is to allow user to modify the validation and actual behavior of the call. To give a somewhat contrived example:

DELETE /resource/123
    -- fails if there are dependent objects for this resource
DELETE /resource/123?cascade=true  
    -- allow delete to cascade to dependent objects (eg. user clicked "I am sure")

Another example:

POST /user?allowId=True  { "id" : 123, "name" : "Bob }
    -- will accept externally-defined ID as opposed to generating a new one

Another example:

POST /container/<foo>/resource    { ... }
    -- create a new resource inside of the <foo> container

Edited

I tried to use the request.args to get at the variable rules but it doesn't seem to work. (It is possible to get at the query args this way, but I'd like the variable rules to work as well.)

*in settings.py*
DOMAIN = {
    'ducks' : {
        'url':'rows/<row>/ducks',
        'schema': {
            'name' : { 'type' : 'string' }
        }
    }
}

*command line*
curl -H "Content-Type: application/json" -X POST 'http://localhost:5001/rows/1/ducks' -d '{"name":"bob"}

When the code enters my on_pre_POST hook, request.args is empty. If I walk up the stack I see that in endpoints.collection_endpoint() function lookup does contain {'row':1} but it is not passed into the post(response) call. I can submit a pull request to fix this, if it makes sense.

Edited 2

I found that these parameters are available in request.view_args as opposed to request.args. This means both kinds of parameters are accessible anywhere in flask/eve without code changes.


Solution

  • Since on_pre_POST passes the request object you can easily achieve that:

    def my_pre_post_callback(resource, request):
        allowId = request.args.get('allowId')
        ...