[Cubicweb] Thoughts on RESTfulness and rqlcontroller

Christophe de Vienne christophe at unlish.com
Sat Jan 24 01:14:03 CET 2015


Hi,

I think a RESTful API is complementary of rqlcontroller.

Full RQL access is great for endusers, but manipulating RQL in the code
can be tedious, especially in javascript.

A RESTful API on the other hand is very easy to use, especially with
libraries like Backbone or AngularJS. Such an API is also more
accessible to third-party developers who don't need to learn RQL, which
still getting a lot of its features.

To achieve that I wrote cubicweb-wsme, which gives CRUD access to any
entity of the model, along with a json-based filter syntax that get
translated to RQL on the server side. It is a work in progress (ie
incomplete and without bw compat for a while), although we already use
it in production.

See below how cubicweb-wsme answers some of the questions you mention:


Le 23/01/2015 23:47, Nicolas Chauvat a écrit :
> Hi List,
> 
> For the record, here is the summary of a discussion that took place at Logilab
> about a year ago when we decided to allow write access through HTTP and ended up
> writing rqlcontroller. I had the thread of emails sitting in my work directory
> and thought it would be better to summarize it and archive it in the open on the
> mailing list than to lose it.
> 
> It all begins with the question "we want write to allow write access, maybe we
> should try to merge the ideas / vocabularies of REST and RQL ?".
> 
> First consensus is that creating, modifying and deleting objects using a
> "GET /?rql={SET,INSERT,DELETE}" would definitely not be RESTFul.
> 
> A possible mapping is::
> 
> .. csv-table::
> 
>    RQL, HTTP, action
>    `Any`, `GET /ticket/1234`, return json for ticket
>    `INSERT`, `POST /ticket` + request payload, create ticket and return its URL
>    `SET`, `PUT /ticket/1234` + request payload, modify ticket attributes and relations
>    `DELETE`, `DELETE /ticket/1234`, delete ticket

One missing important mapping is:

     `Any`, `GET /ticket[?filter=xxx]`, return json for a tickets
matching the filter.

> 
> Here is what an INSERT with POST could look like::
> 
>   POST /ticket
>   rql=INSERT Ticket T: T title %(mytitle)s, T priority %(mypriority)s, T
>     concerns P, T type %(mytype)s WHERE P eid %(peid)s
>   mytitle=Mon nouveau ticket
>   mypriority=important
>   mytype=enhancement
>   peid=1357
> 
> or maybe use directly the attributes and relations as parameters::
> 
>   POST /ticket
>   title=Mon nouveau ticket
>   priority=important
>   type=enhancement
>   concerns=1357

I chose this second option, but the data format is json (or xml fwiw).
For example:

POST /ticket
Content-Type: application/json
Accept: application/json
{"title": "Mon nouveau ticket", "priority": "important",
"concerns": {"eid": 1357}}

> 
> The response to both would be::
> 
>   HTTP/1.1 201 Created
>   Location: /ticket/98765
> 
> Follows a list of open questions and thoughts:
> 
> - Is this enough to be useful or is it too limited?

Yes it is enough, as soon as it allow:
- fetching arbitrary attributes and nested relations
- update or create several related entities at once
- filter results with a simple yet powerful enough syntax

> 
> - It is common to need to create several entities in one transaction, or to
>   write queries that use RQL functions?

In cubicweb-wsme we can use RQL functions as soon as we expose them in
the filter syntax. For example, at unlish, we get all events in a given
radius like this:

    GET /api/0.1/Event?filter={'at_place.refpoint':
    {'$dwithin': {'point': [lat, lon], 'distance': 2000}}}

It gets translated to something like that:

    Any E WHERE E is Event, E at_place P, P refpoint POINT
    HAVING ST_DWITHIN(POINT, ST_GEOGFROM(lat, lon), 2000)

> 
> - If the full power of RQL is needed, rqlcontroller is the answer, but then is
>   it useful to have a RESTful interface ? Do we need a RESTful interface when we
>   have rqlcontroller?

I think we do

> - Is it RESTful to allow to GET on a URL with rql= ? What should happen if the
>   rql parameter is INSERT, DELETE or SET something ? Should we add a /rql
>   resource on which to GET an arbitrary request. Isn't this rqlcontroller and
>   its /rqlio?

No, rql should not be a parameter of the RESTful API.
Through the filter system I speak of, we can nonetheless access a good
part of RQL in a transparent way.


> - The idea of HTTP verbs is to help the caching infrastructure do its job and to
>   get a rough idea of permissions (disallow DELETE for example). Doing
>   everything through `POST /rqlio` does not help caching.
> 
> - Is there a parallel between rqlcontroller/REST and Sparql/RDF-Fragments?
> 
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: OpenPGP digital signature
URL: <http://lists.cubicweb.org/pipermail/cubicweb/attachments/20150124/57a3fa70/attachment-0182.sig>


More information about the Cubicweb mailing list