Thanks for a very comprehensive answer, Heiko.
I'll try to explain myself better and put some comments inline below...
On Monday, January 14, 2013 17:50:32 Heiko W.Rupp wrote:
Lukas,
it took me a while to think through your email(s) and I think I
misunderstood especially the first one.
Before I continue let me first point out why the REST-api matters a lot to
me:
The users of RHQ are (supposed to be) administrators that want to manage
the servers and systems in their data center. They need to integrate RHQ
with other existing systems like trouble ticket systems or existing
dashboards. Many if not all those administrators write shell, perl, Ruby or
Python scripts fluently as part of their daily work. They usually do not
write Java code. And all of those languages have http clients and can thus
access the REST-api. A Rest-api can also be accessed from clients e.g. on
an iPad that are written in Objective-C.
I fully support that view and never meant to hint that REST wasn't a top
priority for us. I actually do think it is more important than remote EJBs but
at the same time I do think that that is not a reason for making the
established remote EJB API (and therefore CLI) a second class citizen. Please
read below for more details on this.
While I see the discrepancy between Rest and Ejb-Api, I do not think
that
users will be confused as we also offer different functionality in the UI
and the CLI.
That's where we differ :) IMHO, the choice of the interface to RHQ should be
based on technological merits, not on the functionality each interface happens
to offer.
> We could deprecate the remote EJB API, but I'd find it quite
sad. If we
> based REST on remote API right from start, we could have had 2 interfaces
> to RHQ for free
This is only partially true, as some of the code (take the
AlertDefinitionManagerRemote as example) of the Remote-Api is not enough to
support the current developments in the Rest-Api. So adding more methods
("the same as in the Rest-api", but see below) in the Remote-Api would be
possible, but would also require more testing of that code path, which is
doable, but not free. On top of that, some methods of the internal api are
hard to use as I had to learn over the previous days, so just exposing
those internal methods to all remote clients will not be enough either.
Well, that is exactly what my original email was supposed to be about. IMHO,
while the path of expanding/modifying the remote EJB API is not free and would
definitely require more work, we would be in a better place if we used it for
REST.
The reason for that is that REST is a great test-bed for the underlying API
from the usability point of view (as you also correctly point out). So basing
REST on remote EJBs would, IMHO, be killing two birds with one stone so to
speak. On one hand we'd create a new interface to RHQ (REST) and on the other
hand would make the remote EJB API more complete and maybe even slightly more
usable.
> For this I think that ideally REST should exclusively use the
remote EJBs
> to achieve its thing
I originally understood this in a way that the Rest-Api should only use the
existing Remote-Api; this would clearly not work as the Remote-Api is not
rich enough as just said.
The other way around (exposing all Rest-Api methods via @Remote) would not
work either, as technical parameters that are needed in the Rest-Api
(http-headers, uri info, ..) would not be available via Remote
Ejb-interfaces and also the 'Response' return type that contains payload +
additional information like is the response cacheable or should it be
gzipped on the transport layer etc. would not make a lot of sense on the
Ejb-side.
On top of that is that due to the nature of the Jax-RS setup, entities are
marshaled into the actual data that is transported over http, at the
web-layer and thus outside of the boundaries of EJB-Transactions and the
entity manager. This means that the domain objects as they stand will throw
lazy-load exceptions or need to be "pre-filled". We do have the
SerialUtility for this purpose in the direction of the UI, that could be
used. When I started the Rest-effort I have decided against the
core-domain objects for those reasons:
- be on the save side wrt lazy loading (may be void with the serial utility)
- be able to cut "rest-domain" objects in a way that possible is better
suited to be exposed via the rest-api. Take for example our Resource
object, that has many relations to many other objects. Some of that linked
data should be exposed in a ResourceRest object, while other information
should not -- or in a different way (e.g. a hyperlink)
- I did not want to make changes to core-domain objects, which are used all
over the place and where a simple change may have big effects (serial
compatibility, db-changes, db-update procedure, db-load times due to
(non-)caching effects).
And then Rest is about state transfer, as the acronym REST says (and also
about discoverability and linking). A more classical, procedural api is
rather about "do something".
E.g. in a classical api you may find a method:
Schedule.enableDisable(boolean enabled);
In the Rest-world you would rather do the equivalent of on the client
Schedule s = restClient.get(".../schedule/12345");
s.enable();
restClient. put(".../schedule/12345");
Imposing that style on procedural apis would feel awkward. On the
REST-side, there is a rule of thumb - if your URI contains a verb
("enable" in above example), then you are doing it wrong.
Yep, exposing the REST interfaces as @Remote's wouldn't make sense.
> Perhaps the remote CLI could be retrofitted to use REST under
the covers??
While this is doable, it would require a lot of coding in the CLI under the
covers to offer the current functionality of the current CLI, so I am not
sure if that is feasible just for the sake of unification.
Agreed, backwards compatibility would be hard because the APIs are just too
different - and for a good reason. But as I said in my original email - while
the REST and EJB APIs differ (i.e. state-transfer vs. procedural approach), the
user should, IMHO, be able to achieve the same using both APIs - even if in
completely different ways.
> I would call it a failure on our side if we dropped/deprecated
remote EJB
> API
I don't think we should drop it - and this was never the question for me.
So while I think it makes sense to expose some functionality that is right
now encoded in the Rest-Api as methods in theEjb-Api (e.g setting a
baseline for a schedule), I do not think this generally a good direction.
This is another area where I again with you. I strongly believe, as I pointed
out above, that all of our interfaces (GUI, REST, remote EJB) should offer the
same functionality (obviously in different programming/usage styles - GUI is
clickable, REST is state transfer and EJBs are procedural). Obviously it is
not the case today but I think it is a goal we should strive for. The reason
for that is purely usability - when a user wants to interact with RHQ, s/he
should not be forced to study our different interfaces (REST, EJBs (by which I
also mean CLI)) and figure out if what they want to do is possible in one of
them. They should just pick an interface that is most comfortable for them and
go with it.
My suggestion of using remote EJBs in REST exclusively would bring one benefit
- this would mean that we can always answer the question of how to do stuff
using remote EJB API that you can do in REST - because we would be doing it
ourselves that way ;)
Thinking about this, I can see that there might be cases where exposing some
methods that basically serve as a support for the "translation" from the state
transfer approach of REST to the procedural world of EJBs wouldn't make sense
in remote EJB API - i.e. we'd better not expose those helpers directly but
have another remote EJB method that would provide a similar functionality in a
more procedural manner.
So maybe using remote EJBs in REST exclusively wouldn't be possible after all
(I don't know - that is something you can answer much better) and there would
have to be exceptions to that rule. But that doesn't make my point much weaker
- right now we have a growing feature gap between our interfaces. I think it
should be our priority to close that gap as quickly as we can otherwise it is
going to be a nightmare to a) try to close it later and b) explain to users
why they made a bad choice when they chose a particular interface to RHQ.
Hope that answers some of your questions.
Heiko