users@jsr311.java.net

Re: URI Contracts

From: Sean Landis <sean.landis_at_gmail.com>
Date: Tue, 10 Jun 2008 18:19:47 -0600

Clients are problematic for all the reasons Bill pointed out. We've
hit them all in our attempts to have service providers deliver clients
to other teams to 'ease the pain' of the disparity between Java and
HTTP. Some like the proxy approach but it is limiting.

I think focus should be on the server side too.

Sean

On Tue, Jun 10, 2008 at 8:01 AM, Bill Burke <bburke_at_redhat.com> wrote:
> 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
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jsr311.dev.java.net
> For additional commands, e-mail: users-help_at_jsr311.dev.java.net
>
>