jsr370-experts@jax-rs-spec.java.net

Re: [jax-rs-spec users] SSE Draft

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Tue, 3 Nov 2015 21:28:07 +0000

https://github.com/mpotociar/api/blob/46d81cf3c5826f62e5824d5330fa4d59ffa0d98f/examples/src/main/java/jaxrs/examples/sse/ServerSentEventsResource.java#L103
(1)

Replace @Produces(text/event-stream) with Produces(application/json) and
add @SSE and that works neatly, otherwise if we keep
@Produces(text/event-stream) there and have Produces(application/json)
at this level

https://github.com/mpotociar/api/blob/46d81cf3c5826f62e5824d5330fa4d59ffa0d98f/examples/src/main/java/jaxrs/examples/sse/ServerSentEventsResource.java#L62
(2)

then when I do

https://github.com/mpotociar/api/blob/46d81cf3c5826f62e5824d5330fa4d59ffa0d98f/examples/src/main/java/jaxrs/examples/sse/ServerSentEventsResource.java#L112
(3)

(but use MyBean instead to be serialized as JSON) the class level
Produces(application-json) (ref (2) above) it will be ignored and the
only way to set application/json is to use the builder.

Sergey

On 03/11/15 16:55, Santiago Pericasgeertsen wrote:
>
>> On Nov 3, 2015, at 4:10 AM, Sergey Beryozkin <sberyozkin_at_talend.com
>> <mailto:sberyozkin_at_talend.com>> wrote:
>>
>> Hi Santiago
>>
>> So I'm wondering if inserting a special MT would interfere with the
>> regular policy of figuring out what MT should be allocated to a given
>> data piece.
>> Example if I do not use SSE, I can put Produces on Class or on Method
>> or in Response. If we keep depending on a special MT to make a method
>> initiating an SSE output then the only mechanism to set an event data
>> MT is to use a builder, neither Class or Method Produces can be used
>> which would be unfortunate IMHO.
>
> I’m not sure I follow. The MT of the method/class/response is always
> text/event-stream, so indeed any other MT will be supplied while
> constructing each SSE event. Is that what you meant? If not, please
> provide some code :)
>
> — Santiago
>
>>
>> I'm not proposing to block text/event-stream but rather treat it as a
>> technical aspect of implementing SSE, i.e, it is an SSE protocol
>> specific 'demarcation' MT which does not have any relevance to the
>> format of the actual data (referring here to the MT/format used to
>> select JAXRS providers) pushed inside this text/event-stream
>> 'envelope'. Example, having both @SSE for the purpose of marking the
>> method and @Produces for the purpose of specifying the *default* MT
>> for the event data fragments (while letting users override if with a
>> builder if needed) can work well.
>>
>>
>>
>> Sergey
>>
>> On 29/10/15 13:17, Santiago Pericasgeertsen wrote:
>>> Sergey,
>>>
>>> Inlined.
>>>
>>>> My understanding the format of the message is expected to be known
>>>> to the client (example, it is JSON all the time in a known
>>>> representation, etc),
>>>
>>> Yes, there is nothing in the SSE protocol about an event's MT.
>>> There is a single MT returned in the response, and that is
>>> text/event-stream. The reason for the MT proposal is simply so that
>>> JAX-RS can find the correct MBW.
>>>
>>>> I was more curious about the default MT that would be used for
>>>> selecting MBW for serializing a custom event object…
>>>
>>> In my view, this ought to be consistent with the way we handle the
>>> return of an entity in a resource method without an @Produces. In
>>> other words, it should be consistent with the algorithm in Section 3.8.
>>>
>>> — Santiago
>>>
>>>> If a builder media type property is not set then at least for
>>>> String toString() will produce a meaningful message, but a
>>>> Object.toString() should not be allowed to escape if a user forgets
>>>> to set a MT builder property
>>>>
>>>> Sergey
>>>> On 28/10/15 18:55, Markus KARG wrote:
>>>>> Quoted from W3C: <The default event type is "message">.
>>>>> Actually there is problem with MIME and SSE: W3C does not define
>>>>> how to transfer the Content-Type. They do specify that one can add
>>>>> any name to a field (like "content-type") but that name is not
>>>>> mandatory. Without it, our only chance is assuming "String",
>>>>> actually -- even if this means "toString()".
>>>>> *From:*Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>>>>> *Sent:*Mittwoch, 28. Oktober 2015 19:18
>>>>> *To:*jsr370-experts_at_jax-rs-spec.java.net
>>>>> *Subject:*Re: [jax-rs-spec users] SSE Draft
>>>>> Either by the return type or otherwise by something like @SSE,
>>>>> please see the prototype below
>>>>>
>>>>> By the way, this is probably orthogonal, but what is the default
>>>>> MT (for the purpose of selecting MBW) if the event object is not
>>>>> String but say MyEvent.
>>>>> Is toString() a default ? That would work for String but would
>>>>> look not good for custom objects
>>>>>
>>>>> Sergey
>>>>>
>>>>>
>>>>> On 28/10/15 17:59, Markus KARG wrote:
>>>>>
>>>>> Understood. So how to detect SSE then if not by MT? By return
>>>>> type?
>>>>> *From:*Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>>>>> *Sent:*Mittwoch, 28. Oktober 2015 00:26
>>>>> *To:*jsr370-experts_at_jax-rs-spec.java.net
>>>>> *Subject:*Re: [jax-rs-spec users] SSE Draft
>>>>> Or per-event MT approach can still work where, if set, it
>>>>> overrides a method specific Produces, exactly as it works with
>>>>> a regular JAX-RS response.
>>>>> So I guess the only thing I suggest is to make setting
>>>>> text/event-stream implicit and keep Produces for specifying
>>>>> the event format if preferred...
>>>>>
>>>>> Sergey
>>>>> On 27/10/15 23:22, Sergey Beryozkin wrote:
>>>>>
>>>>> Hi Markus, I'm not suggesting to redefine, I'm suggesting
>>>>> to make the way SSE is implemented in JAX-RS a little bit
>>>>> less technical as far as users working with it are concerned ?
>>>>> Re restricting to a single MT for all the events inside a
>>>>> single channel, is it a bad thing ? I'm not sure. We can
>>>>> always assume that in theory it is possible, but lets face
>>>>> it, I doubt anyone can come up with a practical example
>>>>> where multiple MTs are mixed in. In fact supporting
>>>>> per-event MT can be added later on at a builder level if
>>>>> such a freedom of formatting is ever needed...
>>>>>
>>>>>
>>>>> Cheers, Sergey
>>>>> On 27/10/15 22:32, Markus KARG wrote:
>>>>>
>>>>> But Sergey, we only should define an API how SSE can
>>>>> be mapped upon JAX-RS. We cannot redefine how SSE
>>>>> works. And it is simply the W3C that defined that SSE
>>>>> is initiated by sending that particular MT and that
>>>>> each single event can definitively have different
>>>>> entity type. What you propose certainly looks more
>>>>> familiar, but would redefine the W3C-defined semantics
>>>>> of SSE.
>>>>> *From:*Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>>>>> *Sent:*Dienstag, 27. Oktober 2015 23:25
>>>>> *To:*jsr370-experts_at_jax-rs-spec.java.net
>>>>> *Subject:*Re: [jax-rs-spec users] SSE Draft
>>>>> Hi
>>>>>
>>>>> I have to admit I'm still uncomfortable about a
>>>>> specialized Produces(text/event-stream) in this case.
>>>>> I could not figure why until yesterday... Basically
>>>>> this is what the SSE spec requires to accompany the
>>>>> data going to the SSE channel - but it is orthogonal
>>>>> to the act of converting the data into event specific
>>>>> formats such as JSON or plain text.
>>>>> When myself and possibly other users see Produces they
>>>>> think this is the format of the response data.
>>>>> Having an SSE-required MT in a method @Produces does
>>>>> not fit well into a JAX-RS state of 'mind'.
>>>>>
>>>>> Letting people set MT for individual events actually
>>>>> loosens the API - i.e, the API makes it very easy to
>>>>> do what is obviously not meant to be, mixing different
>>>>> formats in a single channel, 1st event is JSON, next
>>>>> is XML. Of course we can say the users needs to know
>>>>> what to do, but it is different from having an API
>>>>> which does not explicitly allows such nonsense
>>>>> operations...In 2.0 one can also do it, say mess up
>>>>> with writing into StreamingOutput - but the user needs
>>>>> to try hard :-)
>>>>>
>>>>> I'd like to return to discussing this idea:
>>>>>
>>>>> @POST
>>>>> @Produces(MediaType.APPLICATION_JSON)
>>>>> public SseEvenOutput startDomain() {
>>>>> }
>>>>>
>>>>> or
>>>>>
>>>>> @POST
>>>>> @Produces(MediaType.APPLICATION_JSON)
>>>>> @SSE
>>>>> public Response startDomain() {
>>>>> }
>>>>>
>>>>> In either case, setting text/event-stream is the
>>>>> responsibility of the runtime, something that will be
>>>>> documented in the spec/API, it is implicit, while
>>>>> @Produces(MediaType.APPLICATION_JSON) represents the
>>>>> format of the every event fragment for a given SSE
>>>>> output channel...
>>>>>
>>>>> Sergey
>>>>>
>>>>> On 22/10/15 16:11, Sergey Beryozkin wrote:
>>>>>
>>>>> Hi Santiago
>>>>> On 22/10/15 15:29, Santiago Pericasgeertsen wrote:
>>>>>
>>>>> Sergey,
>>>>> This is how I reason about media types
>>>>> associated with events. First, sometimes the
>>>>> data associated with an event is structured,
>>>>> most notably these days it’s JSON. JAX-RS
>>>>> already has a facility for mapping Java
>>>>> objects to representations (MBR/MBW) whose
>>>>> selection is based on MTs.
>>>>> This mechanism is there for entities, but it
>>>>> is only natural to see if it can be extended
>>>>> for SSE event data. To do so, you need to
>>>>> specify an MT for the event’s data. If we
>>>>> don’t allow re-usability of this mechanism,
>>>>> we’d either only support string messages or
>>>>> build a completely different mechanism, which
>>>>> seems like an overkill.
>>>>>
>>>>> Sure, +1, indeed reusing MBR/MBW for this is perfect
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> I’m still unsure about interceptors: to me
>>>>> interceptors and MBR/MBW’s are inseparable, but at
>>>>> the same time it’s not clear what advantages they
>>>>> bring in this case.
>>>>> I've no strong opinion right now about it. I can
>>>>> imagine some confusion about the response
>>>>> interceptors/filters meant for processing 'main'
>>>>> HTTP channel responses being also used for
>>>>> filtering sse events, though I can also imagine
>>>>> may me some events being blocked by filters if
>>>>> needed, not really sure right now :-)
>>>>>
>>>>> Sergey
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> — Santiago
>>>>>
>>>>> On Oct 21, 2015, at 4:46 PM, Sergey Beryozkin
>>>>> <sberyozkin_at_talend.com> wrote:
>>>>> Hi Markus - OK, thanks.
>>>>> Still looks like a foreign body, this @Produces...
>>>>>
>>>>> The question about formatting the event data
>>>>> fragments still remains,
>>>>> If we are including MBW then surely not
>>>>> because we need a help with writing String
>>>>> into output stream.
>>>>> Oh, actually.
>>>>>
>>>>> https://github.com/mpotociar/api/blob/master/jaxrs-api/src/main/java/javax/ws/rs/sse/OutboundSseEvent.java#L108
>>>>>
>>>>> So ended up doing some home work after all :-)
>>>>>
>>>>> Sergey
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On 21/10/15 19:05, Markus KARG wrote:
>>>>>
>>>>> Sergey,
>>>>> maybe there is a misunderstanding: The W3C
>>>>> SSE specification clearly says that the
>>>>> initiation of a SSE channel _is_ by
>>>>> declaring a content type of
>>>>> text/event-stream. Hence this is not a
>>>>> marker made up by JAX-RS, but it
>>>>> definitivel _is_ correct according to the W3C.
>>>>> -Markus
>>>>> *From:*Sergey Beryozkin
>>>>> [mailto:sberyozkin_at_talend.com]
>>>>> *Sent:*Mittwoch, 21. Oktober 2015 13:26
>>>>> *To:*jsr370-experts_at_jax-rs-spec.java.net
>>>>> *Subject:*Re: [jax-rs-spec users] SSE Draft
>>>>> Hi Marek
>>>>>
>>>>> Few comments/questions,
>>>>>
>>>>> Re the special MediaType vs the MediaType
>>>>> for individual event writes,
>>>>>
>>>>> How is a Media Type for an event data
>>>>> fragment is specified ?
>>>>> And can we assume that the same MediaType
>>>>> is used for all the event writes ?
>>>>>
>>>>> If it is a single Media Type then I'd
>>>>> object to the idea of a *special* MT,
>>>>> example, if every event write is a JSON
>>>>> payload, why do
>>>>>
>>>>> @POST
>>>>> @Produces(MediaType.SERVER_SENT_EVENTS)
>>>>> public SseEvenOutput startDomain() {
>>>>> }
>>>>>
>>>>> This actually appears to be a bit off the
>>>>> JAX-RS style because we use
>>>>> MediaType.SERVER_SENT_EVENTS as a marker
>>>>> of the method which initiates
>>>>> SseEvenOutput but not the *format* of the
>>>>> response event data chunks, it overloads
>>>>> the concept of Produces IMHO.
>>>>>
>>>>> Should we just have
>>>>>
>>>>> @POST
>>>>> @Produces(MediaType.APPLICATION_JSON)
>>>>> public SseEvenOutput startDomain() {
>>>>> }
>>>>>
>>>>> Which is more in line with a
>>>>> StreamingOutput like pattern ?
>>>>>
>>>>> The runtime can mark startDomain() as
>>>>> needed given the response type is
>>>>> SseEvenOutput and if Response (or
>>>>> AsyncResponse ?) are allowed then
>>>>> we can do
>>>>>
>>>>> @POST
>>>>> @Produces(MediaType.APPLICATION_JSON)
>>>>> @SSE
>>>>> public Response startDomain() {
>>>>> }
>>>>>
>>>>>
>>>>> Thoughts ?
>>>>>
>>>>> Cheers, Sergey
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On 21/10/15 11:42, Marek Potociar wrote:
>>>>>
>>>>> At the same time, it is the spec lead
>>>>> job to steer the EG and the JSR
>>>>> outcome. And since it was me and
>>>>> Santiago who submitted the JSR
>>>>> charter, EG does not need to find
>>>>> interpretations, EG can simply ask the
>>>>> spec leads to provide the explanation. 😉
>>>>> In case of CDI, our intention was to
>>>>> improve the alignment of @Inject and
>>>>> scope support. FWIW, we’re still
>>>>> hoping that CDI 2.0 will become more
>>>>> modularized so that we do not have to
>>>>> formally deal with the whole spec
>>>>> (that becomes more and more bloated by
>>>>> features less and less relevant to
>>>>> “context and dependency injection”
>>>>> problem), only with it’s core pieces.
>>>>> So once, again, our CDI alignment is
>>>>> about aligning the JAX-RS injection
>>>>> support with CDI. It is NOT about
>>>>> integration with CDI eventing (for SSE
>>>>> support or whatever other purpose).
>>>>> Hope the explanation above is clear
>>>>> enough and does not require further
>>>>> interpretation in EG.
>>>>> As for the SSE support, we want to
>>>>> provide a facility that fits well into
>>>>> JAX-RS programming model. And since
>>>>> SSE is really just a (special) media
>>>>> type, the proposed API is building on
>>>>> top of the existing support for entity
>>>>> providers in JAX-RS. So to touch on
>>>>> the questions you raised in more detail:
>>>>> - Yes, we plan to leverage message
>>>>> body readers and writers for each
>>>>> single SSE event. We do not plan to
>>>>> engage Filters and Interceptors with
>>>>> each event, those should only be
>>>>> engaged when the request or response
>>>>> is initiated.
>>>>> - Injectable SseEventOutput is
>>>>> certainly an option to consider. At
>>>>> the same time, we do need to find a
>>>>> way how to provide access to event
>>>>> builder and broadcaster, so rather
>>>>> than injecting three separate things,
>>>>> it so far seems to me simpler to just
>>>>> inject the context and use it to get
>>>>> access to all of the important
>>>>> components. In any case, we can simply
>>>>> look into this further to see what can
>>>>> be done to make the API simpler.
>>>>> - To your comment "/I do not see why
>>>>> creating the SseOutput from an
>>>>> SseContext should be the
>>>>> responsibility of the application
>>>>> programmer./”, my response is that SSE
>>>>> stream is a representation of a
>>>>> resource in the JAX-RS philosophy. So
>>>>> it is only natural that the JAX-RS
>>>>> resources return the new instance of
>>>>> SSE stream from a resource method.
>>>>> That’s the common JAX-RS programming
>>>>> model.
>>>>> - To respond to your item #3, other
>>>>> than my CDI related comments earlier
>>>>> in this email, SSE is a standardized
>>>>> spec with well defined standard APIs.
>>>>> It IMO begs for a dedicated API.
>>>>> Otherwise it would not make any sense
>>>>> to provide a special support for it.
>>>>> It is only good that we can come up
>>>>> with a really small API (8 classes)
>>>>> that fits well the JAX-RS programming
>>>>> model and is tailored to support this
>>>>> technology. SSE is a specific
>>>>> technology that covers important, but
>>>>> again specific use cases. Coming up
>>>>> with some clever abstractions is not
>>>>> going to provide any real user value,
>>>>> I’m afraid.
>>>>> Cheers,
>>>>> Marek
>>>>>
>>>>> On 20 Oct 2015, at 22:53, Markus
>>>>> KARG <markus_at_headcrashing.eu> wrote:
>>>>> Well, according to the JCP bylaws,
>>>>> it is the expert group to define
>>>>> the outcome of the JSR. So it is
>>>>> up to us to interpret the charter
>>>>> as we like. ;-)
>>>>>
>>>>> -----Original Message-----
>>>>> From: Sergey Beryozkin
>>>>> [mailto:sberyozkin_at_talend.com]
>>>>> Sent: Dienstag, 20. Oktober 2015 22:43
>>>>> To:jsr370-experts_at_jax-rs-spec.java.net
>>>>> Subject: Re: SSE Draft
>>>>>
>>>>> Hi Markus
>>>>>
>>>>> I suspect it is about better
>>>>> support for Inject, etc, but not sure
>>>>>
>>>>> Cheers, Sergey
>>>>> On 20/10/15 21:37, Markus KARG wrote:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> If we cannot, why did the JCP
>>>>> accept the JSR 370 charter, which
>>>>> clearly requests CDI integration?
>>>>>
>>>>> -----Original Message-----
>>>>> From: Sergey Beryozkin
>>>>> [mailto:sberyozkin_at_talend.com]
>>>>> Sent: Dienstag, 20. Oktober 2015 22:23
>>>>> To:jsr370-experts_at_jax-rs-spec.java.net
>>>>> Subject: Re: SSE Draft
>>>>>
>>>>> Can a 2.1 (non major version)
>>>>> introduce a strong CDI dep ? MVC
>>>>> is a diff
>>>>> story.
>>>>>
>>>>> Sergey
>>>>>
>>>>> On 20/10/15 16:26, Bill Burke wrote:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On 10/19/2015 5:19 PM, Markus KARG
>>>>> wrote:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> (1) Maybe I missed the code line,
>>>>> but will it be possible to send an
>>>>> entity so MBWs, Filters and
>>>>> Interceptors are getting involved?
>>>>> In the
>>>>> end, we do not write an SSE
>>>>> server, but actually do add SSE to
>>>>> JAX-RS.
>>>>>
>>>>> Like:
>>>>> sseContext.newEvent().name("custom-message").data(myEntity);
>>>>> =>
>>>>> use MBW to stream entity, applying
>>>>> all filters and interceptors that
>>>>> are registered for the resource
>>>>> class that owns this SSE channel.
>>>>>
>>>>> (2) I am not convinced that the
>>>>> complexity is needed. Why is there a
>>>>> SseEventOutput and an SseContext?
>>>>> Can't we simply inject an SseOutput
>>>>> in the resource automatically? I
>>>>> do not see why creating the
>>>>> SseOutput from an SseContext
>>>>> should be the responsibility of the
>>>>> application programmer.
>>>>>
>>>>> (3) I am not convinced that the
>>>>> technology of SSE should also bring
>>>>> with it its own eventing
>>>>> subsystem. Wouldn't it make more
>>>>> sense to
>>>>> rely on CDI events? Using CDI
>>>>> events we could allow events origin
>>>>> from other Java EE components
>>>>> (like JCA, MDB or timed EJBs) to be
>>>>> forwarded in a
>>>>> protocol-transparent way into the
>>>>> JAX-RS container,
>>>>> which then is the only one that
>>>>> has to know that SSE is used to
>>>>> transport the event to the http
>>>>> client. As JAX-RS is an integral part
>>>>> of Java EE, and as SSE is a
>>>>> web-only technology, I don't like the
>>>>> idea that either
>>>>> non-web-components are polluted by
>>>>> SSE, or
>>>>> non-web-events couldn't be
>>>>> forwarded to SSE clients.
>>>>>
>>>>> What would SSE over CDI look like?
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>