users@jersey.java.net

Re: [Jersey] [PATCH] to allow the API of RESTful services to be rendered using hierarchial Implicit Views

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 20 Feb 2009 17:41:36 +0100

On Feb 20, 2009, at 3:38 PM, James Strachan wrote:

> 2009/2/20 Paul Sandoz <Paul.Sandoz_at_sun.com>:
>>
>> On Feb 19, 2009, at 4:42 PM, James Strachan wrote:
>>
>>> 2009/2/19 Paul Sandoz <Paul.Sandoz_at_sun.com>:
>>>>
>>>> Hi James,
>>>>
>>>> This looks really interesting! thanks for doing this.
>>>
>>> No worries - it was fun! I was surprised how easy it was to reuse
>>> the
>>> WadlResource in an implicit view with really minor changes to
>>> Jersey!
>>>
>>
>> Index:
>> jersey-server/src/main/java/com/sun/jersey/server/impl/uri/rules/
>> SubLocatorRule.java
>> ===================================================================
>> ---
>> jersey-server/src/main/java/com/sun/jersey/server/impl/uri/rules/
>> SubLocatorRule.java
>> (revision 2021)
>> +++
>> jersey-server/src/main/java/com/sun/jersey/server/impl/uri/rules/
>> SubLocatorRule.java
>> Thu Feb 19 14:03:33 GMT 2009
>> @@ -47,6 +47,8 @@
>> import com.sun.jersey.spi.inject.Injectable;
>> import com.sun.jersey.spi.uri.rules.UriRule;
>> import com.sun.jersey.spi.uri.rules.UriRuleContext;
>> +import com.sun.jersey.spi.uri.rules.UriRules;
>> +
>> import java.lang.reflect.InvocationTargetException;
>> import java.lang.reflect.Method;
>> import java.util.Iterator;
>> @@ -95,7 +97,14 @@
>> context.pushResource(resource);
>>
>> // Match sub-rules on the returned resource class
>> - final Iterator<UriRule> matches =
>> context.getRules(resource.getClass()).
>> + if (resource == null) {
>> + return false;
>> + }
>> + UriRules<UriRule> rules =
>> context.getRules(resource.getClass());
>> + if (rules == null) {
>> + return false;
>> + }
>> + final Iterator<UriRule> matches = rules.
>> match(path, context);
>> while(matches.hasNext())
>> if(matches.next().accept(path, resource, context))
>>
>> Was there something going wrong that forced the above changes. I am
>> trying
>> to work out if there is a deeper problem here.
>>
>> I think one problem is that a sub-resource locator can return a
>> null value,
>> which was not checked before.
>>
>> IIRC if "resource" is not null there will always be a non-null
>> "rules"
>> returned. Did you have a case where this was null?
>
> Sorry forgot that was still there. I had some NPE's and wasn't exactly
> sure the reason - I think it was the resource being null, not the
> rules being null. I think it was when I was trying a URI that didn't
> correctly map to a resource bean; but would rather see 404's returned
> than NPE's and a stack dump :).
>

I agree. I need to double check what we say on the spec for a null
value, it could be unspecified.


>
>> Do you think there might be value in letting the developer plugin
>> in the
>> required WadlResource, extending from a base class? this might make
>> it
>> easier to allow developers to evolve the code as they require e.g a
>> property
>> for a class, or instance, that extends WadlResource.
>>
>> Or... to support it using it in a conventional way e.g.
>>
>> @Path("/api")
>> public CamelWadlResource extends WadlResource {
>> ...
>> }
>>
>> and have things injected correctly on WadlResource. The runtime
>> could check
>> in any resource class implements WadlResource and if none do it can
>> supply a
>> default (if JAXB is present in the classpath).
>
> Ah thats a neat idea! The most likely place for new methods would
> probably be on the WadlResourceResource to be honest when rendering a
> specific resource's documentation; but am sure others might think of
> other things they want to add when rendering the documentation for
> their API (e.g. querying some database/wiki/CMS for extra content to
> render?).
>
> One thing I was gonna add to this patch was a helper method that
> returns a kinda multi-map of method REST verbs as keys then for each
> verb, the various methods. e.g. for GET find the N representations
> (methods) of GET rather than just navigating a flat list. As when
> rendering you might just want the list of all the GET methods for
> example.
>
> Though other than that I can't think of too many other methods I might
> want to add to the resource classes - but am sure others might think
> of something. Its kinda easy to wrap up any custom view functions
> inside a custom tag these days - e.g. here's the <api:resource> tag
> I'm using...
> https://svn.apache.org/repos/asf/camel/trunk/components/camel-web/src/main/webapp/WEB-INF/tags/api/resource.tag
>
> and to show the doc of a resource/method
> https://svn.apache.org/repos/asf/camel/trunk/components/camel-web/src/main/webapp/WEB-INF/tags/api/doc.tag
>
> But it is kinda nice keeping helper methods on the resources and
> sharing the common code in Jersey
>
>
>> Or do you think the modifications on the WADL-based resources will be
>> sufficient that no further modification would be required?
>
> I think it would offer more flexibility and control; provided we
> expose an overloadable factory method in WadlResource to allow custom
> WadlResourceResource implementations to be created too.
>
> Also it would let you keep all your implicit view templates in the
> same package structure (e.g. org/apache/camel/web/resources/* in my
> case) rather than some there and some in com/sun/jersey/whatever...
>
> So yes - I think its a good idea!
>

OK. I will look into this.

Paul.