friendsofphp/well-known-implementations

v1.0.0 2022-10-24 17:25 UTC

This package is auto-updated.

Last update: 2022-11-25 09:23:06 UTC


README

This package helps reduce the proliferation of same-abstraction implementations in vendor directories.

It is targeted at SDK maintainers that write their code in a decoupled way but still need an actual implementation to provide a nice experience out of the box.

Without this package, one would e.g. require the "php-http/client-implementation" virtual package to signal that a given SDK uses HTTPlug to make API calls, and would also require "php-http/guzzle7-adapter" to install an actual implementation in case none is wired by the consuming app when calling the SDK.

But imagine that the consuming app already has a dependency on another "php-http/client-implementation": the SDK should ideally reuse that implementation and "php-http/guzzle7-adapter" should be removed from vendor/ with all its transitive dependencies. This would help with dependency-management and might enable better integration in debugging panels for example.

By requiring "friendsofphp/well-known-implementations" instead of "php-http/guzzle7-adapter", SDK maintainers can provide ideal experiences: because this package is also a composer-plugin, it will auto-install an actual implementation of the required abstraction when none is already installed, or reuse it if one is found.

In their constructors, SDKs should then reference the provided "well-known" classes and they will get whatever implementation is available:

class MySdk
{
    public function __construct(
        private HttpClient $client = new WellKnownHttplugClient(),
    )
    {
        // ...
    }
}

All provided WellKnown* classes have standardized constructor signatures so that you don't need to care about which exact implementation is available to instantiate them.

Althought not required most of the time, you can check which implementation is used by using the ConcreteImplementation::*_VENDOR constants.

The logic to decide which implementation should be installed relies on the packages that are already found in a project. For example, if one is using react/event-loop, the plugin will select php-http/react-adapter (the rules are declared in ComposerPlugin; they're open for discussion.) The missing packages will be added to the project's composer.json file. This makes it easy to override the choices of the plugin by explicitly requiring the preferred implementations.

As of now, the following abstractions are supported:

  • php-http/async-client-implementation
  • php-http/client-implementation
  • psr/http-client-implementation
  • psr/http-factory-implementation
  • psr/http-message-implementation

And the following vendors are supported:

  • Guzzle
  • HTTPlug
  • Laminas
  • Nyholm
  • React
  • Slim
  • Symfony

More abstractions / vendors can be added by contributions.

If your favorite SDK does not use this package yet, please let them know about it or better: send them a PR!