incubator-jspwiki-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Murray Altheim <murra...@altheim.com>
Subject Re: REST-ful URLs [Was: url rewriting supported?]
Date Tue, 08 Jul 2008 07:34:15 GMT
Andrew Jaquith wrote:
> Murray --
> 
> Ok, wanna turn the crank on this a little?

Yes, lets.

> My thought, after reading what you wrote, is that we (meaning: you and 
> I) could probably hammer out something that bridges 1) what you want, a 
> nicer RESTish URL format, and 2) what I've been thinking about with all 
> of the automatic bean-binding goodies that will come with JSPWiki 3.0, 
> courtesy of Stripes.

Andrew, first of all: thanks very much for taking the time and effort
to explain all of this. It took two readings but I understand it, and
it's brilliant. Yes, it ties us into Stripes, but basically the code
could be replaced in five years by whatever is the latest trend in
five years (none of that matters, really) because the real API is the
URL and the constitution of the messages passed between the URL handler
and the application, and those messages should be highly rational and
form their own mini-API without any extra work (heck, it's already
there!).

> 1) STRIPES IN 60 SECONDS
>[...]
> So far, that's pretty great, huh? We've gone through the entire bean 
> resolution, binding and event execution lifecycle without writing any 
> special code -- it's all done via simple annotations. Best of all, we 
> get to rip out lots of crappy JSP scriptlet code.

Yes, great stuff.

> 2) WHAT ABOUT MURRAY'S CLEAN URLS?
> 
> Assuming you follow the logic here, you can see how the 
> resolution/binding/event lifecycle works in a straight-ahead, 
> traditional URL format (e.g., path?param=value=&param=value).
> 
> Now, let's apply this to a "clean URL" scenario like the one you described:
> 
> http://murray.org/{subject}/{predicate}/ [optional "adjectives"]
> 
> Using our example, it might look like this:
> 
> /pages/Foo/?event=create
> 
> or maybe: /pages/Foo/create
> 
> This presents more of a challenge. We need some way of transforming the 
> inbound URL into a normal request -- with normal parameters -- so that 
> Stripes can locate the right bean, [etc.]
> 
> Originally I was thinking we'd need to write our own filter to do this, 
> or use URLRewrite. It turns out some clever Stripes devs got there 
> first. They call this the "clean URL" feature. It was initially a user 
> contribution, but the Gregg and Tim liked it so much they put it into 
> the trunk.
> 
> I have been watching the 1.5 builds, but TOTALLY forgot about this. 
> Needless to day, it completely solves the problem, and it makes my 
> previous comments about needing an external filter totally obsolete. 
> Assuming you buy into the Stripes Way, the URL scheme you describe can 
> be completely accommodated.

Very exciting, especially since the investment in code is so minimal,
the functionality so rationalized, and the result just works.

> Anyway, the new Clean URL feature works like this (from the Stripes 1.5 
> Javadoc):
> 
> "Stripes supports "Clean URLs" through the UrlBinding annotation.
> [...]
> "Clean URL parameters can be assigned default values using the = 
> operator. For example,@UrlBinding("/foo/{bar=abc}/{baz=123}"). If a 
> parameter with a default value is missing from a request URL, it will 
> still be made available as a request parameter with the default value. 
> Default values are automatically embedded when building URLs with the 
> Stripes JSP tags. The default value for $event is determined from the 
> DefaultHandler and may not be set in the @UrlBinding.
> 
> "Clean URLs support both prefix mapping (/action/foo/{bar}) and 
> extension mapping (/foo/{bar}.action). Any number of parameters and/or 
> literals may be omitted from the end of a request URL."

This is great. I spent some hours last week writing a URL remapper and
this does it via an annotation; brilliant.

> You can see some addition comments on the development of the feature here:
> 
> http://www.stripesframework.org/jira/browse/STS-262
> 
> So-- to wrap up our previous example, the @URLBinding annotation for our 
> PageActionBean class would look like this:
> 
> @URLBinding("/pages/{page=Main}/?event={$event}")
> 
> or:
> 
> @URLBinding("/pages/{page=Main}/{$event}")
> 
> Nice, huh? No coding needed.

Yes, a very clean design. Thanks.

[...]
> 4) THINKING ABOUT BEANS AND EVENTS
> 
> The difficult part of all this is figuring out how to map ActionBeans to 
> what we understand today as WikiContexts, and to the URL scheme you have 
> suggested. It all comes down to how you look at things:
> 
> - Do you select a page, then take an action on it? (view, edit, comment)
> - Or do you "edit" something... and specify that that something is a 
> particular page?
> 
> The URL scheme you suggested implies the first approach. Today's JSP 
> scheme implies the second.

Yes, but as I just replied to Janne, my own requirements are for a
REST-ful design that doesn't embed any implementation detail in the
URL (e.g., ".action") and fully separates noun from verb.

Almost all of our present services are in need of an architectural
overview, and what we're trying to do is (sorry to the use the word
again, but) rationalize the URL schema. We're for one large project
working with a major vendor who uses a term called an "intellectual
entity" or IE, similar to what in RDF are called "resources". These
form the nouns of our services, such that there is a canonical URL
to identify the IE. This can be considered both independently of a
base URL or with it, e.g.,

    oid: isbn0-87685-479-X

    resolveable oid: http://www.acme.com/item/isbn0-87685-479-X

So we have a strong requirement that from the beginning of the
base URL to the end of the oid forms a canonical reference to
an oid.

This works well with a scheme where the last or semi-last token
in a URL is the oid, the last case using the last as the verb. I'm
not wedded to either approach of where the verb should sit.

> Personally, I like the "object" followed by "verb" idea (the first 
> approach). It maps fairly cleanly to the Stripes ActionBean properties + 
> event model. 

When I read the above I smiled, as that's exactly what I'm aiming
at. So we can have either

   http://www.acme.com/item/isbn0-87685-479-X/get/

or

   http://www.acme.com/item/isbn0-87685-479-X/?action=get

as far as I'm concerned. I'm guessing that my teammates might go with
the latter (given some designs I've seen) but as I mentioned I do
have *some* flexibility (I think).

> Thus, a hypothetical PageActionBean class ("the action bean 
> you use to 'do stuff' with pages") might include the following 
> properties and methods:
>
> @URLBinding("@URLBinding("/pages/{page=Main}/{$event}")
> class PageActionBean {
>   WikiPage getPage()
>   void setPage(WikiPage)
>   int getVersion()
>   void setVersion(int)
>   void view()
>   void edit()
>   void comment()
> }
> 
> The view, edit and comment methods are the events. These are also, at 
> least in theory, "request contexts" as well. (It is easy to see how 
> these would map to WikiContext.VIEW, .EDIT, and .COMMENT...)
> 
> Murray, assuming I have not bored the crap out of you, what do you 
> think? Want to brainstorm some more about "nouns" (action beans) and 
> "verbs" (events)? Got the full schema to share?

Bored? Hardly. No, this is great, I'm keen to try this out.

What I'm thinking is that Janne doesn't sound all that enthusiastic
about this so it might have to fit into the application as another
URLConstructor, or as a sort of proxy that hands off services to
the WikiEngine, dunno. If it were handled as a modular, standalone
web service with an open backend API we'd just need the glue to
hook it into the WikiEngine et al, and it could be reused for other
related web services (those layers I mentioned) that provide alterna-
tive access to the wiki repository, e.g. a web service alternative
to some of the XML-RPC functionality, interwiki or wiki-hive features,
the means of hooking the repository into analysis or preservation
system, etc.

In other words, the Stripes stuff you've mentioned sounds like it
could be useful for all sort of things. I'm just not sure how it
might fit into JSPWiki itself at this point.

As for the URL schema, you've got most of it at this point, unless
you mean the specifics of the verb names, etc.  I don't mean to
sound secretive at all, but I just don't think the specifics matter
all that much at this point, i.e., they'd like just be implementation
details as far as I'm concerned, some constant values we can argue
over at some other time (I wouldn't want to get bogged down in that
kind of thing).

Murray

...........................................................................
Murray Altheim <murray07 at altheim.com>                           ===  = =
http://www.altheim.com/murray/                                     = =  ===
SGML Grease Monkey, Banjo Player, Wantanabe Zen Monk               = =  = =

       Boundless wind and moon - the eye within eyes,
       Inexhaustible heaven and earth - the light beyond light,
       The willow dark, the flower bright - ten thousand houses,
       Knock at any door - there's one who will respond.
                                       -- The Blue Cliff Record

Mime
View raw message