Design Principles: A Discussion on SPI and API

Author: Happy Framework

Original: https://www.cnblogs.com/happyframework/p/3325560.html

Design Principles: A Discussion on SPI and API

Background

Design Principles: A Discussion on SPI and API

My first encounter with SPI was while reading “The Art of Software Framework Design”. Later, I gradually discovered this way of organizing code in JDBC and SpringBoot. Here, I present a thought process on why we should distinguish between SPI and API.

Design Principles: A Discussion on SPI and API

Starting from interface-oriented programming

Design Principles: A Discussion on SPI and API

Design Principles: A Discussion on SPI and API

We introduced an “interface” between the “caller” and the “implementer”. The above diagram does not specify which “package” the “interface” should be in. From a purely possible standpoint, we have three choices:

  1. The “interface” is located in the package of the “caller”.

  2. The “interface” is located in the package of the “implementer”.

  3. The “interface” is located in an independent package.

Let us analyze these three possibilities one by one. If such possibilities exist in reality, we might as well give them names for easier communication.

Design Principles: A Discussion on SPI and API

The “interface” is located in the package of the “caller”

Design Principles: A Discussion on SPI and API

Let’s imagine a scenario using the repository interface as an example:

Design Principles: A Discussion on SPI and API

We place the “repository interface” in the “domain layer” package, while the implementation is in an independent package. We notice that DDD masters implement it this way, now let’s think about why they do this.

The “domain service” in the “domain layer” will depend on the “repository interface”, and the “repository interface” will also depend on the “aggregate root”. These two dependencies are apart from the “implementation dependency”. If we put the “interface” into the “repository implementation”, we lose the significance of interface-oriented programming (the compilation will also fail). What about placing it in the independent layer? It will also fail to compile due to circular dependency.

In such cases, we call the interface “SPI”, which stands for:<span><span><span>service provider interface</span></span></span>. The rules for “SPI” are as follows:

  1. Conceptually more dependent on the caller.
  2. Organizationally located in the package of the caller.
  3. Implementation is located in an independent package.
  4. A common example is: plugins in the plugin pattern.
Design Principles: A Discussion on SPI and API

The “interface” is located in the package of the “implementer”

Design Principles: A Discussion on SPI and API

Let’s imagine a scenario using the IUnityContainer interface provided by Unity. Apart from the team maintaining this framework, we have not found anyone who has implemented this interface, although it is theoretically possible to implement this interface (if it were possible, why not create our own IoC container?). Search for the public account: Java Backend Programming, reply: java to receive materials.

For interfaces in such cases, we call them “API”, and the rules for “API” are as follows:
  1. Conceptually closer to the implementer.
  2. Organizationally located in the package of the implementer.
  3. Implementation and interface are in the same package.
Design Principles: A Discussion on SPI and API

The “interface” is located in an independent package

Design Principles: A Discussion on SPI and API

We won’t discuss scenarios here. If an “interface” is an “API” in one context and an “SPI” in another, then you can organize it this way.

Design Principles: A Discussion on SPI and API

Points to Note

Design Principles: A Discussion on SPI and API

Regardless of whether it is SPI or API, interfaces can be organized into independent packages. Whether this is meaningful is up to you to decide.

SPI and API are not necessarily interfaces; I am referring specifically to concrete interfaces in a narrow sense.
Design Principles: A Discussion on SPI and API

Scenario Image

Design Principles: A Discussion on SPI and API

Design Principles: A Discussion on SPI and API

Every thought process comes with gains and is inseparable from communication with friends; the sky has become bluer.

SPI Interface:

  1. Definition: SPI is a service provider interface that allows for loading different service implementations at runtime.

  2. Usage Scenarios:

  • Modular Design: When the system requires high modularity and wishes to separate core functionalities from specific implementations.

  • Pluggable Architecture: When multiple service implementations need to be supported and can be replaced or added without modifying the code.

  • Service Discovery: Dynamically discovering and loading services at runtime based on configurations or service registries.

  • Microservices Architecture: In microservices architecture, SPI can be used for dynamic interaction and integration between services.

  • Advantages:

    • Provides a mechanism for selecting and loading service implementations at runtime, increasing system flexibility and scalability.

    • Supports hot swapping of services, allowing service implementations to be changed without restarting the system.

    API Interface:

    1. Definition: API is a set of predefined functions, protocols, and tools for building software applications, defining the contract for interaction between software components.

    2. Usage Scenarios:

    • Client-Server Interaction: When designing communication protocols between clients and servers.

    • Libraries and Frameworks: Public interfaces provided to developers for use in libraries or frameworks.

    • Third-party Integration: When integration with third-party systems or services is required.

    • Internal Component Communication: Interaction between different components or modules in large systems.

  • Advantages:

    • Provides clear interface documentation and specifications for developers, making it easy to understand and use.

    • Helps maintain system stability, as API changes must follow version control and compatibility rules.

    • Facilitates code reuse and modularization.

    How to Choose?

    Considerations for choosing between SPI and API:
    • Extensibility: If functionality needs to be extended without modifying code, SPI is more suitable.
    • Interactivity: API is more suitable for defining stable interaction interfaces within or between systems.
    • Dynamic Nature: SPI allows for dynamic discovery and loading of services at runtime, while API is typically determined at compile time.
    • Security and Stability: Due to its stability and predictability, API is usually preferred. SPI, while flexible, may introduce runtime errors.
    • Version Control and Compatibility: API changes need to consider version control and backward compatibility, while SPI can handle compatibility issues through service version negotiation.

    Architecture is a matter of trade-offs, not a silver bullet.

    Reprint Statement: All reprinted articles must indicate the original source or reprint source (if the reprint does not indicate the original source). If there is any infringement, please contact for deletion.

    Leave a Comment