WHY Rest

Jeremy McAnally said the following on 04/01/08 03:33 PM:

No but you get a bunch of them generated for free.

Why _not_ use them?

I could say 'defensive programming'. The named routes aren't explicit, as I understand it. A malicious user could experiment with dynamically generating routes. A fat fingered typist (I'm one, so I know!) could use typos as routes that are incompatible with other parts of the code.

I favour pushing back the checks. Routing seems a good place to say what is and isn't permitted.

I'm sorry if I seem confrontational; I'm just frustrated on a number of counts.

No worries. I wasn't sure you could tell, and I want to help you figure this out. I figured other people may have been having the same reaction I was.

Surely I can't be the only person so afflicted?

I hope not...you're all the market for my eBook that I haven't written! :slight_smile:

Please, give us more detail regarding your experience! :slight_smile:

Your answer was very sensible and I would like to hear more from you. I can see some of the benefits, but nothing REALLY interesting so far...

Cheers, Sazima

You are not alone. I have not been particularly impressed with REST as a design paradigm for anything other than web services. While there are certainly advantages to being able to create web services simply and easily, I do not believe that good URL design for web services is the same as good URL design for user-facing sites. Conflating RESTful web services with good user interface doesn't make sense to me.

I might feel differently about it if the class of webapps I develop leaned more toward Twitter or the like, but I typically create custom web applications for nontechnical clients. There are requirements involving how the site is laid out and how it feels to be a user, and no concern about web services.

I'd like to hear some compelling arguments about why RESTful Rails development matters even if web services are completely off the table, but so far all I've heard is about how thinking of things as resources makes for a nice design, which I'm not buying (see above).

--Greg

All of this has nothing to do with REST. Basically what REST does (and I’m going to simplify things a bit), is express your public model and relationship structure in the url. In essence, REST doesn’t even dictate how URLs have to be formed, it’s a Rails convention to do it the way it’s done.

I like my urls to reflect (part of my) model structure in a logical way. It guides you in where to put your methods, e.g. if it has to do with manipulating and article, i should put it in the articles controller. Having the basic crud operations use a convention is a nice bonus. Some people like to structure their controllers logically into their views structure (e.g. project_summary, project_details, … controllers for each tab in the projects section)

Your comment about a malicious user is something I really can’t get my head around. In a dynamic web application, you always have a certain logic in your urls. If your security issues have to do with one user entering someone else’s account, there’s something very wrong in your controller code, you should check if a user has access to something instead of using cryptic urls hoping they won’t be reverse-engineered. If you want to avoid scraping of your data, it’s up to you to put appropriate measures in your controller to avoid this (or better yet, use something like fail2ban to scan your http logs for this kind of activity). I expect my REST urls to be logical, that’s the whole point.

Programming using Rails (or any framework, but especially Rails with its convention over configuration) is all about using the convention that is laid out for you. Following the convention will save you time, require less coding and make your code nicer to work with (both for you and other people who also know the framework). Using the restful conventions also opens a few doors to things like an API with minimal extra coding, and never say never (more and more web applications benefit from either using or providing an api, so even if you don’t plan it now, it’s bound to come up one day). Converting an existing application on the other hand has to be seen in perspective. I will gradually introduce restful aspects in our existing apps if i work on them, but converting a five month project to rest just for the sake of it isn’t necessary.

Best regards

Peter De Berdt

Use it or don’t. Nobody’s forcing you to. In fact, I dislike a lot of the Rails REST stuff, having done Rails for 3 years now. It’s easy to get stuck in your ways. Fact of the matter is that you have to make money and progress. If what you have works, great. Investigate RESTful architecture for a future app.

Here’s how REST makes sense though, and this is NOT made clear by Rails:

Resources are NOT models.

I built a simple system to control the lights in my house. I did it with REST. I ended up with two resources:

a Unit, which is the resource to manage the creation, deleetion and modification of the X10 devices in my house.

When the time came to actually turn on a light switch or turn it off, my first instinct was to add the following code to the Unit controller:

def on

@unit = Unit.find_by_id(params[:id]).on!

end

def off

@unit = Unit.find_by_id(params[:id]).off!

end

But after thinking about it, what I’m doing is changing the STATE of the unit. Therefore, it made more sense to have a State resource.

Changing the state is an Update, and Updates, according to REST should be PUT requests, not GET requests, as I was doing.

So I made a nested resource

map.resources :unit do |u|

u.resource :state # singular resource here cos I don’t need to list them.

end

My state controller now had a method like this:

params[:value] can be “on” or “off” or “dim” or “brighten”

params[:amount] can be 0 to 100 and is used with “dim” or “brighten”

def update

@unit = Unit.find_by_id(params[:unit_id])

@unit.change_state(params[:value], params[:amount]) # amount is for dimming.

end

Notice how the state resource changed how I implemented the code to manipulate the light? Interesting stuff.

This also made me realize that the show action (get) could tell me the current state of the light.

Already I have less complicated controllers, though I have more.

That’s just my .02. :slight_smile: I did a fun project to learn more about how REST can help me design things. I can share some code if anyone cares.

Gregory Seidman said the following on 04/01/08 04:11 PM:

Surely I can't be the only person so afflicted?

You are not alone. I have not been particularly impressed with REST as a design paradigm for anything other than web services. While there are certainly advantages to being able to create web services simply and easily, I do not believe that good URL design for web services is the same as good URL design for user-facing sites. Conflating RESTful web services with good user interface doesn't make sense to me.

Good point. As in "I wish I had said that". Things like games and wikis ARE the user interface, in many ways.

I might feel differently about it if the class of webapps I develop leaned more toward Twitter or the like, but I typically create custom web applications for nontechnical clients. There are requirements involving how the site is laid out and how it feels to be a user, and no concern about web services.

Yes, that applies to Wikis, and to the games I've seen and used.

Here's how REST makes sense though, and this is NOT made clear by Rails:

Resources are NOT models.

I built a simple system to control the lights in my house. I did it with REST. I ended up with two resources:

a Unit, which is the resource to manage the creation, deleetion and modification of the X10 devices in my house.

When the time came to actually turn on a light switch or turn it off, my first instinct was to add the following code to the Unit controller:

  def on     @unit = Unit.find_by_id(params[:id]).on!   end

  def off     @unit = Unit.find_by_id(params[:id]).off!   end

But after thinking about it, what I'm doing is changing the STATE of the unit. Therefore, it made more sense to have a State resource.

...

Notice how the state resource changed how I implemented the code to manipulate the light? Interesting stuff.

This also made me realize that the show action (get) could tell me the current state of the light.

Already I have less complicated controllers, though I have more.

That's just my .02. :slight_smile: I did a fun project to learn more about how REST can help me design things. I can share some code if anyone cares.

YEP! It's not so much the url structure as the view of controllers as resource controllers that's important.

I got the same kind of epiphany from building one or two NEW applications in rails 2.0 using rails view of restful design. It's one of those paradigm shifts that you have a hard time getting until you do.

And I think that the epiphany is more likely to come from trying a new fairly simple app using REST than by struggling through converting an existing one. After the epiphany you're much more likely to understand what such a conversion really entails and how to do it successfully.

Since a lot of us seem to make a living out of this:

following as much of the convention as possible => less code => less time => more productivity => more income.

One of our apps already uses a RESTful controller structure. It has been a joy developping it, and when we got a new developer in on the project, he immediately knew his way around. All of our apps are custom apps for nontechnical clients, using REST hasn’t been a problem at all (even if a lot of different “resources” were on one single page). It does happen that the index method isn’t defined for the moment (or just provides a quick @all_records.to_xml method), but creating records, updating them, … are things you have to do anyway.

The hardest thing about it all is getting yourself to think outside of your comfort zone and try to get into a new way of thinking. We’ve done it, and for the most part, the whole REST thing just works, and better than I ever expected.

Saying you’ll never need an api, is very dangerous. One of our clients bought himself a very specialized application that would benefit from pulling some of the data from our application. Their supplier contacted us, we said we could provide an api very quickly (he couldn’t, they would have to look into soap, make an analysis, …) and explained the REST XML interface, added it to the application in just half an hour (only the parts that needed to be exposed, but still) and pleased our customer by not charging anything and tell him it would be part of the support contract. It was so easy to do and since we were the ones who could provide the api in the shortest possible time with minimal effort, we could easily dictate it.

Best regards

Peter De Berdt

Jeremy McAnally said the following on 04/01/08 12:01 PM:

You don't have to. You can have a search method on WikiController. Nothing is stopping you.

Nothing is stopping me making system calls to custom C-code either, but that's not the point.

I'm trying to ask HOW I can re-structure things to take advantage of REST. I'm repeatedly told its 'good for you' but short on the HOW.

Lots of the hints don't make sense. A search method in the WikiController could just as easily be a web service.

You go on to say

You're completely missing the point of REST.

Yes, and its not the benefits I'm asking about, its the HOW. Not the technical HTTP level how, but the code organization how.

And yes, I've read a lot about it and its stirred my interest, but its still not telling me anything I can see how to USE. And by 'use' I mean how to structure my code design to make sense and make use of it.

Because replacing what is now a method with a controller doesn't make sense - not to me, and not unless there is some advantage that you guys see that I don't and hasn't been stated. And thinning down the WikiController isn't the advantage 'cos all the code is in 'lib/search.rb'.

Let me give an example of what I mean by the HOW. A blog, sorry can't find it in my bookmarks quickly, suggested a skinny controller full of 'def action end' and the code in the models views and helpers. Well I managed to make one with all the code in the helpers. Lots of DRY; the helper was really a 'library' for the 'calls' in the views.

The examples of RESTfulness I've seen, with the exception of 'restful authentication' (and questions about that have gone unanswered) all seem to focus on CRUD and the kind of routing I very much DO NOT want to use. They really do not communicate any advantage. But so what; I've seen code fragments that show Perl and PHP outperform Ruby - perhaps they do, in fragments, but at the level of whole applications where the code is in Ruby-idioms rather than merely translating Perl, then Ruby performs at least as well as Perl.

I had to learn the Ruby idioms, and now I prefer Ruby to Perl. So I can accept it when Jeremy says he can write RESTful apps fluently.

What I don't see is the HOW for anything but the basic CRUD.

Suppose I do that 'SearchController with one method' change, and work though the changes to the routes (!?!). What do I do next? I can't keep coming back here and asking 'what do I do next'. I need to understand the HOW to convert (or redesign). That's what I'm seeking to find out. And its why I'm frustrated by people simply telling me that RESTfulness is a good thing.

As I just tried to point out in a recent reply to this post, it's probably better to learn how to first design using restful principles for a simple new app before trying to re-design an existing app.

One small starting point might be to really understand the differences between code generated by the the acts_as_authenticated and restful_authentication plugins. Although that's probably too small an 'app' to demonstrate the benefits of going from a few complex controllers to more but much simpler ones.

Clearly this is a book asking to be written. That it hasn't yet appeared tells me that not many people (or at least not the right ones) have a strong enough and solid grasp of it to write that book, even if they personally know that it's a useful idea.

In the software development race I'm a tortoise. I plod along until the next step has been clearly explained by one of the smart hares who have figured it out. So while I feel a tinge of guilt that my app is not RESTful and my controllers fat, it's not yet enough to get my tortoise-behind to make the change.

And I don't worry that my current application will later seem antiquated and in need of a massive rewrite - every program I've ever written could benefit from a rewrite, and I expect that to always be true for me, and usually true for almost everybody else as well.

Anton Aylward wrote:

What I don't see is the HOW for anything but the basic CRUD.

You keep harping on "basic CRUD." As if "basic CRUD" applications cannot be complex.

It might help you to watch this video of DHH explain his new-found love for CRUD:

Also, I thought Brian Hogan did a pretty good job of explaining the elusive "how."

Post: http://www.ruby-forum.com/topic/137572?reply_to=612281#612265

I'll reiterate what I find to be his most important part: Resources are _not_ models.

Imagine a collection of clients. We can create, read, update and delete those resources (forget that you may have an actual client model as well).

But what about searching for clients? That doesn't seem to fit the CRUD model. Except it does.

If we twist our brains, we might come up with a ClientSearches resource. Notice I said resource. That means another controller. No new models though. Just a different way of looking at our model.

With ClientSearches in our brains, it _does_ make sense to CRUD it. When we perform a search we are _creating_ a new search.

That's REST.

I think someone else in this thread mentioned that a single resource doesn't have to be restricted to one model. If I have an Account resource, I could use the show method to display a Company object, all their Client objects, and maybe even some Contact objects. Remember: resources are not objects.

Also, REST is not limited to CRUD. You can easily define other actions in your controllers provided the actions they carry out are respective to their HTTP method. In Rails 2 (possibly lower versions, not sure) you can specify a new custom route onto a map.resources command.

See this pod cast for more on that:

Hope that helps answer the "how" portion of your question.

- Daniel

Daniel Waite wrote:

It might help you to watch this video of DHH explain his new-found love for CRUD:

Oops, here's the video:

- Daniel

I don't see the problem with searching at all and therefore may be blind for what this solution offers, but I can't imagine why I would model(!) searching as creating a resource.

What's wrong with

  GET /clients?firstname=John&lastname=Doe

and handling it in ClientsController#index?

Michael

Michael Schuerig wrote:

If we twist our brains, we might come up with a ClientSearches resource. Notice I said resource. That means another controller. No new models though. Just a different way of looking at our model.

I don't see the problem with searching at all and therefore may be blind for what this solution offers, but I can't imagine why I would model(!) searching as creating a resource.

What's wrong with

  GET /clients?firstname=John&lastname=Doe

and handling it in ClientsController#index?

Interesting. I never said there was a problem. And there's certainly nothing "wrong" with your approach.

Some things are better learned through experience. For me, REST was certainly one of them. Perhaps the same is true for you.

At this point I'd strongly suggest that if you _really_ want to understand the how and why, you do it for yourself.

Obviously I hope you try the RESTful lifestyle and love it, but if you don't, no hard feelings. =)

- Daniel

Hey Ryan, thanks for the interesting REST tutorial. You should really get a blog / post that on a blog rather than on this forum. The formatting on this forum is atrocious and I would really like to be able to refer back to this later.

Daniel Waite said the following on 04/01/08 08:03 PM:

I'll look up the video when I get my codecs working, but ...

I'll reiterate what I find to be his most important part: Resources are _not_ models.

OK, not a problem. See below.

Imagine a collection of clients. We can create, read, update and delete those resources (forget that you may have an actual client model as well).

But what about searching for clients? That doesn't seem to fit the CRUD model. Except it does.

For some values of 'fit'. See below.

If we twist our brains, we might come up with a ClientSearches resource. Notice I said resource. That means another controller. No new models though. Just a different way of looking at our model.

With ClientSearches in our brains, it _does_ make sense to CRUD it. When we perform a search we are _creating_ a new search.

No. You're confusing an artefact of the language with the abstraction. In Ruby you have to deal with classes and hence you have to do a 'new'.

If you look at the code base for TWiki you'll see they've made everything an object. To do a save you hand the string to an object that is the instance of the StorageManager rather than writing to a file. There are lots of such objects. The startup code is full of

  $this->{part} = new TWiki::Part( $this )

as the various parts (implemented as objects) are instanced and references to them kept in one big 'context' object, and all further operations indirect though that. It makes the code ugly. Well uglier than Perl code needs to be. But that's Perl and objects for you.

I point this out because a language in which each 'thing' is an object can't be used (aka its methods) until you create an instance of that object. Ruby is such a language. It doesn't matter if the Search class is a controller or a library, you still end up doing

     s = Search.new( ... )

You've made a 'virtue out of a necessity'. Of course we're creating a new search. But that has nothing to do with a resource being a design decision.

I've seen the likes of 'search' implemented many ways. With Ruby's light-weight objects it makes sense to load stuff at create time. In TWiki's Perl, there's just the one search engine for each context (aka thread) so its completely parametrized when its invoked:

$this->{search} = new TWiki::Search( $this ) # 'new' per session ..... $text = $this->{session}->search->searchWeb( .. huge argument list ...)

Now THAT is a design decision. That it is ugly and ungainly is an artefact of the language!

So whether the design decision loads up at the time the search object is instanced or when its method is invoked IS a design decision. You can see a permutation on this with the use of the BruteMatch method used for searching in the Socks-Wiki, another Ruby Project from before Rails. The loading of the patterns and the search space are very spread out and obscure, since, one again, the single engine is instanced into a context object.

But unless you call the instantiation of the search object a 'create/INSERT//Post', and its going poof! when it goes out of context and becomes a candidate for the garbage collector as a 'delete/DELETE/Destroy' there's not going to be a lot of methods. As far as I can see a 'new()' and a 'do_the_search()'. No CRUD in it. Or did I blink and miss something?

That's REST.

See below.

I think someone else in this thread mentioned that a single resource doesn't have to be restricted to one model.

Indeed. No argument, but that's a design an decision that is independent of REST. My WikiController handles both the Web and the Topic models in one gulp. If you look at Instiki, it does the same, and updates other models that keep track of links and cross references.

While I'm mentioning it, would you call Instiki 'RESTful'?

If not, why not, and if so, why so.

If I have an Account resource, I could use the show method to display a Company object, all their Client objects, and maybe even some Contact objects.

If I'm looking at a page in an address book the Person might have any number of addresses and phone numbers. (Don't you hate the things like ACT where there's only a fixed number of slots for phone numbers because they are part of the Person record and not a separate 'has many' object.)

Remember: resources are not objects.

Or at least they need not be. See 'restful authentication'.

Also, REST is not limited to CRUD. You can easily define other actions in your controllers provided the actions they carry out are respective to their HTTP method. In Rails 2 (possibly lower versions, not sure) you can specify a new custom route onto a map.resources command.

Hope that helps answer the "how" portion of your question.

No, if anything it leaves me more confused than before, for the simple reason I'm doing most of that without anything looking what I've seen described as RESTful.

My wiki has a controller that has no model behind it and my models don't have corresponding controllers. The Wiki is the resource the user sees. The webs and the topics in them aren't resources, they are content.

In fact I get puzzled why forums and blogs do nested routing.

If you look at the URL http://reclusive-geek.blogspot.com/2006/11/peepcodes-restful-rails.html there isn't a month controller in the year controller. The URL is user-friendly, its not

     /year/2007/month/11/post/peepcodes....

And since there's a lot of 'old code' that works this way its not a feature of RESTfulness.

In fact the only controller in my wiki that that has a model behind it or model with corresponding controller is the 'User' and that's 'restful authentication' and that has

  new create activate   suspend unsuspend destroy   purge change_password forgot_password   reset_password find_user

And a deal of that was pasted in from 'acts_as_authenticated' and 'state machine' as you can see. And I kept the named routes as well. So I'm not bothered by 'beyond the CRUD'. Is this a 'fit the CRUD model'? I wouldn't call it that. Not without squinting. I could remove the 'destroy' and 'purge' since there's no button on any of the views that leads to them and its not part of the functionality. A user gets suspended but the record is still there so that authorship can be attributed. That's part of being a Wiki. I could delete those methods; perhaps T should :-). And the login process don't offer a 'find' to the user interface. You have to know the name or the activation code. So its C-U-.

I have a (single) custom route for the wiki that doesn't involve any 'nesting' as there is only one relevant controller - the WikiController. See above and previous postings. The 'restful controller', however, uses lots of custom routes.

Sorry if this seems argumentative, but I'm trying to explain why I'm saying "no it doesn't help explain the HOW'. Either I'm doing RESTful design (and always have) without RESTful routing and without knowing it, or there's something I'm not getting here.

But you appear to suggest that my approach is somehow not RESTful. I'd take exception to that and claim that, yes, what I suggest is completely in line with REST. And it is my understanding that the authors of "RESTful Web Services" (Leonard Richardson & Sam Ruby) agree. I highly recommend that book.

Michael

No, its not. Unless you are _just_ dong a CRUD.

Anything with more complex actions (a wiki: search, attach, roll-back, access control ...; a game: many functions!) you ARE going to have to specify the actions and quite possibly the controller.

It seems that the REST philosophy is all about breaking things down to where you can handle everything with CRUD.

For example, instead of an action 'search' you might create a resource of SearchResult, which you would only need to Read (GET). Even though it wouldn't make sense to perform the other CRUD operations on a SearchResult, you have still transformed it to focus on an object or resource. For attaching an article, rather than having an 'attach' method for Articles, you would have an ArticleAttachments, on which you could do all of your CRUD.

The presentation found at RailsEnvy "The Future of Web Services" (http://www.railsenvy.com/2007/12/17/the-future-of-web- services) gives some good examples of 'how' to make this switch. This is found in the last 3rd of the presentation. It also addresses benefits of a RESTful approach as it relates to web services.

I'm still not converted to the RESTful approach for plain web applications but maybe it's because I haven't followed the "do it and you'll see" advice yet. It seems to me that the a user doesn't or shouldn't care about the Model behind your web application, so it seems following a CRUD approach for everything will lead to bad user interface design. I think this relates to Jamis Buck's blog post "Scaffolding's Place" (http://weblog.jamisbuck.org/2007/1/26/ scaffolding-s-place).

I suppose I could still start the design from the user interface and build the application in a RESTful manner. Maybe it's just a matter of organizing which interfaces belong to which controller. This seems like it would require a lot of going out of my way to make my application RESTful, but like I said, I haven't really tried out the RESTful application design approach yet, so I may be wrong.

What do you think?