users@jax-rs-spec.java.net

[jax-rs-spec users] Re: Hypermedia API

From: Markus KARG <markus_at_headcrashing.eu>
Date: Tue, 16 Dec 2014 18:41:27 +0100

Santiago,

I hacked a short pseudo code to illustrate what our current solution works
like:


---snip---

@Path("demo")
public class StructuralLinksDemo {
        public class A {
                int a_id = 0;

                @StructuralLink B b_ref;

                A(int id, B ref) {
                        this.a_id = id;
                        this.b_ref = ref;
                }
        }

        public class B {
                int b_id;
                
                B(int id) {
                        this.b_id = id;
                }
        }
                
        public class MyMBW implements MessageBodyWriter<A> {
                @Override
                public void writeTo(A a, Class<?> type, Type genericType,
Annotation[] annotations,
                                MediaType mediaType, MultivaluedMap<String,
Object> httpHeaders,
                                OutputStream entityStream) throws
IOException, WebApplicationException {
                        /*
                         * When rendering instance of 'A' then reference
'b_ref' shall get replaced
                         * by '.../demo/b/1' in this demo application!
                         *
                         * As MyMBW is provided by a third party vendor, it
can neither know
                         * (1) what URI pattern is used in this application
/ resource for 'GET B',
                         * (2) nor whether 'b_ref' actually is intended by
the application vendor to be a structural link or not,
                         * which can be tricky in case multiple
alternative MBW (e. g. JAXB vs. JSON-B) are to be used with
                         * the same data model.
                         * (3) nor what @ApplicationPath or resource's @Path
are.
                         *
                         * Hence a JAX-RS API is needed which is neutral
w.r.t to vendor of MyMBW, data format, and
                         * application. This API will...
                         * (1, 3) allow the MBW to 'lookupLink(Object,
params);', which returns link of ".../demo/b/1"
                         * taken from that resource method in this
application which has '_at_GET' and returns 'B'.
                         * (2) allow the MBW to identify those references in
the model which are to be rewritten without
                         * enforcing MBW-specific annotations in the
data model.
                         */
                        Link b_link = JAXRS.lookupLink(a, a.b_ref.b_id); //
link effectively is ".../demo/b/1" now!
                        // 'b_link' is written to stream instead of 'b_ref',
e. g. JAXB can be used with custom adapter!
                }
        }
        
        public class MyMBR implements MessageBodyReader<A> {
                @Override
                public A readFrom(Class<A> type, Type genericType,
Annotation[] annotations,
                                MediaType mediaType, MultivaluedMap<String,
String> httpHeaders,
                                InputStream entityStream) throws
IOException, WebApplicationException {
                        /*
                         * When parsing document 'A' then URI '.../demo/b/1"
has to be replaced by instance of B.
                         *
                         * The problems for MBR are the same as for MBW.
                         *
                         * Hence a JAX-RS API is needed which allows...
                         * (1, 3) to forward URI to JAX-RS for resolution
without a complete network stack loopback roundtrip
                         * (2) to identify those references in the data
model which are URIs and shall be replaced by Java object
                         */
                        return new A(JAXRS.lookupObject(b_link)); // returns
instance of 'B' produced by implicit invocation of 'get_b(1);'
                }
        }

        @GET @Path("a/{a_id}")
        public A get_a(@PathParam("a_id") int a_id) {
                // MyMBW replaces instance of B by URI '.../demo/b/1'
                return new A(a_id, new B(1));
        }
        
        @PUT @Path("a/{a_id}")
        public void put_a(@PathParam("a_id") int a_id) {
                // MyMBR replaces URI '.../demo/b/1' by instance of B.
                ...
        }
        
        @GET @Path("b/{b_id}")
        public B get_b(@PathParam("b_id") int b_id) {
                // Client's MBR will invoke 'conditional GET' when replacing
URI by instance of B.
                return new B(b_id);
        }
        
        @PUT @Path("b/{b_id}")
        public void put_b(@PathParam("b_id") int b_id) {
                // Client's MBW will invoke 'conditional PUT' when replacing
instance of B by URI.
                ...
        }
}

---snip---

I think the comments expain pretty well how it works. Our particular MyMBW /
MyMBR utilizes JAXB's XmlAdapter to exchange objects with URIs and vice
versa, and it works on both, client and server side. But as I said before:
It is our particular data format, so it is _not_ a generic XML solution, as
we must know how the syntax for links is like. Anyways, it pretty well
depicts the demand on behalf of a structural links API.

What the API cannot do is -unfortunately- simplify client programming:
Unless JAX-RS makes WADL discovery mandatory, the client cannot know the URI
patterns needed. So the proposal is a first step for server side only.

I assume that Casey's solution works similar and would benefit from the
proposed annotation and lookupLink / lookupObject methods in the same way.

If there are questions, just ask. :-)

Regards
-Markus


-----Original Message-----
From: Santiago Pericas-Geertsen [mailto:Santiago.PericasGeertsen_at_oracle.com]

Sent: Montag, 15. Dezember 2014 16:14
To: jsr370-experts_at_jax-rs-spec.java.net
Subject: Re: Hypermedia API

Markus,

 I have a lot of questions about the proposal, but I feel most can be
answered if you translate your ideas into a sample application. Assuming
what you're proposing is available in JAX-RS, how would your application
look like? Could you provide a sample app?

-- Santiago

On Dec 15, 2014, at 7:38 AM, Markus KARG <markus_at_headcrashing.eu> wrote:

> Sergey,
>
> yes and exactly at that point we'd like to give the data model
> designer an annotation at hand which marks that field as an injection
> point for the actual URI at runtime. That's the sole idea of the
> proposed API. :-)
>
> Regards
> -Markus
>
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
> Sent: Montag, 15. Dezember 2014 11:25
> To: jsr370-experts_at_jax-rs-spec.java.net
> Subject: Re: Hypermedia API
>
> Hi Markus
>
> What I meant is that data model designers may not necessarily need the
> help of JAX-RS in order to design the data representations that can
> accommodate links.
> Example, a data designer wishing for a given piece of data have a link
> would add a field such as href, etc... May it is oversimplifying it...
> Cheers, Sergey
> On 15/12/14 09:46, Markus KARG wrote:
>> It is not as simple as you say. You're right that for XML and other
>> generic syntax there cannot be a generic entity provider. Hence, a
>> generic XML entity provider will not be able to fulfil the
>> application author's wish, obviously. But in that case, the request
>> is invalid, as it relies on the false assumption that there can be a
>> generic solution with pure XML. XML cannot do magic tricks, hence JAX-RS
cannot.
>> Certainly the proposed API makes only sense for "valid wishes", i. e.
>> the application assembler co-bundles entity providers (one or many)
>> which are non-generic, i. e. are written according for particular XML
>> schemas (hence not generically
>> @Produces("application/xml") but partcularly
>> @Produces("application/xml+foobar") for example, where "foobar" is a
>> link-aware schema. I understand that for JAX-RS _implementation
>> vendors_ this looks like a rather seldom case, but from the view of a
>> JAX-RS _application vendor_ and _extension vendor_ this is my daily
>> work,
> actually.
>>
>> You're pretty right that this API is only good for the data model
>> designers, absolutely. But I am representing these people in this
>> expert group. JAX-RS is not only about SPI topics (which are
>> essential for JAX-RS implementation
>> vendors) but to a great extend is an API for application vendors. :-)
>>
>> -----Original Message-----
>> From: Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>> Sent: Sonntag, 14. Dezember 2014 21:30
>> To: jsr370-experts_at_jax-rs-spec.java.net
>> Subject: Re: Hypermedia API
>>
>> Hi Markus
>> On 12/12/14 18:34, Markus KARG wrote:
>>> This is correct, hence it is impossible to have a generic solution,
>>> but need support by Entity Providers. As Entitiy Providers are aware
>>> of the abilitiy how to merge structural links, they -and only they-
>>> can decide about the sole correct way to add them at time of coding
>>> and how to resolve them at time of decoding.
>>>
>> The above is a conflicting statement. A solution involving the entity
>> providers can not qualify as a generic solution because the providers
>> have no idea about the schema constraints possibly applied to a
>> representation to be produced from a given bean.
>> This solution can work in some cases where no schemas are involved or
>> a consumer does not care about the validation or when schemas are
>> designed to allow the extra content. But it is not a generic solution.
>> To be honest I do not expect such solutions to become mainstream.
>>
>> It is really about people designing the data model, the one meant for
>> the external consumption, with the links in mind, auto-augmenting the
>> existing data can be interesting but does not appear to be something
>> 2.1 should be spending much time on
>>
>> Sergey
>>
>>
>>
>>
>>
>>> -----Original Message-----
>>> From: Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>>> Sent: Donnerstag, 11. Dezember 2014 22:24
>>> To: jsr370-experts_at_jax-rs-spec.java.net
>>> Subject: Re: Hypermedia API
>>>
>>> The problem with auto-augmenting XML with links is that it can
>>> produce non valid XML, schema - invalid. A corresponding schema
>>> instance (and for most serious applications there will be a schema)
>>> may not be open enough for a given XML instance to include extra
>>> attributes or elements representing the links.
>>> Sorry if I misunderstood
>>>
>>> Sergey
>>> On 11/12/14 21:02, Markus KARG wrote:
>>>> I do not see how JSON-LD is any better than XML based links, as it
>>>> doesn't solve the root problem: In the end it plays no role whether
>>>> the document syntax is JSON or XML. The problem is the missing API.
>>>> To make structural links work, there must be standard annotations
>>>> in the entity POJOs, and the entity providers must process them,
>>>> and the spec must unambiguously tell how. Yes this is tough, but I
>>>> think that shouldn't be an excuse for not standardizing it. Rather
>>>> we should concentrate on the question whether we _want_ standardize
>>>> structural links or not, and in case we do, who provides the RI for
>>>> that, as possibly Casey has something which can be built upon, and
>>>> implementing it won't be cheap, and it has to be done by _all_
>>>> JAX-RS
>> vendors.
>>>>
>>>> So my question to the spec leads and vendors is: Shall we really go
>>>> on with discussing structural links, or is it simply out of scope
>>>> of JSR 370? Frankly, I would love to have structural links API, but
>>>> I certainly respect it if none of the vendors wants to pay that. In
>>>> the end, a standardization should standardize existing products,
>>>> not enforce _all_ vendors to build something made up synthetically
>>>> from
>> scratch.
>>>>
>>>> *From:*Santiago Pericas-Geertsen
>>>> [mailto:Santiago.PericasGeertsen_at_oracle.com]
>>>> *Sent:* Donnerstag, 11. Dezember 2014 20:47
>>>> *To:* jsr370-experts_at_jax-rs-spec.java.net
>>>> *Subject:* Re: Hypermedia API
>>>>
>>>> Casey,
>>>>
>>>> Yes, structural links in entities is not something that JAX-RS
>>>> provides any "special" support for (in some cases, people have
>>>> included them in headers, but it is arguably less clean).
>>>>
>>>> The reason why JAX-RS hasn't done much (other than the JAXB Link
>>>> serialization bit) is that JAX-RS has not been, and likely never
>>>> will be, in the business of (structured) entity serialization; it
>>>> delegates to specific JSON and XML libraries for that. Clearly this
>>>> is an issue for link processing, but the architectural decision of
>>>> not duplicating existing APIs is certainly sound.
>>>>
>>>> As you point out, JAX-RS would need some additional meta-data to
>>>> "learn" about these links in representations. However, this needs
>>>> to be done without introducing unnecessary coupling and in a
>>>> standard manner --that is, not in a way that would require using a
>>>> JAX-RS implementation for it to work. This is a difficult problem to
solve.
>>>>
>>>> JSON-LD [1] is a step in the right direction, especially since
>>>> becoming a W3C recommendation. Not having full control of the
>>>> serialization is still an issue for us, but perhaps there's
>>>> something we can do working with the new JSON-B EG.
>>>>
>>>> -- Santiago
>>>>
>>>> [1] http://www.w3.org/TR/json-ld/
>>>>
>>>> On Dec 11, 2014, at 1:43 PM, Casey Lee <cplee_at_nektos.com
>>>> <mailto:cplee_at_nektos.com>> wrote:
>>>>
>>>>
>>>>
>>>> I agree, Markus that the issue here is the technical infrastructure
>>>> (or lack of) around HATEOAS has limited its adoption and
>>>> understanding. Specifically, the limitation is with the fact that
>>>> the links we currently have with JAX-RS 2.0 are only transitional
>>>> links in the HTTP header, but no support for structural links in
>>>> the
>> Entity.
>>>>
>>>> I feel the issue is that the current API is all about RESOURCES,
>>>> which causes server side developers to focus more on the URIs than
>>>> on the REPRESENTATIONS. Additionally, this has leaked into the
>>>> client API, causing the client side developer to also have an
>>>> awareness of the resources, which limits the need to think about
>>>> links or at best makes the links optional.
>>>>
>>>> Is there an opportunity to evolve the API to enable adding (server
>>>> side) and retrieving (client side) Links from the Entity? One
>>>> approach would be by annotating your Entity POJOs where Links would
>>>> be added. This would allow some declaration of the structural (and
>>>> possibly transitional) links for the representation.
>>>>
>>>> This would cause developers (client and server side) to begin to
>>>> think about links and the structure/relationships of the
> representations.
>>>>
>>>> At our organization, we've developed our own sets of annotations
>>>> for declaring the structure of your representations and associating
>>>> them to a media type. All of our documentation and the API that
>>>> the client uses is based on the following:
>>>>
>>>> * Follow a link
>>>> * Get back a representation
>>>> * Find a link in the entity
>>>> * Repeat
>>>>
>>>> This causes us to spend most of our effort describing the media
>>>> types, and very little if any effort describing the URIs.
>>>>
>>>> -Casey
>>>>
>>>> On Wed, Dec 10, 2014 at 1:36 PM, Markus KARG
>>>> <markus_at_headcrashing.eu <mailto:markus_at_headcrashing.eu>> wrote:
>>>>
>>>> Santiago,
>>>>
>>>> you asked for statements on the field of hypermedia and reactive. I
>>>> will take the chance to start discussion hereby on the field of
>>>> hypermedia and provide a starter for reactive in a separate thread.
>>>>
>>>> Some weeks back I gave a lecture on JAX-RS 2.0 big picture at JUG
>>> Stuttgart,
>>>> just as I did infrequently at other events before. I'd like to
>>>> describe
>>> the
>>>> reactions as those were stereotypical, independent of audience,
>>>> location
>>> and
>>>> date. People where convinced by the very clean separation of
>>>> concerns (application made up from pure domain objects, technical
>>>> aspects separated from domain model), and the mostly declarative
>>>> programming style (simply adding annotations to declare needs,
>>>> engine solves the needs "under the hood" using a sophisticated and
>>>> extensible technical infrastructure). But when the presentation
>>>> came to hypermedia support, they were some kind of shocked by the
>>>> mostly algorithmic coding style needed to make it work, voiding the
>>>> aforementioned separation of concerns and declarative code style.
>>>> While the existing API clearly is a foundation to achieve at least
>>>> "something", real HATEOAS becomes a hack with the existing low
>>>> level
>>> support
>>>> only. Code gets cluttered with old-style techno-punk, which is hard
>>>> to
>>> read
>>>> and understand. This is due to the lack of a declarative way to
>>>> tell the infrastructure how to make up the links from application
>>>> domain state, and how to provide the links to an entitiy provider
>>>> so he can merge them into the wire-level representation. Certainly
>>>> everbody would vote for a declarative kind of solution fitting into
>>>> the existing infrastructure. On the other hand, nobody (yes, really
>>>> zero) people wanted to agree that they have a REAL NEED for HATEOAS
>>>> (hence, neither for an explicit HATEOAS API)
>>> as
>>>> 100% of all attendees admitted that their recent and current
>>>> RESTful projects are on level 1 or 2 of the REST Maturity Model
>>>> only, and that the largest obstacle to level 3 is not a techical
>>>> issue (hence not a missing explicit HATEOAS API) but the fact that
>>>> HATEOS as a paradigm simply is not well understood by most of them
>>>> and / or they do not see the actual
>>> benefit
>>>> of HATEOAS in the real world: It wouldn't pay off, but it would be
>>>> cool,
>>> to
>>>> sum it up.
>>>>
>>>> So the question is: Is HATEOAS commonly understood well enough that
>>>> it
>>> makes
>>>> actual sense to provide an explicit API for it, or does it make
>>>> sense to make an API even when it is not? And if we define an API,
>>>> do we all agree that it should support the separation of concerns
>>>> and declarative style
>>> that
>>>> is typical for JAX-RS?
>>>>
>>>> I think without an agreement on that general topics, it wouldn't be
>>>> a good idea to discuss any kind of details of API proposals in the
>>>> area of
>>> HATEOAS.
>>>>
>>>> Bill and Sergey, what's your opinion on that?
>>>>
>>>> Regards
>>>> -Markus
>>>>
>>>>
>>>> -----Original Message-----
>>>> From: Santiago Pericas-Geertsen
>>> [mailto:Santiago.PericasGeertsen_at_oracle.com]
>>>>
>>>> Sent: Mittwoch, 10. Dezember 2014 20:03
>>>> To: jsr370-experts_at_jax-rs-spec.java.net
>>>> <mailto:jsr370-experts_at_jax-rs-spec.java.net>
>>>> Cc: Marek Potociar
>>>> Subject: Welcome to the JAX-RS 2.1 EG
>>>>
>>>> Hello Experts,
>>>>
>>>> Welcome to the JAX-RS 2.1 (JSR 370) expert group!
>>>>
>>>> This is the official mailing list for the JSR. Note that the old
>>>> mailing list for JAX-RS 2.0 (JSR 339) is still available for 2.0
> matters.
>>>>
>>>> Before we start any discussions, I would like everyone to take a
>>>> couple of minutes and read the JSR description one more time to
>>>> make sure we are all on the same page ;)
>>>>
>>>> ===
>>>> 2.1 Please describe the proposed Specification:
>>>>
>>>> Server-Sent Events (SSE) is a new technology defined as part of the
>>>> HTML5 set of recommendations for a client (e.g., a browser) to
>>>> automatically get updates from a server via HTTP. It is commonly
>>>> employed for one-way streaming data transmissions in which a server
>>>> updates a client
>>> periodically
>>>> or every time an event takes place.
>>>>
>>>> JAX-RS 2.0 introduced the notion of asynchronous processing for
>>>> both the client and the server APIs. However, asynchronous
>>>> processing alone cannot deliver on all the promises of a modern
>>>> architecture without the help of non-blocking I/O. If only blocking
>>>> I/O is available, asynchronous
>>> processing
>>>> simply pushes the problem from one thread to the next --this is
>>>> akin to borrowing from a person to pay another, the problem is not
>>>> really solved, only deferred. Thus, support for non-blocking I/O is
>>>> necessary to achieve high throughput and efficiently manage
>>>> resources
>> like threads.
>>>>
>>>> In summary, the following is a list of the tasks in scope for
>>>> JAX-RS
> 2.1:
>>>>
>>>> * Adding support for SSE.
>>>> * Improving integration with CDI.
>>>> * Exploring support for non-blocking I/O in providers (filters,
>>>> interceptors, etc.).
>>>> * Evaluating ways in which declarative security can be supported
>>>> either directly in this JSR or by leveraging other EE-platform JSRs.
>>>> * Making JAXB conditional on runtimes where it is available.
>>>> * Providing integration with JSON-B.
>>>> * Building upon the hypermedia API added in version 2.0.
>>>> * Investigating the reactive programming paradigm as a way to
>>>> improve the JAX-RS asynchronous client API.
>>>> * Evaluating any requirements necessary to support the use of
>>>> JAX-RS resource classes as controllers in the MVC 1.0 JSR.
>>>> ===
>>>>
>>>> Some useful links:
>>>>
>>>> [JSR] https://www.jcp.org/en/jsr/detail?id=370
>>>> [JAX-RS Spec] https://jax-rs-spec.java.net/ [JIRA for 2.1]
>>>> https://java.net/jira/browse/JAX_RS_SPEC/fixforversion/16402/
>>>> [RI] https://jersey.java.net/
>>>> [E-mail Archives] https://java.net/projects/jax-rs-spec/lists
>>>>
>>>> As before, all of our discussions will be conducted using the
>>>> expert's alias and (automatically) CCed to the user's alias.
>>>>
>>>> Some of the 2.1 tasks above require coordination with other
>>>> specifications (JSON-B, Security), so these tasks will tackled
>>>> later on
>> in the process.
>>>>
>>>> We have tentatively selected 2 topics to start our discussions,
>>>> both of which require some investigation, these are: hypermedia
>>>> improvements and reactive programming. If you have any
>>>> suggestions/comments/concerns about these two topics, feel free to
>>>> start a discussion about them. We will be sending some more info as
>>>> well
>> in the upcoming weeks.
>>>>
>>>> Looking forward to working with all of you!
>>>>
>>>> --
>>>> Santiago Pericas-Geertsen
>>>> Marek Potociar
>>>> JSR 370 Spec Leads
>>>>
>>>>
>>>
>>>
>>
>>
>
>