(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@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/hibernate-dev

Reply via email to