Skip to main content

[jsr339-experts] Re: HEADS-UP, IMPORTANT: Problems with JAX-RS interceptors

  • From: Sergey Beryozkin <sberyozkin@...>
  • To: <jsr339-experts@...>
  • Subject: [jsr339-experts] Re: HEADS-UP, IMPORTANT: Problems with JAX-RS interceptors
  • Date: Thu, 26 Apr 2012 15:52:57 +0100

Hi

Please see comments at the end of the message
On 26/04/12 13:29, Marek Potociar wrote:
Hello all,

As we started to look more closely into implementing support for JAX-RS
Interceptors API in Jersey, we ran into several major issues. It seems,
that there are serious questions around the interaction between filters
and interceptors. This is IMO to a large extend caused by the
functionality overlap between the interceptors and filters (applies to
both filtering API proposals - the old one as well as the new one).

A very brief summary of the concept: Interceptors form a wrapping chain
and are supposed to intercept calls to entity providers (MBR/MBW)
whenever the entity is read or written either by the client, resource
method or a filter. Filters form an un-wrapping chain and filter every
request and response send or received. Unfortunately, it seems that the
two concepts just don't work well together the way they are designed.

Here is the list of the issues and open questions that we identified so far:

   1. Name-bound interceptors seem to clash with pre-matching filters.
      If a pre-matching filter will try to manipulate the entity, the
      name-bound interceptors would not get invoked, which may be fatal
      (see Example 1).
   2. The generic type information on the interceptor seems redundant.
      It is not clear what should the runtime do when an interceptor is
      configured for a type that it does not support in it's generic
      type declaration.
   3. The reader interceptors are now not restricted in any way wrt.
      changing the returned entity Java type to a type that is
      incompatible with the Java type requested by the caller (either
      JAX-RS runtime or an interceptor up in the chain). Changing the
      type of the returned entity in a non-compatible way seems to
      always have fatal consequences as, by definition, the caller
      expects to receive the original type it asked for.
   4. Filters may un-intentionally corrupt the entity stream in
      applications configured asymmetrically wrt. interceptors (see
      Example 2)


A couple of examples to demonstrate the issues:

    * /Example 1: //Interceptors interfere with filters reading/writing
      entity - named interceptors/

    /
    /
    /
    Suppose the successful reading requires a special named interceptor
    attached to a resource method.
    How do we guarantee that the entity can be read in a pre-matching
    filter?
    /
    /
    /

    * /Example 2: Interceptors interfere with filters reading/writing
      entity - asymmetrical configuration/


    Suppose a filter wants to replace an entity using writeEntity
    method. Suppose a special (inbound) reader interceptor is configured
    in the interceptor chain (e.g. signature verifier), but there is no
    (outbound) writer interceptor counterpart (e.g. signature appender).
    How do we guarantee that the entity written by the filter will be
    readable again? Note that not having a corresponding outbound
    (signature appender) interceptor configured for the request is a
    valid and justifiable use case. Even worse, the corresponding
    outbound functionality can be, in general, provided by an outbound
    filter instead of an interceptor, which will obviously not get
    invoked as part of the writeEntity method.


We haven't found any reasonable way to resolve the outlined issues
without changing the API. Here are couple of options for a solution we
can see:

    * /Option 1/
          o interceptors should not be typed, should be stream focused -
            i.e. could be renamed to Input/OutputStreamInterceptors
                + people should use MBW and/or filters for entity
                  type-dependent manipulation
          o interceptors should only be global (as they may need to be
            invoked in the pre-matching phase)
          o interceptors should be executed just once per
            request/response when reading from/writing to the wire, not
            for intermediate transformations (hence calling it MBW
            interceptors may be misleading)
          o filters should work with entities (decoded) - with one
            possible kind of entity being a stream
                + drop the get/setEntityStream methods as redundant (or
                  keep them just as convenience shortcuts for
                  read/writeEntity counterparts)

Option 1 seems to allow the interceptors to be reused between client and
server side. But not sure if this is not only useful in a very limited
set of use cases (e.g. real life may show that in most cases a server
and client-side implementation may need to be separate anyway due to the
need of attaching/checking different headers on the client side than on
the server side etc.).

    * /Option 2/
          o completely remove interceptors, have just filters
          o filters are more versatile and can wrap the input/output
            stream by the way of calling get/setEntityStream() - which
            covers the functionality separated out into interceptors

Option 2 stream-lines the API and makes it easier to understand by the
end user as it removes the need to take the two different concepts into
account when writing a filter or interceptor or make decisions about
whether the intended functionality belongs to a filter or an interceptor
or a combination of the two.

This option2 seems like a good candidate. I'm a bit confused at the moment by the necessity to have MBRs & MBWs (basic interceptors, especially MBWs which can update the response headers), filters and interceptors. Having only in/out filters on client/server sides, in addition to existing MBRs and MBWs seems ideal, assuming it is possible to refactor filters such that can also manage what interceptors can do now.

I'll try to provide a more specific feedback in the next few days,

Cheers, Sergey


Please, let us know what is your preferred solution for the issues. We
need your feedback ASAP as we plan to postpone the EDR3 release a week
or two so that we can release a solid filtering API proposal.

Thank you.

Marek & Santiago


[jsr339-experts] HEADS-UP, IMPORTANT: Problems with JAX-RS interceptors

Marek Potociar 04/26/2012

[jsr339-experts] Re: HEADS-UP, IMPORTANT: Problems with JAX-RS interceptors

Sergey Beryozkin 04/26/2012

[jsr339-experts] Re: HEADS-UP, IMPORTANT: Problems with JAX-RS interceptors

Bill Burke 04/26/2012

[jsr339-experts] Example 3: Why current ReaderInterceptors are cool.

Bill Burke 04/26/2012

[jsr339-experts] Re: Example 3: Why current ReaderInterceptors are cool.

Sergey Beryozkin 04/27/2012

[jsr339-experts] Re: Example 3: Why current ReaderInterceptors are cool.

Sergey Beryozkin 04/27/2012

[jsr339-experts] Re: Example 3: Why current ReaderInterceptors are cool.

Bill Burke 04/27/2012

[jsr339-experts] Re: Example 3: Why current ReaderInterceptors are cool.

Sergey Beryozkin 04/27/2012

[jsr339-experts] Re: Example 3: Why current ReaderInterceptors are cool.

Bill Burke 04/27/2012

[jsr339-experts] Re: Example 3: Why current ReaderInterceptors are cool.

Marek Potociar 04/27/2012

[jsr339-experts] Re: HEADS-UP, IMPORTANT: Problems with JAX-RS interceptors

Bill Burke 04/26/2012

[jsr339-experts] Re: [jax-rs-spec users] Re: HEADS-UP, IMPORTANT: Problems with JAX-RS interceptors

Marek Potociar 04/27/2012
 
 
Close
loading
Please Confirm
Close