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 web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to