users@jax-rs-spec.java.net

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

From: Bill Burke <bburke_at_redhat.com>
Date: Wed, 17 Dec 2014 08:52:32 -0500

Are you automatically expanding URI links into data when reading (MBR)?
  And automatically linking when writing (MBW)? BTW, this
resolving/building of links could be done in a
Writer/ReaderInterceptor.What I don't understand is how is the container
supposed to resolve/build links. There's not enough metadata in your
example and the container would have to guess which methods to use to
expand/build the link.

I think some facility to automatically create links when marshalling
might be useful. We had a contributor build something for us, but I was
never completely satisfied with it. [1]. Honestly though I found that
I'd rather just build the links by hand. We've had this feature for
years and I've rarely gotten a question on it. Also, as I've said
before, Hypermedia/linking is pretty much ignored by app developers.
Some of the REST talks I've been to over the years suggest that it is
not a very popular "feature" of REST.

As far as automatically expanding links? I'm really not convinced it
would be useful and is a real edge case.

This does make me think it might be interesting to include the opposite
of a UriBuilder...a UriParser in the specification.

On 12/16/2014 12:41 PM, Markus KARG wrote:
> 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
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>

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