RESTful request args/vars with JSON array

335 views
Skip to first unread message

Henry Nguyen

unread,
Oct 12, 2014, 5:32:23 PM10/12/14
to web...@googlegroups.com
I have a function in my controller decorated with the @request.restful() decorator. I would like to be able to accept a JSON array of objects, 

[{"id": 1, "new_value": 1},{"id": 2, "new_value": 2}]

, on a POST, PUT, or DELETE. For example, I'd like the client to be able to update a series of values on one request, as opposed to having to submit multiple requests for each individual update. However, the args and vars parameters being passed to the methods are empty when a request is sent with the JSON payload above. Specifically, args only gets populated from URL args and vars only get populated if the array is accompanied by a key, such as in:

{"update": [{"id": 1, "new_value": 1},{"id": 2, "new_value": 2}]}

While i
t certainly isn't too much trouble to include that initial key, I was wondering if there's any way to retrieve the JSON objects from the request without having to specify the key so that I could pass a simple array instead?  

Thank you ahead of time for any help.

Niphlod

unread,
Oct 13, 2014, 3:25:54 PM10/13/14
to web...@googlegroups.com
you have to code your own methods.

Henry Nguyen

unread,
Oct 22, 2014, 7:24:09 PM10/22/14
to web...@googlegroups.com
For posterity's sake, I was able to retrieve the array in the request body by using:

import json
my_list
= json.loads(request.body.read())

and then iterating through the list items just like any other list. This was taken from http://web2py.com/books/default/chapter/29/04#request under request.body.

Thanks for letting me know that request.restful() wouldn't parse it automatically, Niphlod.

Henry

Niphlod

unread,
Oct 23, 2014, 10:16:00 AM10/23/14
to web...@googlegroups.com
if the content-type of the POST request is application/json, "mylist" would actually be yet parsed into request.post_vars (i.e. you can skip body.read())

Henry Nguyen

unread,
Oct 23, 2014, 9:01:23 PM10/23/14
to web...@googlegroups.com
Niphlod,

That does not appear to be the case, either for request.restful() requests or regular controller requests. For example, consider this controller method:

def test():
    logger
.debug(request.env.content_type)
    logger
.debug(request.post_vars)
    logger
.debug(request.body.read())
   
return

With the request data as a JSON array of objects, such as:

[{"id":1, "is_read":true}]

I get the following logs:

2014-10-23 17:51:47,488 DEBUG test.py test():14 : application/json
2014-10-23 17:51:47,490 DEBUG test.py test():15 : <Storage {}>
2014-10-23 17:51:47,490 DEBUG test.py test():16 : [{"id":1, "is_read":true}]

With the data as a JSON object, such as

{"id":1, "is_read":true}

I get the following logs:

2014-10-23 17:54:46,468 DEBUG test.py test():14 : application/json
2014-10-23 17:54:46,469 DEBUG test.py test():15 : <Storage {u'is_read': True, u'id': 1}>
2014-10-23 17:54:46,470 DEBUG test.py test():16 : {"id":1, "is_read":true}

Note that request data is not parsed into request.post_vars. This would make sense to me; since request.post_vars is a Storage object which inherits from a Python dictionary, there would be no dictionary key to store the array value, no?

Henry

Niphlod

unread,
Oct 24, 2014, 3:37:15 AM10/24/14
to web...@googlegroups.com
what web2py version are you on ?

Henry Nguyen

unread,
Oct 24, 2014, 2:08:02 PM10/24/14
to web...@googlegroups.com
I'm on the latest version from the repo, 2.10.0-beta+timestamp.2014.10.16.15.58.50, though I had this issue on the mainline 2.9.11 as well.

Henry

Niphlod

unread,
Oct 24, 2014, 3:41:55 PM10/24/14
to web...@googlegroups.com
ok. got it. usually in APIs you don't post an array, you post an object. automatic parsing works only for objects, not for arrays.
Reply all
Reply to author
Forward
0 new messages