Great post, Craig.  Most everything you describe is supported by the
Rest Plugin:
 * All the described URL patterns
 * The automatic use of the Location header after a POST
 * Ability to switch representation using extension (adding accept
header support would be easy)
 *  All actions are on one Controller class
 * XML and JSON outputs are automatically generated and processed on POST/PUT
 * Ability to customize XML and JSON output (declare a result named
"NAME-EXTENSION", e.g. "success-xml"
 * Support for any additional action method
 * Workaround support for browsers that can't PUT or DELETE (using the
_method parameter just like Rails)
 * Code doesn't know or care if the request came from a browser or
service client

The reason all the Rails features are supported is a blatantly copied
their design and conventions.  In addition to easing the transition of
one familiar with Rails and using a proven design, it means clients
written for Rails apps will work with no changes.  The pieces that are
missing are the backend, database-touching stuff like ActiveRecord or
the automatic HTML generation.  So while you wouldn't get the quick
initial development speed of Rails, you get all the core framework
support and then some.

Some things that Struts 2 with the Rest Plugin has (or will have) that
Rails doesn't:
 * Type-safe cache header (last-modified and etag) support
 * Better view abstraction with the Result object so paths aren't
hard-coded into your class
 * The controller doesn't have to have any knowledge of the
representation types it supports - all automatic
 * Automatic partial GET support (not done yet, but it is next)
 * WADL support (again, coming soon)

Don't get me wrong, I'm not trying to make Struts 2 go up against
Rails, but rather, I think it is past time we applied the lessons of
Rails' Rest support to a Java framework and I think Struts 2 is the
perfect match.

Don

On 10/23/07, Craig McClanahan <[EMAIL PROTECTED]> wrote:
> 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]
>
>

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

Reply via email to