[hibernate-dev] [OGM and others] API, SPI and FPI

Emmanuel Bernard emmanuel at hibernate.org
Thu May 22 05:21:13 EDT 2014


(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


More information about the hibernate-dev mailing list