On 10/21/07, Don Brown <[EMAIL PROTECTED]> wrote:
> On 10/22/07, Martin Cooper <[EMAIL PROTECTED]> wrote:
> > On 10/21/07, Don Brown <[EMAIL PROTECTED]> wrote:
> > >
> > > [...]
> > > Which reminds me, this plugin is targeted towards HTML-based web apps
> > > that want to expose their information in machine-readable ways (XML
> > > and JSON),
> >
> >
> > I presume you mean DOM-based apps; some of us don't use HTML any more. ;-)
>
> HTML = text format that you want to manually generate using jsp,
> velocity, or freemarker

What happens when different clients want different representations?
This is one of the places where Rails does a pretty nice job, using
the respond_to method to let the controller choose which
representation to produce, based on some combination of (a) what did
the client ask for (via a content type header or a format suffix on
the URL), and (b) what representations are available in the app.

On the other hand, when combined with a plugin like
make_resourceful[1] , a Rails controller supporting simple things like
CRUD operations, with multiple representations, can be incredibly
concise.  (Rails lets you define multiple related actions in a single
controller, so this is all in one class.)  The domain of interest in
this example is the posts on a blog system.

  class PostController << ApplicationController
    make_resourceful do
      actions :all
      publish :xml, :json, :yaml,
        attributes => [ :id, :title, :body,
                                 { :comments => [ :id, :author, :body  ]  }
                               ]
    end;
  end;

That's the whole controller (without make_resourceful it'd be about
100 lines of code) ... but it allows you to select any of XML, JSON,
or YAML (a text format for hierarchical data commonly used in Rails
config files, but not restricted to Ruby).  Adding HTML as an output
option is one more entry on the publish line (plus writing the
corresponding views in your favorite template language).  And this
controller automatically maps *all* of the following (think of them as
context relative) URLs to the specified controller actions, which
perform the specified tasks:

  # POST /posts -- create a new post and return status 201 plus a
Location header with the
  # appropriate URL to access the newly created post instance
  def create ... end

  # DELETE /posts/xxx -- delete the post row with key xxx
  def delete ... end

  # GET /posts/xxx/edit -- create an HTML entry form for the post with
key xxx; the
  # resulting PUT will call the update() action.  Only used for HTML
representation
  # (in earlier edge rails, this was ";edit" instead of "/edit")
  def edit ... end

  # GET /posts -- return an HTML table or a data structure in the
requested format
  def index ...  end

  # GET /posts/new -- create an HTML entry form for a new post
instance; the resulting
  # POST will trigger the create() action.  Only used for HTML representation
  # (prior to edge rails, this was ";new" instead of "/new")
  def new ... end

  # GET /posts/xxx -- return HTML details or data representation of
post with key xxx
  def show ... end

  # PUT /posts/xxx -- update the post row with key xxx from parameters
in this request
  def update ... end

Several notes are important to understand if you're not familiar with
Rails REST support:

* With make_resourceful, you don't actually write the above methods at
all -- they
  are generated at runtime.  The source code above is what the
developer writes (plus any
  HTML views).  Can you write a complete CRUD web service with
Struts2, supporting
  multiple representations, in nine lines of code (minus HTML views)?

* Without make_resourceful, there's a Rails generator that will
actually generate all
  this code -- but you end up with ~100 lines per controller, with a
pattern that is repeated
  in every controller with only a few details being different.  That's
not optimal, which is
  why a plugin like this got created.  It won't be part of Rails 2.0
core (the Rails core
  developers have a similar allergy to a bloated core that the Struts2
developers have),
  but it's readily available.

* You can add additional actions that are related, and this is not
uncommon for special
  purpose requests that don't strictly conform to CRUD operations but
share the same
  requirements for data acquisition.

* For index and show, the client requests the representation they
want, either via an
  accept header specifying the content type, or adding ".xml",
".json", or ".yml" to the URL.

* A client of a RESTful web service will never need the "edit" or
"new" actions ... it will
  simply interact directly with "update" or "create" appropriately.

* The Rails helper methods for form based HTML input have workarounds
for the fact
  that browsers do not actually know how to do a PUT or DELETE (except
in an Ajax
  callback).  This kind of thing could easily be implemented in the
server side view
  representation, but it'll be specific to whatever templating
technology you like.

* Note that the controller's create/delete/update methods do not care
at all whether
  the client is a browser or a RESTful web service client.  The same
is basically true
  for index and show -- the "publish" capability maps to "respond_to"
methods in the
  generated actions.  This is one of the core values of REST as a
paradigm -- URIs
  are "nouns" that describe resources that can be retrieved in
multiple formats, rather
  than treating them as "verbs" that invoke a particular action
method, which is typical
  of most action oriented frameworks.

Why the long winded diatribe? Because while I'd *love* to see life
made simpler for Java web developers, and a lot of the things
happening in Struts2 are going that way -- it won't be me doing it.
I've gone over to the dark side :-) and much prefer to develop in
Rails -- for the conciseness mentioned above, but also because I don't
ever have to do a "build" or "deploy" step during my development cycle
any more.  But you guys and gals need to be reminded that *this* is
the kind of thing you are competing against if you expect to attract
Rails developers ... or to avoid even more "previously Java web
developer" defectors like me :-).

Craig

[1] http://nex-3.xom/posts/7 (but google for the make_resourceful
google group for more current info)

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to