patterns = [ ("posts/{post.id}", {"coments": {"author": "auth_user"}}] # My implementation .... parser = Rest.generate(patterns, args, kwargs)
This automatically generate, the post with comments associate and user associated to a comment... What do you think about my idea ? 2014-06-23 9:50 GMT-05:00 samuel bonill <pythonn...@gmail.com>: > Thanks massimo, this is the point, generate many2many relations, with one > request get all the information relations to a resource. I'm developing a > plugin to generate great RESTful API based in many2many relations. inspired > by the Instagram API > <http://instagram.com/developer/endpoints/users/#get_users>. > > for example : > > > GET: http://example.com/default/index/posts/1.json > > > { > "data": [{ > > "id": "1", > "title": "web2py", > "text": "testing ...", > "picture": "http://web2py.s3.amazonaws.com/post/my_s3_file.jpg";, > "coments": [{ > "id": 1, > "text": "my coment", > "author": {"id":3685, "name": "Lebron james" ...}, > }, ... ] > > }] > > } > > I'm trying do this possible, this is my implementation : > > > > 2014-06-23 0:14 GMT-05:00 Massimo Di Pierro <massimo.dipie...@gmail.com>: > > Let me add that Collection+JSON is a standard but that does not make it >> perfect. I find many limitations. I managed to overcome some but utilizing >> extensions. >> https://github.com/mamund/collection-json/tree/master/extensions >> I also made some of my own extensions. Extensions are allowed and >> compatible. >> >> Yet it needs more extensions. I did not push this too much because I did >> not want to depart too much much from the standard. >> >> Collection+JSON is also very verbose. I made a Collection(compact=True) >> option that makes it much less verbose but will break the specs. >> >> >> >> On Monday, 23 June 2014 00:01:27 UTC-5, Massimo Di Pierro wrote: >>> >>> This is a automatic in Colleciton+JSON. For example: >>> >>> # assume a model that described things and their attributes >>> db.define_table('thing',Field('name')) >>> db.define_table('attr',Field('thing','reference thing'),Field('name')) >>> >>> and you expose both: >>> >>> def api(): >>> from gluon.contrib.hypermedia import Collection >>> rules = { >>> 'thing': { >>> 'GET':{'query':None,'fields':['id', 'name']}, >>> 'POST':{'query':None,'fields':['name']}, >>> 'PUT':{'query':None,'fields':['name']}, >>> 'DELETE':{'query':None}, >>> }, >>> 'attr': { >>> 'GET':{'query':None,'fields':['id', 'name', 'thing']}, >>> 'POST':{'query':None,'fields':['name', 'thing']}, >>> 'PUT':{'query':None,'fields':['name', 'thing']}, >>> 'DELETE':{'query':None}, >>> }, >>> } >>> return Collection(db).process(request,response,rules) >>> >>> $ curl http://127.0.0.1:8000/super/collections/api/thing/1 >>> {"collection": {"version": "1.0", "href": "/super/collections/api/thing", >>> "items": [{"href": "http://127.0.0.1:8000/super/ >>> collections/api/thing/1/chair", "data": [{"prompt": "Id", "name": "id", >>> "value": 1}, {"prompt": "Name", "name": "name", "value": "Chair"}], >>> "links": [{"href": "http://127.0.0.1:8000/super/ >>> collections/api/attr?thing=1",..... >>> >>> The links field tells you how to get the attributes of the thing Chair. >>> >>> For many2many and links to images you have to do a little bit more >>> programming. For example: >>> >>> Given: >>> db.define_table('thing',Field('name'),Field('image','upload')) >>> >>> You can define: >>> rules = {'thing':{'GET':{'query':None, 'fields':None, >>> 'links':{'picture':lambda row: URL('download',args=row.image, >>> scheme=True)}}}} >>> >>> Problem is that collection+JSON does not say anything about image >>> uploads (POST) and does not say anything about many2many relations. >>> >>> Massimo >>> >>> >>> >>> >>> On Sunday, 22 June 2014 18:20:36 UTC-5, samuel bonill wrote: >>>> >>>> it's good, I use db.parse_as_rest for generate the representation of >>>> resources, Collection+JSON help much. >>>> >>>> other thing, I would like generate a resource with relationship .... >>>> for example >>>> >>>> >>>> patterns = [ ("posts/{post.id}", {"coments": {"author": >>>> "auth_user"}}] # My implementation >>>> .... >>>> parser = db.parse_as_rest(patterns, args, kwargs) >>>> >>>> GET: http://example.com/default/index/posts/1.json >>>> >>>> { >>>> "content": [{ >>>> "id": "1", >>>> "title": "web2py", >>>> "text": "testing ...", >>>> "picture": "http://web2py.s3.amazonaws.com/post/my_s3_file.jpg";, >>>> "coments": [{ >>>> "id": 1, >>>> "text": "my coment", >>>> "author": {"id":3685, "name": "Lebron james" ...}, >>>> }, ... ] >>>> >>>> }] >>>> } >>>> >>>> the problem with the traditional RESTful apps on web2py is that for get >>>> the information >>>> of our restful example planted before, you need do three request to the >>>> api, like this case. >>>> >>>> patterns = [ "post/{post.id}", >>>> "post/{post.id}/coments[coments]/{coments.id}", >>>> >>>> >>>> "post/{post.id}/coments[coments]/{coments.id}/author[auth_user]" >>>> >>>> ] >>>> .... >>>> parser = db.parse_as_rest(patterns, args, kwargs) >>>> >>>> #1 GET: http://example.com/default/index/post/1.json >>>> >>>> #2 GET: http://example.com/default/index/post/1/coments/1.json >>>> #3 GET: http://example.com/default/index/post/1/coments/1/author.json >>>> >>>> sorry my english... regards >>>> >>>> >>>> >>>> El domingo, 22 de junio de 2014 15:45:06 UTC-5, Massimo Di Pierro >>>> escribió: >>>>> >>>>> I added Hypermedia API support to web2py using Collection+JSON. >>>>> Experimental. >>>>> Collection+JSON is a standard for self documenting RESTful API. >>>>> Read more: http://amundsen.com/media-types/collection/ >>>>> >>>>> Example >>>>> ========= >>>>> >>>>> Let's say you have a model: >>>>> >>>>> db.define_table('thing',Field('name')) >>>>> >>>>> and in controller default.py you add >>>>> >>>>> def api(): >>>>> from gluon.contrib.hypermedia import Collection >>>>> rules = { >>>>> 'thing': { >>>>> 'GET':{'query':None,'fields':['id', 'name']}, >>>>> 'POST':{'query':None,'fields':['name']}, >>>>> 'PUT':{'query':None,'fields':['name']}, >>>>> 'DELETE':{'query':None}, >>>>> }} >>>>> return Collection(db).process(request,response,rules) >>>>> >>>>> And now by magic your table "thing" is fully exposed using the >>>>> Collection+JSON API. The API is self documenting and supports GET, POST, >>>>> PUT, DELETE, etc. >>>>> >>>>> For example you can do things like: >>>>> >>>>> curl http://127.0.0.1:8000/app/default/api/thing >>>>> curl http://127.0.0.1:8000/app/default/api/thing/1 >>>>> curl http://127.0.0.1:8000/app/default/api/thing?id=1 >>>>> curl http://127.0.0.1:8000/app/default/api/thing?name=Box&id. >>>>> gt=10&_offest=10&_limit=30 >>>>> curl -X POST -d name="Box" http://127.0.0.1:8000/app/default/api/thing >>>>> curl -X PUT -d name="Chair" http://127.0.0.1:8000/app/ >>>>> default/api/thing?name=Box >>>>> curl -X DELETE http://127.0.0.1:8000/super/collections/conform/thing? >>>>> name=Chair >>>>> >>>>> The API are completely self documenting as explained here >>>>> http://amundsen.com/media-types/collection/ >>>>> >>>>> It is customizable >>>>> ============== >>>>> >>>>> rules = { >>>>> 'thing': { >>>>> 'GET':{'query':None,'fields':['id', 'name']}, >>>>> 'POST':{'query':None,'fields':['name']}, >>>>> 'PUT':{'query':None,'fields':['name']}, >>>>> 'DELETE':{'query':None}, >>>>> }} >>>>> >>>>> Let you specify which tables are exposed, which methods are available >>>>> and which fields are exposed for each method. The query property lets you >>>>> specify optional filters for example { >>>>> 'query':db.thing.name.startswith('A'),....} >>>>> will only exposed things starting with letter A. Fields can be conditional >>>>> and different for different users or for the same user in different stages >>>>> of a workflow (the communication is stateless, but the server is not). >>>>> >>>>> Supports complex queries >>>>> ===================== >>>>> http:/...../{table} >>>>> http:/...../{table}/{id} >>>>> http:/...../{table}?{field}=value >>>>> http:/...../{table}?{field}.gt=value # field>value >>>>> http:/...../{table}?{field}.le=value # field<=value >>>>> ... >>>>> http:/...../{table}?_orderby={field} >>>>> http:/...../{table}?_limitby=value >>>>> http:/...../{table}?_offset=value >>>>> ... >>>>> and combinations there of. They are mapped directly into DAL queries. >>>>> More examples are in the API response itself. >>>>> >>>>> The bigger picture >>>>> =============== >>>>> >>>>> This API provide enough information to generate forms and tables and >>>>> grid completely client side. Recently we stumbled against the problem of >>>>> moving from Bootstrap 2 to Bootstrap 3 because so much of the form and >>>>> grid >>>>> logic is server side. My plan is to move most of the logic in the JS >>>>> library and allow users to customize them for different CSS frameworks. >>>>> >>>>> Eventually (in dreams) I would like to have a very slim framework >>>>> based on bottle+dal+validators+auth+collection and have client side >>>>> only templates (based on jquery, sugar, and ractive.js) that can generate >>>>> forms and grids based the collection API. This framework could ship with >>>>> web2py and allow you to program using same web interface that we all love. >>>>> There are many design decisions to make to get there. Your suggestions are >>>>> welcome. >>>>> >>>>> How can you help? >>>>> =============== >>>>> 1) test it. >>>>> 2) there are many existing client side tools for Collection+JSON. Try >>>>> them with web2py. >>>>> 3) blog about it and suggest improvements. >>>>> >>>>> >>>>> I said, it is experimental >>>>> =================== >>>>> >>>>> Collection+JSON has limits: >>>>> - it is very verbose JSON. This is my my implementation has >>>>> compact=True option that breaks the protocol but makes much smaller JSON >>>>> messages. >>>>> - it does not convey field type information and constraints. This is >>>>> why I extended to do so but more work is needed because DAL types do not >>>>> map into HTML5 input types (this of list:string or list:reference). >>>>> >>>>> More extensions of the protocol are required. Extensions are allowed. >>>>> Yet they may change the API in the near future. >>>>> >>>>> Massimo >>>>> >>>> -- >> Resources: >> - http://web2py.com >> - http://web2py.com/book (Documentation) >> - http://github.com/web2py/web2py (Source code) >> - https://code.google.com/p/web2py/issues/list (Report Issues) >> --- >> You received this message because you are subscribed to a topic in the >> Google Groups "web2py-users" group. >> To unsubscribe from this topic, visit >> https://groups.google.com/d/topic/web2py/WN9yzLIfi6M/unsubscribe. >> To unsubscribe from this group and all its topics, send an email to >> web2py+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > -- Resources: - http://web2py.com - http://web2py.com/book (Documentation) - http://github.com/web2py/web2py (Source code) - https://code.google.com/p/web2py/issues/list (Report Issues) --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.