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