[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Web services revisited



Hi,

On 05/22/2012 05:10 PM, Chris Travers wrote:
On Tue, May 22, 2012 at 12:27 PM, John Locke <..hidden..> wrote:
Hi, Chris,

One forgotten method, on the object controllers, realized on IRC:

... We need an INDEX handler.

GET would presumably get an individual resource, using an internal id
guaranteed to be unique. Index would return a collection of resources,
and would accept a variety of search parameters, presumably sent via GET
parameters.
hmmmm  This would seem to make most sense if we break off subresources
into subclasses.

Not sure about this -- the way I think about subresources is that they are "sugar", convenient ways of crossing relationships.

For example, we might have a "sugar" subresource on customers to access their invoices:

GET /rest/1.0/mycompany/customer/23422/invoices

... would essentially be a "sugar" api for this:

GET /rest/1.0/mycompany/invoices/?customer_id=23422

... at least that's how I think about them. So in most cases, I guess yes these would be different classes -- not subclasses exactly.

In Drupal Services, there is a "relationships" description you can implement to essentially create these -- specify what other handler to call and which path parts to pass as arguments. Maybe make that an optional part of the resource controllers?


Also question:

should it be possible to PUT or POST a collection?  For example, an ar
batch?  If so how do we want to handle that?

For this case, I would expect to be able to POST the collection to a specific URL for the method, which may take an arbitrary payload.

If you can think of a more general way to solve this, great -- in my experience, these would be defined individually per module -- basically an RPC-style service when REST isn't quite up to it...

One thing I am working on for another project is standardizing a way to update hierarchies -- basically being able to PUT an object with children embedded, and possibly update data on the children. I think that would be the RESTful way to do it -- in my experience collections are more like SELECT queries, and INSERT and UPDATE work on individual rows -- you need to provide additional methods to do a bulk update.


It would be nice to be able to handle that because we could define
format handlers for things like CSV or Excel and then have apps that
upload spreadsheets......

That sounds really good, actually. Some sort of bulk insert/bulk update method? Perhaps that can be as simple as passing a "multiple" GET parameter, and POST/PUT the collection to the base URL without an id. I would think this could be handled by the same PUT/POST handlers... just have the method detect if it's multiple and loop through the rows...


      
The Index handler should get called when a request comes in via GET,
with no unique identifier in the URL.

This would also apply to resourcetype sub-handlers...
Yeah.  One problem right now that I have spotted with the current
draft is that it is a fixed-length namespace.  I would like to figure
out how we want to do this.  My thinking is that we should treat
subresources proper as only possible where an id has been identified
above.  But this precludes a general request like:

ledgersmb/rest/1.4/mycompany/customer/aging.xml

One option would be to use the "all" keyword to mean that an id is not
supplied.  So that would become:

ledgersmb/rest/1.4/mycompany/customer/all/aging.xml

If we go that route, I don't see why we can't extend subclass handlers
etc as far as needed.


+1 "all" is a very conventional thing to use here...


e.g. possible GET handler:
GET /rest/1.0/my_company/ar_transactions/43353

Possible Index handler:
GET /rest/1.0/my_company/ar_transactions/?invoice_id=N499216
Now, if only one invoice is found with that number (which it should)
would that return a document representing that single invoice or a
collection of one?  

I would expect a collection of one. I would expect a collection anytime I didn't specify an id or used "all" in place of an id.


If none are found do we issue a 404 or a 200
accompanied by an empty collection document?

I would expect 200 with an empty collection. 404 would be ok, though.

GET
/rest/1.0/my_company/ar_transactions/?status=open,closed&customer=customer1
This would be more obviously a collection of an arbitrary number.
Presumably 0 is a valid number of elements in a collection, I would
think.

Yes.

One other minor point to bring up -- paging results. I recommend having a default page size, and using the "Range" header. I like how Dojo does this with JsonRest Store:

Paging

JsonRest store uses HTTP’s Range header to perform paging. When a request is made for a range of items, JsonRest will include a Range header with an items range unit specifying the range:

Range: items=0-24

On your server, you should look at the Range header in the request to know which items to return. The server should respond with a Content-Range header to indicate how many items are being returned and how many total items exist:

Content-Range: items 0-24/66

That's from here: http://dojotoolkit.org/reference-guide/1.7/dojo/store/JsonRest.html ... also some guidance on sorting on that page.



Cheers,
John Locke
http://www.freelock.com