views:

175

answers:

4

Hi all,

I'm working on a site that has quite a few pages that fall outside my limited understanding of RESTful design, which is essentially:

Create, Read, Update, Delete, Show, List

Here's the question: what is a good system for labeling actions/routes when a page doesn't neatly fall into CRUD/show/list? Some of my pages have info about multiple tables at once. I am building a site that gives some customers a 'home base' after they log on. It does NOT give them any information about themselves so it shouldn't be, for example, /customers/show/1. It does have information about companies, but there are other pages on the site that do that differently. What do you do when you have these situations? This 'home-base' is shown to customers and it mainly has info about companies (but not uniquely so).

Second case: I have a table called 'Matchings' in between customers and companies. These matchings are accessed in completely different ways on different parts of the site (different layouts, different CSS sheets, different types of users accessing them, etc. They can't ALL be matchings/show. What's the best way to label the others?

Thanks very much. =)

+6  A: 

I'm certainly no expert, but if you rethink your resources and think of them more strictly as 'nouns' or at least lists of data, it might be easier to fit any desired action into GET, POST, PUT, and DELETE. For example, you have a /customers/ resource could presumable have a /customers/{username}/ resource for each customer. Maybe that gives them information about themselves. You could have /homebases/{username}/ or /customers/{username}/homebase/ as your homebase resources. Presumably, you'd access that homebase resource mainly through GET, and POST if there's anything there to update (which I wouldn't expect on a home-base or dashboard since it's an aggregate resource).

For 'matchings' you could use something like /matchings/{customer},{company}/ (yes, commas and semicolons are allowed. Commas usually mean the two parts are order-dependent and semicolon means order-independent, though there's no rules about it). From that resource, you can have GET to read, show, and list whatever data you need (including optional query parameters passed as the body of the GET request), POST to update, PUT to create, and DELETE to delete. Using the parameters passed in GET, you could also request different views of the same data. Of course, you can have sub-resources of that matching like /matchings/{customer},{company}/invoices/{invoice#}/.

I liked the book "RESTful Web Services" (2007 O'Reilly), by the way.

I hope that makes some sense and is helpful. =)

Benny Jobigan
+3  A: 

Aggregate and composite views are a serious problem, I think. I had to deal with the homepage problem that went against everything RESTful I knew.

My solution was to consider the homepage or dashboard as a resource in itself, but a resource where only GET operations made sense. POST/PUT/DELETE from the homepage were directed to the specific resources as usual.

Matchings, in contrast, seems an easier problem to tame. It seems like a simple mapping between Customers and Companies from your description, and you could parametrize it based on querystring parameters.

/matchings?companies=X,Y,Z&locations=NY,CA,TX
Anurag
I agree that it seems odd to allow anything but GET on the dashboard resource, and it would be fine to have parts of the dashboard update other resources, as you said.
Benny Jobigan
Considering dashboard as a resource is a perfectly valid approach and there is no problem a Resource only supporting a subset of methods. The only caveat is with a homepage resource. It's not usually a good idea to create a single URL that returns different content for different people. It's better to create a `/users/bob/homegage` resource instead.
Darrel Miller
If the dashboard view requires authenticated access, then you can use the same URL for all users - think mails, facebook, twitter, etc.
Anurag
@Anurag You could, but then you need to make sure that you set the vary header appropriately so that caches know that they cannot return cached results for different users. You also lose the benefit of being able to share urls with others. In general I see a bunch of disadvantages and no advantages to using the same url.
Darrel Miller
That's the whole point of private data that you can only access when authenticated. You wouldn't want your mails, etc. being cached on intermediary servers anyways, and there's no point in sharing your mail inbox/private data url with others either.
Anurag
+2  A: 

By RESTful design, I assume you mean RESTful web services, since a REST-based architecture has a much broader sense than that.

The main thing to consider is that REST-based architectures rely on the HTTP protocol, in virtually all cases. Since HTTP specifies a set of methods, sometimes these methods are used to create the so called RESTful web services.

But the RESTful web services don't follow any concrete standard (unlike SOAP). It is common to use:

  • GET - for fetching existent items
  • POST - for creating new items
  • PUT - for updating existent items
  • DELETE - for removing existent items

Create, Read, Update and Delete (CRUD) are the basic functions of any persistent storage.

It is easy to see that in common RESTful web services, each HTTP method is being used to match one of the basic functions, but the point is: it doesn't have to be this way.

There are other things to consider, URL mapping is one of them (as this is the concern of your question), security is another. POST requests send the content of the request in the HTTP body (which can be encrypted), but GET requests send it in the URL, visible for everyone to see.

If one wants to develop a secure (encrypted) RESTful web service, one could make all requests HTTPS POST, and then specify within the request, which of the CRUD operations one wants to perform, and on what resources.

One could also expand the CRUD concept to a wider range, in fact, in almost every application, one has to.

Remember CRUD are just the four basic operations in which all other actions can build upon. There's no standard you have to follow, you can specify your own protocol, according to what makes sense in your context, and keeping all the relevant considerations in mind (security, URLs, etc.)

Specifically regarding your question, you can have your own actions, like show_by_x, show_by_y, etc. The REST police is not coming to arrest you :-)

ivo
`SOAP RPC architecture over HTTP is a RESTful architecture` Huh? Could you provide some backup to that bizarre claim?
Darrel Miller
I meant to illustrate how REST is in a broader sense, anything that makes use of HTTP methods. SOAP uses the POST method. But my choice of example was indeed poor, because REST is commonly mentioned as an alternative to SOAP, so I've removed the reference from my answer. Thanks for pointing that out.
ivo
A: 

hi sscirrus

REST and ORM is 2 different things, because of that even though you have a model called User , you done necessary to have a users resource. Resources should be managed in the rails controller level

Think resources as modules/sections

Ex: you might want your users to land on a dashboard page after they log in (and say you have two categories of users Administrators and normal users), so you can have two resources namly

admin_dashboard uer_dashboard

and both might only have read action

Second case :

consider having something like above example (different resources according to different user levels) if possible

I'm not a REST guru, but hope this helps :D

cheers, sameera

sameera207