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

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 K. 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…


Diego

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:

Diego,

I am not an expert on these matters, but this is what I can offer you if
you are still interested in:

== Authentication:
restful_authentication provides a RESTful approach to authentication
alone utilizing HTTP Basic Authentication for some of the functionality.
If you want to do RBAC (Role-Based Authorization) you can check out the
following two plugins that sit on top of acts_as_authenticated (and
should also work with restful_authentication):

I am no authority on the matter of how RESTful these authorization
plugins are as I haven’t used them before. So that is something you
will need to determine for yourself.

I am currently working on a site that has the following “types” of
users: internal (e.g. customer service rep), developer (partner
developers), customer (paying customers). I have personally created
three different web applications and hosting them on different
domains/subdomains. This allows the internal web app to only be served
to local IP addresses (in Apache/LigHTTPd) configuration very easily.
The common code (like models, controllers, views, etc.) I created a
plugin for and installed the plugin in each web application (I use
Engines 1.2 to help with this sharing even in Rails 1.2.x too).

These are just my thoughts. I’m interested in other people’s thoughts
and experiences.

Thanks,
SP

On Feb 23, 3:47 am, “diegal” [email protected] wrote:

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
actioncache.

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