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 <[email protected]>: > 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 > [email protected]. > 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 [email protected]. For more options, visit https://groups.google.com/d/optout.

