Just thought about this, you could even use this method thing in the FatClient stuff we have in Woko :
@FatClient(alternateEvent="myEventFat", httpMethods = { PUT, POST }) public Resolution myEvent() { ... } Again, I don't really see any benefit, only added complexity, but it's doable :) Cheers Remi On Wed, Jul 9, 2008 at 11:11 AM, VANKEISBELCK Remi <[EMAIL PROTECTED]> wrote: > Hi folks, > > Been a while... Getting back to geek life, little by little :-) > > I'm not convinced by this REST stuff. To be honest, I'm amongst the > ones who think that when it comes to RPC, no matter what HTTP method > is used, what you need is simply an endpoint that responds to an HTTP > request. Then, request parameters are enough to decide what to do. To > be honest I don't even understand the buzz that has been created > around this HTTP method stuff lately... People trying to build new > middleware over HTTP again ? Erf, deja vu :P > > But sure, the idea of exposing action beans as programatic services, > available to "fat" clients, is a good one. And there are very simple > and effective ways to do it already... :) > > We already have a Stripes extension in Woko that allows instant RPC > enabling of a Stripes action bean. > > Example bean : > > class MyAction ... { > > > public Resolution doIt() { > ... > return new RedirectResolution(...); > } > > } > > The doIt() event returns a redirect, thus making it hardly usable from > a fat client, or a javascript in the client browser. Moreover, if > validation errors occur, or an exception is thrown, then HTML is > returned in the response, and again is hardly usable by a fat client. > > Now what if you wanna enable this event for fat clients ? Well, easy, > just annotate the event method, and define another one that handles > streaming of the result in the format you want (Woko supports JSON and > XML ootb, but you could even write your own format) : > > class MyAction ... { > > @FatClientEvent(method="doItFat") > public Resolution doIt() { ... } > > public Resolution doItFat(Resolution originalResolution) { > String myJson = ... ; > return new StreamingResolution("text/plain", myJson); > } > > } > > Thanks to a specific interceptor, and using a specific request > parameter, you can now invoke this action bean from the browser, the > regular HTML way : > http://.../myapp/my.action?doIt=true&... -> returns HTTP redirect > > Or from any client that is able to send HTTP requests and understands > your format : > http://.../myapp/my.action?doIt=true&fatClient=true&... -> return JSON > > Of course, the interceptor also handles exceptions and validation > errors (streamed back as JSON or XML). > > The good thing with this approach IMHO is that you reuse the existing > logic, as the real event is actually invoked, only the returned > resolution is discarded for another, fat client enabled one. You > expose functionnality of your application to third party apps without > touching the human interface (HTML and flows). > > This "trick" is very simple and consistent, and allows to RPC enable > any existing action bean at a very low cost, without any impact on the > existing logic inside your action bean's event methods. > > And really, you don't need any "verb" at all ! GET, POST, PUT, > DELETE... this is just useless : you already have events :-P > We have RPC-enabled all CRUD (and full text search) features of Woko > with this technique : you can actually do everything you do by > clicking in the browser with a fat client. > http://woko.wiki.sourceforge.net/AjaxBackend > http://woko.wiki.sourceforge.net/AjaxExamples > > The RPC layer was added after he whole web stuff was working, and > again it was not intrusive by any mean. It broke no existing web page, > and didn't even require any refactor of the existing code... > > Ok, I might be drifting OT a little bit : your post was about the use > of HTTP method (verbs) in the context of RPC with Stripes. But again, > I think this verb stuff is straight overengineering. I mean, why would > you need this ? Is there a good explanation of the advantages of this > approach somewhere ??? I've never seen such stuff, and it's never been > a problem to me. RPC over HTTP is clearly suckish, but hey, that's > pretty easy to implement and you don't really need all this overhead > IMHO... > Send stuff, get stuff back. As simple as this :) > > My 0.02 > > Fat Rémi > > On Wed, Jul 9, 2008 at 6:36 AM, Will Hartung <[EMAIL PROTECTED]> wrote: >> We were babbling on IRC, as we tend to do. I mumbled about this a >> couple of days ago, and then Double-A Porter got on his bullhorn >> about StripesStuff. >> >> I want to explore adding a more formal REST capability to Stripes. >> >> I think that there is great value is adding better "full bodied" REST >> Support to an Action framework like Stripes. >> >> If you cruise around the Intratubes, you'll find that we have Action >> Frameworks, but we also have REST Specific frameworks as well. >> >> Turns out the Action frameworks don't actually support REST as well >> as they could, and REST frameworks don't support classic web apps >> very well, if at all. >> >> Now, some may say "WTH? What's so hard about REST? It's just HTTP, eh?" >> >> Yes, it is just HTTP. Which is why it's kind of silly to need two >> "HTTP" Frameworks to make writing this server side logic. >> >> "But if REST is just HTTP, why can't we just use Stripes out of the >> box?" Well, first it doesn't come in a box -- you have to download >> it. But, be that as it may, Stripes, like most every other Action >> Framework, actually supports only a subset of HTTP. >> >> For example, we had the post earlier about the other HTTP verbs and >> how, save for GET and POST, Stripes pretty much just shows them the >> door. >> >> That's Bad(tm). >> >> See, the REST wonks want to use all of those other verbs: HEAD, PUT, >> DELETE, etc. In fact, some want to make their own as well (for >> example, WebDAV creates its own HTTP verbs). This is fully within the >> HTTP spec, making this stuff up as you go. >> >> Now, while you Cro-Magnon web page grognards from the "when I was a >> kid, all we had was GET, 14K modems, and Perl" school of web >> programming are happy with the status-quo. REST aficionados, umm, ain't. >> >> Fortunately, it should not be a real leap to bring Stripes in to the >> 21st century, and be a Good Citizen with the rest of the HTTP protocol. >> >> Ideally, this can all be done in Stripes Stuff with interceptors, so >> as not to need to change Stripes core and offend Tim and his "GET OFF >> MY LAWN" ways. >> >> I think the primary thing is to be able to expose the HTTP verb as a >> first class part of the binding and event mechanism. >> >> The requirements are: >> >> + Stripes works as it always has -- this is an "opt in" system. So, >> breaking classic Stripes is off the table. >> + First class handling of the Standard HTTP verbs: GET, PUT, POST, >> DELETE, HEAD, OPTIONS. TRACE and CONNECT appears to be server level >> Verbs, so we'll punt on those. >> + Ability to support other verbs. This means, basically, being able >> to bind to a String. >> + Better support, perhaps through utility methods for content >> negotiation, HTTP headers, and response codes. Response codes are a >> Big Deal to REST folks, so they should be easy. >> + Easy return of ValidationErrors in some format besides HTML (i.e. >> XML or JSON) >> + Ideally, binding to other data types beside multipart form >> requests, notably XML and JSON, though this is at the bottom of the >> list for a reason. >> >> In REST, it's important that the same URL do different things >> depending on the verb. >> >> Right now, Stripes conflates GET and POST to mean the same thing. To >> the REST cognoscenti, the two are quite, quite, different. So, we >> need to be able to readily handle differentiating those two kinds of >> requests, even tho the URL is identical. >> >> There's two ways to do that. >> >> One is annotating a method with @Rest, or @Http or something, and >> then using a configuration by convention meme base on the name of the >> event. >> >> For example: >> >> // Default rest binding >> public class PersonActionBean { >> @Http >> public Resolution post() { ... } >> @Http >> public Resolution get() { ... } >> @Http >> public Resolution delete() { ... } >> @Http {method="MYHTTPVERB"} >> public Resolution myHttpVerb() { ... } >> } >> >> If an event is passed, we could do: >> >> public class PersonActionBean { >> // For event name "view" >> @Http >> public Resolution postView() { ... } // should this be viewPost? >> @Http >> public Resolution getView() { ... } >> @Http >> public Resolution deleteView() { ... } >> @HandlesEvent("view") // stock stripes annotation >> @Http {customMethod="MYHTTPVERB"} >> public Resolution myHttpVerbForViewEvent() { ... } >> } >> >> If we punt on CbC, and be explicit we can do: >> >> @Http(method={HttpVerb.DELETE, HttpVerb.PUT}, customMethod= >> {"MYDELETE", "MYPUT"}, eventName="shazam", default=true) >> >> where >> >> method = The HTTP verbs that this event would bind too. >> customMethod = Custom HTTP verbs to bind to >> eventName = the name of the event to bind too >> >> And stock @DefaultHandler would be used to tell us that it's the >> default for that specified methods. >> >> By default, any event that isn't annotated would be considered as >> method={HttpVerb.POST, HttpVerb.GET}, i.e. both, like Stripes is now. >> >> Does anyone like or dislike either of these techniques for binding >> events? >> >> For content negotiation, I think just some utility methods can be >> used to break up and make the content-types more available to the >> user. I don't see a need to dispatch on content type (though that >> could be interesting as well, I think it's something that could also >> be layered in later). >> >> For the Headers and ResultCodes, that can probably be handled with a >> couple of new Resolution types, I don't recall how stripes handles >> result codes right off the top of my head. >> >> We saw the issue that Freddy had with having to extend >> ForwardResolution to add his Success header, a customer resolution >> that lets us tack on headers would be trivial to do. >> >> As for returning errors in a different format than HTML, that could >> also be done, I think through a custom resolution, >> JSONErrorsResolution, or XMLErrorResolution, and the dispatch code >> could (somehow) know which one to you, either by configuration or, >> ideally, content negotiation. >> >> For now, I'll punt on potentially binding other data type for input >> besides mutlpart form requests. I think there's value here, as many >> REST services are POX services, as well as multipart, and Ajaxy types >> like chatting in JSON. >> >> The basic thought was that the process would "flatten" the in coming >> XML or JSON into, effectively, multipart parameters, and then let >> Stripes do the rest of the work. Also, we make available, perhaps, >> the DOM of the XML if the action has a Document field. And, perhaps, >> something appropriate for JSON (I don't know much about JSON, so I >> can't say what this would be, heaps of bags of maps of maps maybe). >> >> Obviously, if you send stuff that the standard Stripes binding can't >> do, then, well,it doesn't work. Don't do that. Be nice to Stripes, >> it'll be nice to you. >> >> Save for the potential binding of incoming data, you can see that >> this should not be a horrible amount of work. >> >> And I'm not suggesting anyone take it on, or that the Stripes guys do >> it. >> >> But I would like to have your thoughts about the approach, which you >> like better, and any suggestions that y'all might have. >> >> Regard, >> >> Will Hartung >> >> >> ------------------------------------------------------------------------- >> Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW! >> Studies have shown that voting for your favorite open source project, >> along with a healthy diet, reduces your potential for chronic lameness >> and boredom. Vote Now at http://www.sourceforge.net/community/cca08 >> _______________________________________________ >> Stripes-users mailing list >> Stripes-users@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/stripes-users >> > ------------------------------------------------------------------------- Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW! Studies have shown that voting for your favorite open source project, along with a healthy diet, reduces your potential for chronic lameness and boredom. Vote Now at http://www.sourceforge.net/community/cca08 _______________________________________________ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users