Q&A about REST, namespaced controllers, authentication and authorization

Ok, so... this is gonna be a long read. I'd obviously appreciate you
read it all, but I'll understand if you just mark it as read without
doing so.

First, let me clarify that I DID my previous research which helped me
a lot, but I still have problems deciding which way to go. I'm trying
to make informed decisions here.

Also, according to my previous research I'm not the only one with this
kind of concerns and it's about time to summarize it all in one e-
mail.

I'm having problems deciding on some "architectural design" aspects of
my new application. So I'll enumerate the functionalities which I see
as the core ones that should pave the way to start coding.

= Core (high level) requirements

* It's a sort of on-line magazine with articles, news, events
calendar, polls, services and products directory, comments, full-text
search capabilities and maybe some other feature.

* There should be an administration application which serves as the
backend to the content maintainers. This administrators should be
categorized with roles as (at least) Editor and Writer. Each role
would have a set of permissions to manage content. This administrative
interface should be simple, non-cluttered, uniform and completely
separated from the frontend.

* The public site (frontend) should have a homepage summarizing the
latest content of the entire site, banners, etc (typical homepage).
Each kind of content should have it's own main page accessible from
the main navigation as a section of the site (Home, Articles, News,
etc... would be the main menu). This frontend site should have it's
own set of registered users whose "special feature" would be to have
access to the private content. So occasional visitors AND logged in
registered users would use and see the same interface, but registered
users would see public and VIP content.

I think that briefly describes what I need to implement.

So now I'll present to you some questions that I think should have
strong, backed, opinionated answers BEFORE I start coding (which
should be soon according to my deadlines). I'll include my own still
doubtful answers/opinions so some rails' GURUs can correct me (so I
and others can learn) or not (so I feel gooood about my choices).

= REST & resources vs. Namespaced controllers

REST and resources oriented WebApps are getting a lot of attention in
Rails at least since DHH's Keynote last year (which I've seen and felt
amazed). I've read MANY posts and articles, read the RESTful Rails
Development PDF, some RPC->REST refactoring articles, AWDwR2 (by the
way, the REST part lacks the attention it deserves and all the book is
headed the traditional /:controller/:action way. Having that in mind,
it's a damn good book). I even bought the Peepcode REST screencast
which also helped a lot. I downloaded Beast forum as an example of a
modern RESTful Rails app.
Still... I can't find good examples on how to achieve some things "the
RESTful way". And according to my research in rubyonrails-talk, some
of this concerns have been raised many times by different people in
the last 8 months and it appears to me that the answers haven't been
uniform enough. I know we all have our own ways to resolve some
problems and many depend on the nature of the application. But being
Rails such a good opinionated, "educative" framework, I'd really like
to hear Rails' GURUs (maybe core team?) opinions loud and clear. And I
think it's not only me in the public...(but hey! you're doing a
wonderful job and I'm not pressing you in any way :wink: ).

== Questions about REST:

- How should I attend the clear separation between the administrative
and public sites regarding resources' controllers?

- Should I use the same [Articles|Events|News|etc...]Controller to
attend both apps? This would mean that /articles and other resource-
related routes should behave different according to who is calling it,
but it also has to differentiate between administrative users (Editor,
Writer) and visitor users (unidentified guest and logged in registered
user). I've seen this approach recommended (Peepcode's screencast
comes to mind) using before_filters but I think the reality I have to
model is much more complicated than the examples. According to the
sources I've studied, this could also bring some caching problems too
because it practically nullifies the possibility of using page and
action cache. So my currently doubtful decision would be not to
"merge" back and frontend controllers... but it drives me to
controller name's collisions because ArticlesController is a great
name to use in both apps. Unless... I use namespaced controllers...

- Should I use namespaced controllers and views to differentiate the
administrative and public sites? I initially thought this would be a
"cleaner" approach. I read some [1] saying namespaced controllers are
getting out of fashion... but then Jeremy Kemper almost defending them
on the same thread. If I go this way, should my namespaced controllers
be resource or traditional controllers? This is my current choice...
But it feels like going away from REST. And I want my app to be cool :-
D.

[1]
http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/53cb3bc83409f7e/fd16338b5443cc30?lnk=gst&q=dhh&rnum=6#fd16338b5443cc30

- Rails 1.2.2's singleton resource controller appears to me as a good
candidate to attend tipical general pages like homepage, about,
dashboard (HomepageController, AboutController, DashboardController)
seeing them as single resources with just the #index action. Am I in
the right direction here?

= Auth[entication|orization]

I was thinking of using acts_as_authenticated (or
Restful_authentication) and Authorization plugins to leverage the
authentication/authorization layer of my app. But... wait! I have 2
separate models for users. I'm planning to use User (basically: login,
name, e-mail) for the administrative users which use the
administration site differentiated by an associated Roles model, and
Subscriptor (login, name, e-mail, phone, address, country, and a LOT
of etceteras...) for the registered visitors to the frontend
application. Each one of this [back|front]end applications should have
it's own login screens, etc...

== Questions about Authentication/Authorization:

- Will I be able to achieve this kind of functionality using the named
plugins?
- Can you suggest a better more simple way to do this?

Ok. I think this summarizes the 2 most prominent problems I'm in right
now.

I'd appreciate your comments/examples/links...

Very good that someone started a thread like this. I'm having exactly
the same problems as you have and exactly the same questions that I'd
like to get answered before I start my project. Let's hope that we get
some replies.

Pietropizzi

Bump for a very good thread that asks some very practical questions. :slight_smile:

I think you are asking excellent questions. Here's an approach that I
am investigating for caching:

Since neither an editable (form) page nor a simple display page alters
the data, they should both be available via http GET. However, the
scaffold_resource generator produces an architecture that uses a query
string (;edit) to specify which page is wanted. The query string is
ignored by page caching. So, when you GET "/documents/1", it caches
the display page, and when you GET "/documents/1;edit", it gets the
display page out of the cache instead of making a nice editable form
with the data inserted.

I think it's more appropriate to treat alternative html formats as
just that; formats. I might send a request like "/documents/
1.html_edit" (You have to add that mime type to the environment.rb,
like:

.
.
.
Mime::Type.register "text/html", :html_edit
.
.
.
Now, that "works" as far as being recognized by page caching:
everything gets cached and served from cache.You have to add
"caches_page :index, :show"

to the controller. The corresponding "show" method looks like:

  # GET /documents/1
  # GET /documents/1.xml
  # GET /documents/1.html_edit
  def show
    @document = Document.find(params[:id])

    respond_to do |format|
      format.html # show.rhtml
      format.html_edit {render 'documents/edit'}
      format.xml { render :xml => @document.to_xml }
    end
  end

However, expiring the cache isn't pretty:
in my controller's "update" action, for instance, I added:
.
.
.
       #expires /public/documents.html
       expire_page(:controller=>'documents')

       #expires /public/1.html (the show.rhtml result)
        expire_page(:controller=>'documents', :action=>'',:id =>
@document)

       #expires /public/show/1.html_edit

expire_page(:controller=>'documents', :action=>'show', :id=>"#{@document.id}.html_edit")
.
.
.
to get everything to clean up properly. Ugly.

I think perhaps multiple controllers is a good idea. What did you end
up trying?

Ron

Caching: Edgerails is supposed to fix it by appending named actions to
the URL with a "/" instead of a ";", which should do the trick.

Ron