users@jsr311.java.net

Re: URI Contracts

From: Bill Burke <bburke_at_redhat.com>
Date: Tue, 10 Jun 2008 10:01:14 -0400

I was just trying to elaborate on Marc's point that a Java interface is
not something that can be used as an IDL shared by client and server
because client and server have different requirements.


Alexander Horn wrote:
> The original proposal I put forth does include a REST client code
> snippet which may have suggested that I am targeting the entire REST
> service stack. My primary intention is to limit the discussion to the
> server-side though. That is, the client-side proxy framework is an
> important idea but it goes beyond JAX-RS requirements.
>
> Alex
>
> On Tue, Jun 10, 2008 at 2:18 PM, Bill Burke <bburke_at_redhat.com> wrote:
>> We developed a client-side proxy framework using JAX-RS annotations with
>> JBoss's RESTEasy JAX-RS implementation. resteasy.sf.net. A few users have
>> found it useful.
>>
>> One thing to note is that an interface can't always be shared by the client
>> and the server:
>>
>> * Optional parameters and DefaultValues throw a wrench in things for a
>> client interface
>>
>> * The server may be doing complex content negotiation and need a Request
>> injection.
>>
>> * The client-proxy interface needs to define explicitly what mime type it is
>> sending so @ConcumeMime really can only take one parameter. Yeah, you could
>> programmatically do this, but it sort of defeats the purpose of defining an
>> interface.
>>
>> * The server may be returning a typed POJO that can be marshalled. The
>> client might want an org.w3c.Document object instead.
>>
>> * Response objects may not translate well as a Client interface. The client
>> might want a typed object, while the server's API might return a response
>> and vice versa. We also had to provide our own ClientResponse interface
>> because Response has no type information associated with it and the proxy
>> framework would have no idea on how to unmarshal the request into a desired
>> entity.
>>
>>
>>
>> Alexander Horn wrote:
>>> I think you're onto something regarding not using language-specific
>>> means to describe HTTP/1.1 contracts, for instance. But it could take
>>> a different form than one might expect. For instance, the
>>> language-neutral form of URIs could be generated based of a Java
>>> class. Specifically, "CoolResourceURI" provides type-strong guarantees
>>> to the REST service development team but it can be equally used to
>>> express the URI contract in a language-neutral form. So the
>>> development of a REST service could leverage the Java API but REST
>>> clients are not restrained by this implementation detail. Effectively,
>>> the Java API in form of annotations acts as a DSL.
>>>
>>> Alex
>>>
>>> On Mon, Jun 9, 2008 at 9:34 PM, Marc Hadley <Marc.Hadley_at_sun.com> wrote:
>>>> We have discussed "contracts" in the past, mostly in relation to a client
>>>> API but there was disagreement about whether a Java-based contract for a
>>>> HTTP service was good idea or not. There's a good case to be made that
>>>> the
>>>> contract should be explicit (and dynamic) in the representations of the
>>>> resources themselves (hypertext as the engine of state) rather than being
>>>> a
>>>> separate artifact in the form of some kind of IDL shared between client
>>>> and
>>>> server.
>>>>
>>>> Marc.
>>>>
>>>> On Jun 9, 2008, at 6:21 AM, Alexander Horn wrote:
>>>>
>>>>> Is it desirable to create API in order to express URI contracts as
>>>>> first-class citizens?
>>>>> The goal is to encapsulate the routing details from the actual
>>>>> operations that need
>>>>> to be performed for the GET, PUT, DELETE etc. functionality.
>>>>>
>>>>> I am not sure if this has been discussed before so I think a short
>>>>> example
>>>>> might
>>>>> help to illustrate what I mean.
>>>>>
>>>>> Assume the architecture is following a DRY principle with the goal of
>>>>> separating the REST application into three distinct units: "Common",
>>>>> "Server", and "Client". Only "Common" should need to know about the
>>>>> internal URI contract requirements. I follow the conviction that an
>>>>> API-proposal needs to fit on one piece of page. So let me contrast
>>>>> JAX-RS' current design with a different approach by given a
>>>>> code-snippet example. I hope with this post I can get constructive
>>>>> feedback if this is a desirable design alternative from the one put
>>>>> forth in JAX-RS.
>>>>>
>>>>> Code Snippets:
>>>>>
>>>>> == Contract/Commons ==
>>>>>
>>>>> /**
>>>>> * Define a URI contract that has the template {path}/{urn}.
>>>>> * Example URL: "http://localhost:80/a/path/to/urn:some:document"
>>>>> */
>>>>> @UriPattern("{path}/{urn}")
>>>>> CoolResourceURI implements ResourceURI {
>>>>>
>>>>> @Variable("path")
>>>>> private final String path;
>>>>>
>>>>> @Variable("urn", "urn:\\.*")
>>>>> private final URI urn;
>>>>>
>>>>> getPath() {
>>>>> return path;
>>>>> }
>>>>>
>>>>> getURN() {
>>>>> return urn;
>>>>> }
>>>>>
>>>>> ...
>>>>> }
>>>>>
>>>>> == Server-Side ==
>>>>>
>>>>> /**
>>>>> * Attach {_at_code CoolResource} servlet to the {_at_code CoolResourceURI}
>>>>> contract.
>>>>> */
>>>>> @UriContract(CoolResourceURI.class)
>>>>> class CoolResource {
>>>>>
>>>>> /**
>>>>> * Handle {_at_code GET} HTTP/1.1 request for resources that map to
>>>>> {path}/{urn}
>>>>> */
>>>>> get(CoolResourceURI uri) {
>>>>> // do something with the URI components
>>>>> // Ex: "/some/path/urn:cool:cow"
>>>>> // --> path="/some/path", urn="urn:cool:cow"
>>>>> ...(uri.getPath(), uri.getURN());
>>>>> }
>>>>>
>>>>> ...
>>>>> }
>>>>>
>>>>> == Client-Side ==
>>>>>
>>>>> /*
>>>>> * Send {_at_code GET} HTTP/1.1 request for an URI whose lexical
>>>>> representation matches the template {path}/{urn}
>>>>> */
>>>>> ... = getRestController().get(new CoolResourceURI("/some/path",
>>>>> "urn:cool:cow"));
>>>>>
>>>>>
>>>>>
>>>>> Notice how this different design strategy would strengthen the
>>>>> weakly-typed solution that we currently see in the JSR draft. I tried
>>>>> to demonstrate an improvement to the API by showing three REST
>>>>> components that use ResourceURIs (see "CoolResourceURI" as an example)
>>>>> as a means to encapsulate the URI contract to which the REST service
>>>>> must adhere.
>>>>>
>>>>> Also note how the "CoolResource#get(CoolResourceURI)" method is a
>>>>> type-strong and an succinct way of saying that only GET HTTP/1.1
>>>>> requests for a specific URI contract should be fulfilled by the server.
>>>>> It also acts as a type-strong abstraction layer for each
>>>>> template variable assignment (i.e. {path}, {urn}).
>>>>>
>>>>> Regards,
>>>>> Alex Horn
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jsr311.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_jsr311.dev.java.net
>>>>>
>>>> ---
>>>> Marc Hadley <marc.hadley at sun.com>
>>>> CTO Office, Sun Microsystems.
>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jsr311.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jsr311.dev.java.net
>>>>
>>>>
>>>
>>>
>> --
>> Bill Burke
>> JBoss, a division of Red Hat
>> http://bill.burkecentral.com
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jsr311.dev.java.net
>> For additional commands, e-mail: users-help_at_jsr311.dev.java.net
>>
>>
>
>
>

-- 
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com