views:

273

answers:

3

I think my question would be better explained with a couple of examples...

GET http://myservice/myresource/?name=xxx&country=xxxx&_page=3&_page_len=10&_order=name asc

that is, on the one hand I have conditions ( name=xxx&country=xxxx ) and on the other hand I have parameters affecting the query ( _page=3&_page_len=10&_order=name asc )

now, I though about using some special prefix ( "_" in thes case ) to avoid collisions between conditions and parameters ( what if my resourse has an "order" property? )

is there some standard way to handle these situations?

--

I found this example (just to pick one) http://www.peej.co.uk/articles/restfully-delicious.html

GET http://del.icio.us/api/peej/bookmarks/?tag=mytag&dt=2009-05-30&start=1&end=2

but in this case condition fields are already defined (there is no start nor end property)

I'm looking for some general solution...

-- edit, a more detailed example to clarify

Each item is completely indepent from one another... let's say that my resources are customers, and that (luckily) I have a couple millions of them in my db.

so the url could be something like

http://myservice/customers/?country=argentina,last_operation=2009-01-01..2010-01-01

It should give me all the customers from argentina that bought anything in the last year

Now I'd like to use this service to build a browse page, or to fill a combo with ajax, for example, so the idea was to add some metada to control what info should I get

to build the browse page I would add

http://...,_page=1,_page_len=10,_order=state,name

and to fill an autosuggest combo with ajax

http://...,_page=1,_page_len=100,_order=state,name,name=what_ever_type_the_user*

to fill the combo with the first 100 customers matching what the user typed...

my question was if there was some standard (written or not) way of encoding this kind of stuff in a restfull url manner...

+1  A: 

There's no standard or convention which defines a way to do this, but using underscores (one or two) to denote meta-info isn't a bad idea. This is what's used to specify member variables by convention in some languages.

altCognito
yeap, metada, that's what I was talking about
opensas
A: 

I know that the RESTful folk tend to dislike the usage of HTTP headers, but has anyone actually looked into using the HTTP ranges to solve pagination. I wrote a ISAPI extension a few years back that included pagination information along with other non-property information in the URI and I never really like the feel of it. I was thinking about doing something like:

GET http://...?name=xxx&country=xxxx&_orderby=name&_order=asc HTTP/1.1
Range: pageditems=20-29
...

This puts the result set parameters (e.g., _orderby and _order) in the URI and the selection as a Range header. I have a feeling that most HTTP implementations would screw this up though especially since support for non-byte ranges is a MAY in RFC2616. I started thinking more seriously about this after doing a bunch of work with RTSP. The Range header in RTSP is a nice example of extending ranges to handle time as well as bytes.

I guess another way of handling this is to make a separate request for each item on the page as an individual resource in its own right. If your representation allows for this, then you might want to consider it. It is more likely that intermediate caching would work very well with this approach. So your resources would be defined as:

myresource/name=xxx;country=xxx/orderby=name;order=asc/20/
myresource/name=xxx;country=xxx/orderby=name;order=asc/21/
myresource/name=xxx;country=xxx/orderby=name;order=asc/22/
myresource/name=xxx;country=xxx/orderby=name;order=asc/23/
myresource/name=xxx;country=xxx/orderby=name;order=asc/24/

I'm not sure if anyone has tried something like this or not. This would make URIs constructible which is always a useful property IMHO. The bonus to this approach is that the individual responses could be cached and the server is free to optimize handling of collecting pages of items and what not in the most efficient way. The basic idea is to have the client specify the query in the URI and the index of them item that it wants to retrieve. No need to push the idea of a "page" into the resource or even to make it visible. The client can iteratively retrieve objects until it's page is full or it receives a 404.

There is a downside of course... the HTTP server and infrastructure has to support pipelining or the cost of creation/destruction of connections might kill the idea outright.

D.Shawley
I think the problem with HTTP headers is that you loose the ability to pass all the info to get the resource as an utl string...and regarding your second proposal, I think that my resource is the list of "myresource", not pages, I just want to filter that list of "myresources"... I saw other examples like myresourcer/page/1/page_len/10/order/name asc but it didn't convince me either for the same reason...
opensas
Actually, I wonder if the RESTful folks wouldn't be ok with this approach. What they have an issue with is changing the URL in such a way that it doesn't describe the resource. If this is a filter of the data, maybe a header makes sense.
altCognito
so... where are those "RESTful folks" anyway??? is there some page with recommended aproaches or something?I think what I'm trying to achieve is pretty standard stuff...
opensas
D.Shawley
A: 


Note: I started writing this as a comment to my previous answer. Then I was going to add it as an edit, but I think that it belongs as a separate answer instead. This is a completely different approach and a separate answer in its own right since it is a different approach.


The more that I have been thinking about this, I think that you really have two different resources that you have to deal with:

  1. A page of resources
  2. Each resource that is collected into the page

I may have missed something (could be... I've been guilty of misinterpretation). Since a page is a resource in its own right, the paging meta-information is really an attribute of the resource so placing it in the URL isn't necessarily the wrong approach. If you consider what can be cached downstream for a page and/or referred to as a resource in the future, the resource is defined by the paging attributes and the query parameters so they should both be in the URL. To continue with my entirely too lengthy response, the page resource would be something like:

http://.../myresource/page-10/3?name=xxx&country=yyy&order=name&orderby=asc

I think that this gets to the core of your original question. If the page itself is a resource, then the URI should describe the page so something like page-10 is my way of saying "a page of 10 items" and the next portion of the page is the page number. The query portion contains the filter.

The other resource names each item that the page contains. How the items are identified should be controlled by what the resources are. I think that a key question is whether the result resources stand on their own or not. How you represent the item resources differs based on this concept.

If the item representations are only appropriate when in the context of the page, then it might be appropriate to include the representation inline. If you do this, then identify them individually and make sure that you can retrieve them using either URI fragment syntax or an additional path element. It seems that the following URLs should result in the fifth item on the third page of ten items:

http://.../myresource/page-10/3?...#5
http://.../myresource/page-10/3/5?...

The largest factor in deciding between these two is how strongly coupled the individual item is with the page. The fragment syntax is considerably more binding than the path element IMHO.

Now, if the item resources are free-standing and the page is simply the result of a query (which I think is likely the case here), then the page resource should be an ordered list of URLs for each item resource. The item resource should be independent of the page resource in this case. You might want to use a URI that is based on the identifying attribute of the item itself. So you might end up with something like:

http://.../myresource/item/42
http://.../myresource/item/307E8599-AD9B-4B32-8612-F8EAF754DFDB

The key deciding factor is whether the items are freestanding resources or not. If they are not, then they are derived from the page URI. If they are freestanding, then they should have their are defined by their own resources and should be included in the page resource as links instead.

D.Shawley
(no problem with lenghty answers, on the contrary, thanks for your time)I don't think you are missinterpretating my question, you are just considerating a different case...As you suspected, each item is completely indepent from one another... let's say that my resources are customers, and that (luckily) I have a couple millions of them in my db.so the url could be something likehttp://myservice/customers/?country=argentina,last_operation=2009-01-01..2010-01-01It should give me all the customers from argentina that bought anything in the last year(oops... no more space for comments)
opensas
I edited the question to clarify this...
opensas