Topic: Multi-user and REST?

Hi all

I have a simple question: Is REST suitable for a multi-user system?

I see the real advantage for the administrator/superuser, who can "CRUD" everyone and everything by using resource links, etc. Moreover, there is no need for an "admin account area" in the same extend as it is for the "regular" user of the system. Following to this, what about the users with restricted rights and such? How to handle the "account" area for those users? How would the application be designed for those users (RESTful or RPC)?

I try to wrap my head around this, but I am not sure which way to go.

Any comments and help is apprechiated!

Re: Multi-user and REST?

Check out Ryanb's Railscasts episodes 19, 20, and 21 they will be very helpful.

http://www.railscasts.com/

Re: Multi-user and REST?

Hi Learc83

Thanks for your reply, but it is not quite what I want to talk about. Ryans casts feature a single user environment only, e.g. Admin or not. I mean a system with a multitude of users with different rights and roles. Different views for the same action depending on the current user's role.

I am not asking for how to implement user authentication, rights/roles, user groups, relationships between data, and so forth. Nor am I asking for how REST works. I have read a lot about it recently - also got the screencast about REST from PeepCode (most recommended by the way for all who want to learn about it).

My agenda is to find out if a CMS with different levels of hierarchy is suited for REST design. Can it be done purely RESTful or mixed in with RPC? It is kind of related to this post.

Is the effort making it RESTful worth the benefit? I see the strong advantage on shopping-cart/e-commerce applications as browsing through the stock is very intuitive. There is a lot out there about REST, but all sample applications are similar to a cart-system.

Can anyone recommend a good book about REST? Questions over questions ;-)

Re: Multi-user and REST?

Opps sorry, that's what happens when you just skim through a post.

REST isn't able to do everything, but you can still try to keep just some parts of your application RESTful. I started building my latest app as a REST app, and most of it is, but I did run into areas where REST wouldn't make sense so I didn't use it there.

Re: Multi-user and REST?

REST is all about splitting up the controllers and actions based on their behavior, not on how they are accessed. Therefore, I think it is a perfect solution for a multi-user environment because you aren't concerned with creating separate controllers and actions for different kinds of users.

This assumes the CRUD behavior for all users is roughly the same. For example, let's say you have an Event model. When creating an event, the end result is that an event is created - it doesn't matter who creates it. You can definitely adjust the behavior slightly depending upon their access. For example, if you only want admins and priviledged users to change the name or date of the event, you can do that with "if" conditions.

Does that make sense?

Railscasts - Free Ruby on Rails Screencasts

Re: Multi-user and REST?

Thanks for both of your replies.

@learc83: Mixing REST with RPC is my biggest concern as I can forecast already that this might get messy (at least for me), because one tries to walk two paths at the same time.

@Ryan: makes sense, thanks ;-)

Following up on your Event scenario, let's say we have 4 user groups:
1. The admin who can do everything
2. A user group who can create events
3. A user group who can view the events with all info in it
4. The general site visitor who can view the event if it is set to public.

All user groups can add events to their account area (except user group 4 as they don't have a login). In order to view the event, everyone would access the same link "/events". I'd have to distinguish between 4 variants on how to query the events table depending on the user:
1. Admin: get all events in the system
2. Creator/Owner: only get events I created
3. Viewer: get events I added to my account
4. General Visitor: get events that are set to public

I hope this still makes sense so far and you can see the difference in displaying/fetching the data. Projecting this to (almost) every controller in the system, would this still be clean code after all or is that not overloading the controller (design-wise)? Additionally to this, there would be the need to make 4 partials for every user group to see their events as they all get the data displayed in a different format.

What do you think?

Re: Multi-user and REST?

rudionrails wrote:

All user groups can add events to their account area (except user group 4 as they don't have a login). In order to view the event, everyone would access the same link "/events". I'd have to distinguish between 4 variants on how to query the events table depending on the user:
1. Admin: get all events in the system
2. Creator/Owner: only get events I created
3. Viewer: get events I added to my account
4. General Visitor: get events that are set to public

In this case there is a significant difference in behavior. When dealing with REST, you split up the actions depending on the behavior. It just so happens that each account needs a different behavior. So, the events controller needs to support this:

1. find all events
2. find all public events
3. find all events created by a given account
4. find all events related to a given account

Forget about restricting access for a moment, these are all different behaviors that the Events controller needs to provide. I recommend creating a separate action for each one. By default, REST only gives you the "index" action, but here you need to add more "collection" actions which can be specified through the routes.

Once you get each behavior in its own action it's very reasy to restrict access using before filters. If there's duplication in the views, you can either have them all render the same view or use partials to remove the duplication.

An alternative is to move the event fetching into the User model and use Single Table Inheritence for the different type of users. This is a good approach in many cases, but here I prefer making them separate actions.

rudionrails wrote:

Additionally to this, there would be the need to make 4 partials for every user group to see their events as they all get the data displayed in a different format.

How different is the format? If you just need to show/hide a few things, I recommend keeping it all in one partial but using "if" conditions. Also, if you go with the approach I mentioned above, it is split into four actions so there's no need to move them into partials or create separate partials. Just use partials where there is duplication.

Railscasts - Free Ruby on Rails Screencasts

Re: Multi-user and REST?

If I understand you right now, Ryan, this means mixing the two approaches (REST with RPC). What about the additional routes? Is it best practise to define 3 for each new action in our scenario (having index for the administrator) or is "/events/:action" enough, thus, exposing the other controller actions to the public?

Thanks for explaining the behavioural approach by the way, that helps a lot in understanding the matter.

Are there any good books about RESTful design that you might be able to recommend?

Re: Multi-user and REST?

rudionrails wrote:

If I understand you right now, Ryan, this means mixing the two approaches (REST with RPC).

I suppose it's not strictly REST, but it is supported fully by Rails' REST. What you're doing is adding what's called an "aspect" to the query. In other words, you're asking for the same information (list of events) just in a different way.

rudionrails wrote:

What about the additional routes? Is it best practise to define 3 for each new action in our scenario (having index for the administrator) or is "/events/:action" enough, thus, exposing the other controller actions to the public?

You would set it up when you define the map.resources:

# in routes.rb
map.resources :events, :collection => { :public => :get, :owned => :get, ... }

This will create two or more aspects to be used on the events. Currently the URLs will look like this:

example.com/events => index action in events controller
example.com/events;public => public action in events controller
example.com/events;owned => owned action in events controller

In future version of Rails the semicolon will be changed to a forward slash, but it still has the same "aspect" meaning.

Railscasts - Free Ruby on Rails Screencasts

Re: Multi-user and REST?

Wow that is some pretty cool stuff! That example is kind of what I am looking for to handle the multiple ways of querying the DB and displaying the content. I'd be automatically getting: public_events_path and owned_events_path in the example, right?

How would one set up an account area now for the different users? It this the place for a regular Account controller or is there a REST controller that incorporates this for us already?

Thanks for the help, Ryan!

Re: Multi-user and REST?

rudionrails wrote:

I'd be automatically getting: public_events_path and owned_events_path in the example, right?

Yep, one of the great benefits of going REST. If you need a smart path which looks at the type of user and chooses the proper events then you could make a helper method to do this.

rudionrails wrote:

How would one set up an account area now for the different users? It this the place for a regular Account controller or is there a REST controller that incorporates this for us already?

It all comes down to your specific requirements. I would start off with a RESTful "accounts" controller to handle the CRUD operations of the Account model (if that's what you have). If the different accounts need wildly different displays/behavior then you may want to split up the controllers to one per account type.

Railscasts - Free Ruby on Rails Screencasts