On 10/21/07, Don Brown wrote:
On 10/22/07, Martin Cooper wrote:
On 10/21/07, Don Brown 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 ] }

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
# (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 :-).


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

To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org

Search Discussions

Discussion Posts


Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 19 of 29 | next ›
Discussion Overview
groupdev @
postedOct 21, '07 at 2:33p
activeOct 23, '07 at 2:34p



site design / logo © 2018 Grokbase