Tuesday, August 5, 2008

RESTful Searching

Digging into the wild world of REST where there seems to be a lot of information and conventions, I also find there is a lot lacking. I did notice on another blog, wish I kept the reference, that there are a lot of things REST experts would agree on but really no repository of "better practices".

The rails conventions make it very easy to publish entities and do repository style filtering of all the entities of a known type. This is typically done by a GET to a resource URI and most likely with query parameters. This URI GET is usually mapped to a controller's index method. I have some interesting question regarding caching that I think are satisfied using the VARY Http header. Consider that the authorization cookie is actually part of the filter criteria. Meaning results could vary depending on who is doing the searching. Alas, I digress.

My biggest problem so far is what happens if there are user modifiable properties of each search result. Say, there is a check box on each row for a multiple choice scenario. We can't use a GET to modify a resource as its against the idempotency law. Well, we could put this property on the backing entity. Then we have to figure out what to do if multiple people are searching and toggling this selection. Clicking this box would then POST to the backing entity URI. Thing is, how would the controller for the resource POST know to redirect back to the exact search URI? I'm sure people really don't want to tack on a redirect property. I don't particularly like this one.

Perhaps, the result in the set of results is its own entity. Efficiency nerds would cringe at keeping copies of data in multiple forms, especially for multiple users and then perhaps even multiple times for the same user. Ok, so we don't expose each result per se but rather, allow a POST to the search URI where it can maintain state of all the selected results (one way would be to have a form with all the chosen ids in a hidden inputs along with a choose link which submits them. But to where?) I've seen that when others have stumbled into the problem where a search combines heterogeneous entities, they seem to go for a separate search URI as well.

Anyhow, I think I will experiment with this approach and see how it goes.
Expose the resource URI as

  • /ResourceCollection

    1. POST[Create new]
    2. GET[non-filterable list, page-able? OK]

  • /ResourceCollection/ID

    1. GET[get it]
    2. POST[not defined]
    3. PUT[Update]
    4. DELETE[kill it]

  • /ResourceCollection/New

    1. GET[returns a form that represents the entity and will POST to /ResourceCollection]

  • /ResourceCollection/ID/EDIT

    1. GET[return form for editing that PUTs to /ResourceCollection/ID]

  • /ResourceCollection/ID/DELETE

    1. GET[return form for confirming delete, it DELETE to /ResourceCollection/ID]


Then for search have the following scheme

  • /ResourceSearch

    1. POST[create new search results, redirects to /ResourceSearch/ID]

  • /ResourceSearch/New

    1. GET[form to create new search results]

  • /ResourceSearch/ID This resource should/will be security context sensitive. Only the user who created it should be able to work with it.

    1. GET[typically with query parameters for paging and sorting].
    2. POST[updates something about search results, accept post entity of only a search result or perhaps a property of a search result]

This seems like a bit more work but perhaps more flexible. Is it all still RESTful? I think so. Now, what to do with all these sets of search results?!

Then again, maybe there is a better metaphor to solve this problem than sticking a checkbox on a result row. Create a selected resource which is just a maintained list of result rows? Your search results view would then possibly show this list along with the paged results from search? The list of search results would have buttons to add to the selected list?

I'm also coming at this from non-Ajax perspective. In an Ajax world, the client could maintain the list of selected items.

The experiment will be implemented in the ASP.Net MVC framework and using the provided SimplyRestful routing.

Wednesday, January 2, 2008

First Post

Welcome, this is just a test post.