Good morning,
I have an enhancement proposal for the REST handling in Rails.
I was wondering how to implement the RADAR architecture
(http://pragdave.pragprog.com/photos/uncategorized/2007/03/29/radar.png)
in a single Rails app: the idea would be to create two modules of
controllers, the first for the presentation ones (which interacts with
the website and renders views) and the second for the REST ones (for
more about RADAR architecture, see Dave Thomas post
http://pragdave.pragprog.com/pragdave/2007/03/the_radar_archi.html).
Show, Dont Tell:
Lets have a basic social website providing a users profile page: you
have infos about the guy, his events, his tags, his contacts, his
snippets & bookmarks too, etc. Building this website with the RADAR
architecture would mean:
app/controllers/presentation/
* profiles_controller.rb
app/controllers/rest/
* users_controller.rb
* events_controller.rb
* tags_controller.rb
* contacts_controller.rb
* snippets_controller.rb
* bookmarks_controller.rb
The benefit: you have a REST application server which can be accessed to
get xml, rss, etc. and a presentation layer which deals with the
website and queries the REST controllers.
This kind of design is not specific to particuliar applications. For
example, I have just finished writing a Ruby on Rails application for
doctors: it''s accessible online through the presentation layer but also
through remote services thanks to the REST modules (see my snippets
below).
So, back to my example, the idea would be for the show
action of the profiles_controller to GET infos from the 6 ressources
from the module rest:
profiles_controller.rb
# GET presentation/profiles/1
# GET presentation/profiles/1.xml
def show
@user = get rest/users/params[:id]
@events = get rest/events/?attendee=params[:id]
# ../..
end
The result: you have clean controllers. All the authorization logic
(before_filter :authorize, :only => :destroy for instance) will be in the
REST
modules so the presentation one is just designed to retrieve
informations from you different resources.
Moreover you have already an API for the core of your application (the
REST server).
Please tell me if I''m wrong but I think this sort of mocking requests
are not built-in since even render_component, for example, creates a new
request (through ActionController::Integration::Session &
ActionController::Integration#process; using it would be a pain
because it has lots of useless data in our case...).
Looking at the source code, the point would be to create a method which
instantiates @_request, @_params & @action_name and call
ActionController::Base#perform_action (just like
ActionController::Base#process without cookies, sessions, headers,
etc.).
For my application for doctors, I have done a method:
http://pastebin.via.ecp.fr/64 (see: http://pastebin.via.ecp.fr/65 for
usage). It relies on a new dummy format ''internal''. All my
REST actions
respond to it and render text.
Back to my example:
profiles_controller.rb
# GET presentation/profiles/755
# GET presentation/profiles/755.xml
def show
@user = users_get(params[:id])
@events = events_get({:attendee_id => params[:id]})
# ../..
end
and the same with users_(put|delete|post). Those methods returns the body of the
respond_to, e.g.:
class UsersController < ApplicationController
def show
../..
respond_to do |format|
format.internal {render :text => @user.name}
end
end
end
(this part would be application specific; your can render CSV, xml, or
whatever, following your own internal conventions to communicate with
the presentation layer)
Just a detail: unfortunately, I was not able to call
ActionController::Routing::Routes.recognize because it works on a real request.
So you have to call posts_get({:id => 42}) instead of
get posts/42.internal (kind of ugly).
I use this solution and it works (a little bit hackish however, you
might already be thinking of a better way to do such a thing).
What do you thing of building inside of Rails such methods to retrieve
informations? I''m pretty sure it will be a great enhancement for a
better design and to avoid controllers which mix CRUD & non-CRUD actions.
I wanted to open the discussion here to detail those points. If you
are interested in, I will open a [ENHANCEMENT] ticket on the trac.
Thank you for your great job!
Cheers,
--
,========================.
| Pierre-Alexandre Meyer |
| email : pam@mouraf.org |
`========================''
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Core" group.
To post to this group, send email to rubyonrails-core@googlegroups.com
To unsubscribe from this group, send email to
rubyonrails-core-unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---