[hibernate-dev] [OGM and others] API, SPI and FPI
Emmanuel Bernard
emmanuel at hibernate.org
Thu May 22 12:01:47 EDT 2014
You misread me. I have to plan to change the meaning of SPI. I just
pointed the few most prominent definitions I have found while
researching the subject. What did strike me though is that SPI is much
less defined and explained than I anticipated.
What I am questioning is whether an API / SPI split is more or less
useful than a API / FPI (as I call it in the email) split for the users
of our libraries.
Emmanuel
On Thu 2014-05-22 9:32, Steve Ebersole wrote:
> Deja vu as we have had this exact discussion before (and actually, our
> discussions pre-date those TAG discussions....)
>
> You are basing your specific reading of what SPI means based on a single
> wikipedia page that goes out of its way to point out its incompleteness :)
> And really even then in my opinion you are reading too much into its
> mention of the JDK ServiceLoader. What the wikiepdia says specifically is:
>
> *Service Provider Interface* (SPI) is an
> API<http://en.wikipedia.org/wiki/Application_programming_interface>
> intended
> > to be implemented or extended by a third party. It can be used to enable
> > framework extension and replaceable components
>
>
> That's actually not much different (if at all) from how I use the term SPI.
> To me, SPI is simply "the API that is used between internal components to
> accomplish something". A specific important distinction here is that APIs
> are meant for application code to bind to, SPIs are not. As I have pointed
> out probably 100 times already, yes there are 2 facets to this. To me an
> SPI is made up of:
> 1) The SPI contracts that are meant to be extended by users and/or 3rd
> parties.
> 2) The SPI contracts that are not intended for extension.
>
> Another correlated break down is:
> 1) SPI contracts that do things
> 2) SPI contracts that are inputs/outputs to (1)
>
> Take for example, the idea of scanning deployments for annotated classes
> (mainly because this one is fresh in my mind). The main SPI contract here
> is Scanner and ArchiveDescriptorFactory. These are each intended as
> extension points, they both "do stuff". All the rest of the "scanning spi"
> is inouts/outputs to these 2. Why is this an important distinction? Well,
> generally speaking where we get into trouble in terms of "changing SPIs"
> later is when we change this first group. When we have to make
> changes to Scanner
> or make changes to ArchiveDescriptorFactory we cause problems downstream
> for folks that implement/extend this stuff. That's where patterns like
> parameter objects and delegates are sooooooooo beneficial. As an
> illustration, say we need to pass some new information into the single
> Scanner method (this was the recent case I worked through). If that means
> adding a new parameter to that Scanner method, well that just screwed every
> implementor of the Scanner interface because now their implementation is no
> longer valid. If instead, Scanner had made use of parameter objects (it
> now does btw), the parameter object itself would have been changed causing
> no problem of existing Scanner implementations. The "parameter object" is
> still part of the SPI. But it falls into this second category. Changing
> these guys is essentially irrelevant in terms of causing no issues for
> existing SPI implementations.
>
>
> And as far as "a tendency to consider the application developer more sacred
> than the framework/integrator when it comes to breaking backward
> compatibility" I would not phrase it like that. There are a few parts to
> this in my mind:
>
> First, I think you need to step back and look at the bigger picture. The
> API defines the features that Hibernate is exposing to the application
> (save this thing, find that thing). Its kind of broad and generally avoids
> defining a feature in relation to an interaction between 2 things. SPIs in
> many ways are inherently more complicated to design because they need to
> consider both sides of the problem. Going back to scanning, that SPI needs
> to consider Hibernate's requirements from scanning as well as any
> requirements the implementation needs especially accounting for any quirks
> in the various potential implementations.
>
> Second, because of the "overlap" or "integration" aspects between teams and
> projects there needs to be coordination and cooperation when
> building/designing an SPI. To be honest, this part has been lacking even
> within "our team" across projects because people get focused on their work.
> What happens instead, again from my perspective, is no
> coordination/cooperation
> occurs in the building/designing of these; and then later people get upset
> when the SPI needs to change because it was not well designed to begin
> with. Another aspects of this is "more eyes"; the more people involved in
> the design of an API (SPI fits in here equally) looking at it, the better
> designed it will be.
>
>
> All that said, I don't plan on changing use of the phrase SPI based on (a
> questionable interpretation of) one wikipedia page.
>
>
> On Thu, May 22, 2014 at 4:21 AM, Emmanuel Bernard <emmanuel at hibernate.org>wrote:
>
> > (This discussion is around OGM but it is a very generic subject applicable
> > to all projects.)
> >
> > I made a mistake in naming the spi packages SPI because the definition of
> > SPI is quite narrow and even more narrower in Java than elsewhere.
> >
> > ## Definitions
> >
> > ### SPI
> >
> > In Java and according to Wikipedia, a SPI (Service provider interface) is
> > related to the notion of ServiceLoader
> > http://en.wikipedia.org/wiki/Service_Provider_Interface
> > We certainly do not (or very rarely) have these kinds of services in our
> > SPI packages.
> >
> > Another point of you comes from this StackOverflow article
> > https://stackoverflow.com/questions/2954372/difference-between-spi-and-api
> >
> > - the API is the description of classes/interfaces/methods/... that you
> > call and use to achieve a goal and
> > - the SPI is the description of classes/interfaces/methods/... that you
> > extend and implement to achieve a goal
> >
> > A third point of you is the NetBeans one
> > http://wiki.netbeans.org/DevFaqApiSpi
> >
> > SPI stands for Service Provider Interface. It is a subset of all things
> > that can be API specific to situations where a library is providing classes
> > which are called by the application (or API library), and which typically
> > change the things the application is able to do.
> >
> > I think everyone agrees that an SPI is kind of API.
> >
> > ### IPI or FPI (Integrator / Framework Public Interface)
> >
> > I will use FPI as it tastes better than IPI but I have no preferences over
> > integrators vs frameworks.
> >
> > Now in my mind and for some obscure reasons, SPI really meant FPI. To my
> > credit, I have done that fairly constantly on Hibernate Search and Bean
> > Validation. Hibernate OGM was never properly packaged initially so that’s
> > another story.
> >
> > A FPI is used by a framework integrating or extending the project exposing
> > these FPIs.
> >
> > ## What does really matter?
> >
> > It is useful to differentiate an API used from an API extended (SPI)
> > because the constraints are different:
> >
> > - APIs used can add new methods and should be interfaces rather than
> > classes.
> > - APIs extended (SPIs) should be abstract classes so that a new contract
> > added can be offered by the project without breaking implementors.
> >
> > But from a user point of you, I’m tempted to say "so what?”. It does not
> > change your inclination to make use of that contract.
> >
> > It is useful to differentiate application developer(*) facing APIs from
> > framework/integrator facing APIs (FPIs) to keep the API simple to use and
> > to document. There is also a tendency to consider the application developer
> > more sacred than the framework/integrator when it comes to breaking
> > backward compatibility.
> >
> > (*) I say application developer here but it really the primary user group
> > of your project whereas the integrators are usually less numerous and more
> > controllable.
> >
> > To me the latter (API/FPI) is more generally useful and that is the one I
> > wish to separate in different packages naming conventions.
> > The former it seems to me is very often self-obvious to the user and
> > project maintainers. And from a usage PoV, it does not really matter. Plus
> > there are cases where a contract is both used and extended (JDBC’s
> > Connection contract for example).
> >
> > Can and should we split according to both dimensions? I don’t think so.
> > And if I have to chose, I’d prefer to split according to the API/ FPI
> > dimension which is more generally useful to our customers and makes it
> > clear what is non breakable (API), what is inconvenient to break (FPI),
> > what is free lunch (implementation).
> >
> > ## References
> >
> > There has been some discussions in the past as well
> > https://issues.jboss.org/browse/TAG-47
> >
> > Emmanuel
> > _______________________________________________
> > hibernate-dev mailing list
> > hibernate-dev at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
> >
More information about the hibernate-dev
mailing list