Blueprint for the RESTful API
NB This work is basically done: BluePrintRESTImplementation and REST Controller
We need to add support for more representations:
- JSON uploads via POST
- retrieve raw POST data using:
request.body.read()
- send POST data using http://docs.jquery.com/Ajax/jQuery.post#urldatacallbacktype
- jquery.ajax supports username/password: http://docs.jquery.com/Ajax/jQuery.ajax#options
- Cross-domains using JSONP: http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/
- retrieve raw POST data using:
- GeoRSS, KML, GPX, GML, WKT (BluePrintGISImportExport)
- GeoJSON: http://trac.gispython.org/lab/wiki/GeoJSON
- RTF (native to Web2Py)
- ODF:
Also can add extra methods to the controller, such as:
- Enable/Disable & Visible/Invisible could be extra methods for GIS Layers?
Should we add a custom=
option to enable customform sub-processing? (or a separate CustomController*)
- most stuff is the same & the old GIS Layer sub-processing looks right split
- however, for GIS, this is deprecated with the reworking inspired by the LAYER class
- Discussed in BluePrintFramework
This is the S3 way of doing CRUD
Basic approach for the S3 architecture is to have a Web Services backend & a Javascript client front end.
RESTful APIs make this easier.
Web2Py generates URLs in this format:
/application/controller/function/arg1/arg2?var1=x,var2=y
These are generally used in a slightly RESTful way anyway (resources are URLs), e.g.:
/sahana/gis/add_feature /sahana/gis/list_features /sahana/gis/features # List_add /sahana/gis/display_feature/1 /sahana/gis/update_feature/1
We have changed to URLs like these (see BluePrintRESTImplementation):
/sahana/gis/feature # Acts as 'list' (or list_add if t2.logged_in) /sahana/gis/feature/id # Acts as 'display' /sahana/gis/feature/create /sahana/gis/feature/display/id /sahana/gis/feature/update/id /sahana/gis/feature/delete/id
we could potentially do these:
/sahana/gis/feature/id?method=display /sahana/gis/feature/id?method=update /sahana/gis/feature/id?method=delete
but T2 requires ID to be the last argument, so can't do URLs like: /id/create (unless possibly by using routes.py)
These are the benefits:
- Consistency & ease of implementation of all basic functionality for new tables.
- Simplified ability to create .represent widgets:
def shn_list_item(table, resource, action, display='table.name', extra=None): if extra: items = DIV(TR(TD(A(eval(display), _href=t2.action(resource, [action, table.id]))), TD(eval(extra)))) else: items = DIV(A(eval(display), _href=t2.action(resource, [action, table.id]))) return DIV(*items)
This is extended to export raw data in other formats, using the optional vars:
/sahana/gis/feature/display/id?format=[json|xml|csv]
which was considered better than using another arg:
/sahana/gis/feature/display/[json|xml|csv]/id
HTTP DELETE support has now been implemented in the REST controller.
Web2Py now supports HTTP PUT, so we plan to implement that too into the controller in order to make it turly REST-compliant.
This means a little work in clients but isn't too bad if we maintain consistency: no variations between add/create, view/display, edit/update, etc
Discussion of changes to Web2Py to make it more RESTful:
- http://groups.google.com/group/web2py/browse_thread/thread/8506105246e319f6/
- http://groups.google.com/group/web2py/browse_thread/thread/d9f7919c16d62514/
- http://www.wellbehavedsystems.co.uk/web2py/examples/rest.html
- http://www.wellbehavedsystems.co.uk/web2py/examples/rest_alt1.html
- http://groups.google.com/group/web2py/browse_thread/thread/b46ff6f35e82f047
- http://groups.google.com/group/web2py/browse_thread/thread/613d4ac6f87ad413
- PUT implemented: http://groups.google.com/group/web2py/browse_thread/thread/4b1af88db82df261
Web Services
Allows multiple client UIs
- http://talks.php.net/show/webservices/
- http://webservices.xml.com/pub/a/ws/2004/03/24/phpws.html
- http://wiki.sahanafoundation.org/doku.php?id=dev:web_services
REST instead of SOAP
Less bloat, more GIS-friendly.
- http://en.wikipedia.org/wiki/Representational_State_Transfer
- Second Generation Web Services: http://www.onlamp.com/pub/a/php/2003/10/30/amazon_rest.html
- Implementing REST Web Services: Best Practices and Guidelines: http://www.xml.com/pub/a/2004/08/11/rest.html
- Common REST Mistakes: http://www.prescod.net/rest/mistakes/
- How to Create a REST Protocol: http://www.xml.com/pub/a/2004/12/01/restful-web.html
Python REST Servers
- http://mail.python.org/pipermail/python-list/2003-September/223257.html
- http://www.rexx.com/~dkuhlman/rest_howto.html
- FeatureServer: http://featureserver.org/
- WebProcessingServer: http://code.google.com/p/webprocessingserver/
- Tarawa framework: http://www.mnot.net/tarawa/tutorial.html
- Rest in Python framework: http://lukearno.com/projects/rip/
Python REST Clients
- Python client using urllib2: http://mail.python.org/pipermail/baypiggies/2008-January/002853.html
- REST client lib: http://code.google.com/p/py-restlib/
- GAE: http://code.google.com/p/python-rest-client/
- wxWidgets desktop app: http://restclient.org/
- REST framework for Zope: http://pypi.python.org/pypi/z3c.rest
- Django: http://code.google.com/p/django-rest-interface/
Javascript REST clients
- Ext JSONStore
- http://giantrobots.thoughtbot.com/2007/6/11/jester-1-3-jsonic-rest
- http://www.8wireunlimited.com/norockets/2008/10/jquery-vs-xslt-as-rest-client-for-xml-resource-in-the-browser/
- http://www.nabble.com/-OT--Client-side-web-application-with-jQuery-td21043713s27240.html
- Offline: http://www.dotnetkicks.com/opensource/SonicCast_7_SubSonic_REST_and_Jquery_AJAX