tags:

views:

115

answers:

2

I'm designing an api and I'd like to allow users and groups to have saved searches, but am uncertain how to best expose this information. I've come up with a few URI's to expose them:

# These are for CRUD the search definitions, not running the searches
1. /users/{username}/searches # lists the searches for a user
2. /users/{username}/searches/{search-name} # CRUD a specific user search
3. /groups/{groupname}/searches # lists the searches for a group
4. /groups/{groupname}/searches/{search-name} # CRUD a specific group search
5. /searches/{search-id|search-name}
6. /searches/group/{groupname}/{search-name}
7. /searches/user/{username}/{search-name}

I don't feel its right to expose all those URIs. That means there are 2 ways to update or list searches for a user and a group: through the /groups/search, or through /search/group. It also means more to support and I'm afraid that subtle differences would develop.

Searches can be independent records in the database and not tied to a specific user or group (e.g, default system searches, or context-dependent searches).

Because searches can be independent, it feels wrong to expose them as /users/searches and /groups/searches. At the same time, if I'm thinking, "What are bob's searches?" I would first think of /users/bob/searches because, logically, its bob's search. Similarly, if I want to, say, backup bob's account, all his personal information should be under /users/bob.

So, does anyone have advice on which way is preferred, and/or worked well (or poor) for them?

A: 

My tendency would be to divide up into the types of queries (e.g. one type of query is a "list searches" query. Then I'd have arguments. E.g. /searchlist?user=john. Unless you're trying to make this stuff get indexed by bots and search engines, that should work fine.

Brian
+1  A: 

I would tend to stick with

5. /searches/{search-id|search-name}
6. /searches/group/{groupname}/{search-name}
7. /searches/user/{username}/{search-name}

The backup problem can be solved by creating a new resource that contains links to Bob's info throughout the system e.g.

GET /AccountData/Bob

<div class="AccountData">
   <link rel="searches" href="/Searches/User/Bob"/>
   <link rel="options" href="/Options/User/Bob"/>
   <link rel="usagehistory" href="/History/User/Bob"/>
</div>

My experience is that you will drive yourself nuts if you try and create a single hierarchy that meets all of your usage scenarios. You just can't do it. That's why Wikis work so well, they use links instead of hierarchy to provide access to the information.

I would suggest you focus more on what links will be returned in the representations.

e.g.

GET /Groups/{GroupName}

<div class="group">
  <div class="name">AGroup</div>
  <link rel="searches" href="/Searches/Group/AGroup"/>
</div>

With this approach, you care much less about what the URL structure looks like. As Roy states here

A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server)

I realize this may seem like an extreme position, considering how everyone on SO seem fixated on what your urls need to look like to have a RESTful API, but the more you think about it, the more sense it makes.

P.S. Please don't get hung up on my choice of HTML as a media type for the representations, I'm just drawing attention to the fact that you don't always need to use a custom XML vocabulary.

Darrel Miller
I like the idea of /AccountData for backing up an account. One qualm I have with REST is that "proper RESTful design" seems to imply a lot of additional requests. /users/bob/searches should return 303 See Other with Location: /searches/users/bob.
Richard Levasseur
You are correct about the additional requests. Here is a quote from Roy on rest-discuss a few weeks ago which seems appropriate. "Yes, a RESTful system is at least one level of indirection away from a strongly coupled system."
Darrel Miller