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 12:10:12 +0000

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 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
>>> <mailto: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
>>> <mailto: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?
>>>
>>>
>>>
>>>
>>
>>
>