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.

Reply via email to