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 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