[GH-ISSUE #4] Include a DiscoveryStategy for php-http/discovery #3

Closed
opened 2026-02-28 14:22:45 +03:00 by kerem · 5 comments
Owner

Originally created by @eclipxe13 on GitHub (Mar 22, 2019).
Original GitHub issue: https://github.com/chillerlan/php-httpinterface/issues/4

Could you consider to add a Http\Discovery\Strategy\DiscoveryStrategy implementation so it would be easy to register and to use this library when working with php-http/discovery?

I just see that php-http/discovery knows about a very limited set of PSR-17, PSR-18 implementations. But has a way to add your classes to the discover process:

// register class so `php-http/discovery` can find them
Psr18ClientDiscovery::appendStrategy(ChillerlanStrategy::class);
Psr17FactoryDiscovery::appendStrategy(hillerlanStrategy::class);


// on your library:
namespace chillerlan\HTTP;

use Http\Discovery\Strategy\DiscoveryStrategy;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ServerRequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\UploadedFileFactoryInterface;
use Psr\Http\Message\UriFactoryInterface;
use Psr\Http\Client\ClientInterface;

final class ChillerlanStrategy implements DiscoveryStrategy
{
    /**
     * {@inheritdoc}
     */
    public static function getCandidates($type)
    {
        $classes = [
            RequestFactoryInterface::class => ['chillerlan\HTTP\Psr17\RequestFactory'],
            ResponseFactoryInterface::class => ['chillerlan\HTTP\Psr17\ResponseFactory'],
            ServerRequestFactoryInterface::class => ['chillerlan\HTTP\Psr17\ServerRequestFactory'],
            StreamFactoryInterface::class => ['chillerlan\HTTP\Psr17\StreamFactory'],
            UploadedFileFactoryInterface::class => ['chillerlan\HTTP\Psr17\UploadedFileFactory'],
            UriFactoryInterface::class => ['chillerlan\HTTP\Psr17\UriFactory'],
            ClientInterface::class => ['chillerlan\HTTP\Psr18\StreamClient', 'chillerlan\HTTP\Psr18\CurlClient'],
        ];
        $candidates = [];
        if (isset($classes[$type])) {
            foreach ($classes[$type] as $class) {
                $candidates[] = ['class' => $class, 'condition' => [$class]];
            }
        }

        return $candidates;
    }
}

This is a POC that I made and works once #3 is merged.

Originally created by @eclipxe13 on GitHub (Mar 22, 2019). Original GitHub issue: https://github.com/chillerlan/php-httpinterface/issues/4 Could you consider to add a `Http\Discovery\Strategy\DiscoveryStrategy` implementation so it would be easy to register and to use this library when working with `php-http/discovery`? I just see that `php-http/discovery` knows about a very limited set of PSR-17, PSR-18 implementations. But has a way to add your classes to the discover process: ```php // register class so `php-http/discovery` can find them Psr18ClientDiscovery::appendStrategy(ChillerlanStrategy::class); Psr17FactoryDiscovery::appendStrategy(hillerlanStrategy::class); // on your library: namespace chillerlan\HTTP; use Http\Discovery\Strategy\DiscoveryStrategy; use Psr\Http\Message\RequestFactoryInterface; use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\ServerRequestFactoryInterface; use Psr\Http\Message\StreamFactoryInterface; use Psr\Http\Message\UploadedFileFactoryInterface; use Psr\Http\Message\UriFactoryInterface; use Psr\Http\Client\ClientInterface; final class ChillerlanStrategy implements DiscoveryStrategy { /** * {@inheritdoc} */ public static function getCandidates($type) { $classes = [ RequestFactoryInterface::class => ['chillerlan\HTTP\Psr17\RequestFactory'], ResponseFactoryInterface::class => ['chillerlan\HTTP\Psr17\ResponseFactory'], ServerRequestFactoryInterface::class => ['chillerlan\HTTP\Psr17\ServerRequestFactory'], StreamFactoryInterface::class => ['chillerlan\HTTP\Psr17\StreamFactory'], UploadedFileFactoryInterface::class => ['chillerlan\HTTP\Psr17\UploadedFileFactory'], UriFactoryInterface::class => ['chillerlan\HTTP\Psr17\UriFactory'], ClientInterface::class => ['chillerlan\HTTP\Psr18\StreamClient', 'chillerlan\HTTP\Psr18\CurlClient'], ]; $candidates = []; if (isset($classes[$type])) { foreach ($classes[$type] as $class) { $candidates[] = ['class' => $class, 'condition' => [$class]]; } } return $candidates; } } ``` This is a POC that I made and works once #3 is merged.
kerem closed this issue 2026-02-28 14:22:46 +03:00
Author
Owner

@codemasher commented on GitHub (Mar 22, 2019):

The original idea of httplug/php-http/discovery was to provide a common interface for http client libraries. Now that PSR-18 was accepted, it's no longer necessary to add another layer of abstraction. php-http/discovery has basically become obsolete now that we can write interoperable http clients using Psr\Http\Client\ClientInterface - it's up to the implementors now. Aside of that, the majority of what i've seen is still using Guzzle directly.

<!-- gh-comment-id:475736560 --> @codemasher commented on GitHub (Mar 22, 2019): The original idea of httplug/`php-http/discovery` was to provide a common interface for http client libraries. Now that PSR-18 was accepted, it's no longer necessary to add another layer of abstraction. `php-http/discovery` has basically become obsolete now that we can write interoperable http clients using `Psr\Http\Client\ClientInterface` - it's up to the implementors now. Aside of that, the majority of what i've seen is still using Guzzle directly.
Author
Owner

@eclipxe13 commented on GitHub (Mar 22, 2019):

I'm not talking about making php-httpinterface compatible with HTTP interfaces of HTTP Plug.
We have now PSR-17 & PSR-18 and its great. It makes obsolete while those PSR are commonly adopted.

But the discovery is filling a gap between the library user and the implementations provider. And this real need has not been covered by PHP-FIG.

php-http/discovery now support discover PSR-18 implementations using Psr18ClientDiscovery and PSR-17 implementations using Psr17FactoryDiscovery. They have also deprecated old methods that refer to php-http/message-factory and php-http/client-implementation.

As a developer of a component that relies on PSR7 & PSR17 & PSR18, it is easy to offer php-http/discovery support, and if you include a DiscoveryStategy is easy to let users choose your library.

On my side: I don't really care about what PSR implementation are they using.
On the library user's side: They have to do a minimal effort to use your library.
On your side: You provide a php-http/discovery way to use your library.

Yes, the common libraries (symfony on the near future) have the majority of the users. But it should not be this way. It is not even sane.

I was thinking that this suggestion could be archived in another package.
Name it chillerlan/php-httpinterface-discovery that require on php-http/discovery but only suggest chillerlan/php-httpinterface. In that way, it can add strategies for Psr18ClientDiscovery and Psr17ClientDiscovery but will discover the chillerlan/php-httpinterface only if it is installed.

Also, in my library depending on php-http/discovery I can require chillerlan/php-httpinterface-discovery and suggest chillerlan/php-httpinterface, it won't install chillerlan/php-httpinterface by default but include more options to users.

<!-- gh-comment-id:475748159 --> @eclipxe13 commented on GitHub (Mar 22, 2019): I'm not talking about making `php-httpinterface` compatible with HTTP interfaces of HTTP Plug. We have now PSR-17 & PSR-18 and its great. It makes *obsolete* while those PSR are commonly adopted. But the *discovery* is filling a gap between the *library user* and the *implementations provider*. And this real need has not been covered by PHP-FIG. `php-http/discovery` now support discover PSR-18 implementations using `Psr18ClientDiscovery` and PSR-17 implementations using `Psr17FactoryDiscovery`. They have also deprecated old methods that refer to `php-http/message-factory` and `php-http/client-implementation`. As a developer of a component that relies on PSR7 & PSR17 & PSR18, it is easy to offer `php-http/discovery` support, and if you include a `DiscoveryStategy` is easy to let users choose your library. On my side: I don't really care about what PSR implementation are they using. On the library user's side: They have to do a minimal effort to use your library. On your side: You provide a `php-http/discovery` way to use your library. Yes, the common libraries (symfony on the near future) have the majority of the users. But it should not be this way. It is not even sane. I was thinking that this suggestion could be archived in another package. Name it `chillerlan/php-httpinterface-discovery` that require on `php-http/discovery` but only suggest `chillerlan/php-httpinterface`. In that way, it can add strategies for `Psr18ClientDiscovery` and `Psr17ClientDiscovery` but will discover the `chillerlan/php-httpinterface` *only* if it is installed. Also, in my library depending on `php-http/discovery` I can require `chillerlan/php-httpinterface-discovery` and suggest `chillerlan/php-httpinterface`, it won't install `chillerlan/php-httpinterface` by default but include more options to users.
Author
Owner

@codemasher commented on GitHub (Mar 22, 2019):

I get your point. However, it's not my goal to walk backwards. Users of existing libraries won't need this library - there are tons of others which will satisfy their needs and of which this library originated - namely: Guzzle, Slim, Nyholm. If someone's going to write a new library that needs a http client, they'll probably prefer a PSR-18 client over a non-standard implementation anyway - without the need for lazy-loading or anything. If they're going to prefer the non-standard, it's up to them to provide an adapter for other client libraries in case they want them to be used (been there). I prefer not to contribute to technical debt and go with the standards we're given. Feel free to provide a php-http/discovery adapter for my library on your own - nothing will stop you.

<!-- gh-comment-id:475756894 --> @codemasher commented on GitHub (Mar 22, 2019): I get your point. However, it's not my goal to walk backwards. Users of existing libraries won't need this library - there are tons of others which will satisfy their needs and of which this library originated - namely: Guzzle, Slim, Nyholm. If someone's going to write a new library that needs a http client, they'll probably prefer a PSR-18 client over a non-standard implementation anyway - without the need for lazy-loading or anything. If they're going to prefer the non-standard, it's up to them to provide an adapter for other client libraries in case they want them to be used (been there). I prefer not to contribute to technical debt and go with the standards we're given. Feel free to provide a `php-http/discovery` adapter for my library on your own - nothing will stop you.
Author
Owner

@eclipxe13 commented on GitHub (Mar 22, 2019):

Ok, I will not insist on this. But I think you are missing the point that this is provide only standards.

Users of existing libraries won't need this library

They could, existing libraries based on HTTP Plug are obsolete now by HTTP Plug itself, and they will search for PSR compliant code as HTTP Plug is moving in that way.

This suggestion is to have more clients on PSR-17 & PSR-18 available. This is not going backwards and as you can see in the example code, is promoting only PSR-17 & PSR-18, is not promoting any non-PSR or HTTP Plug interfaces.

In my case, as a library creator, I will not use a direct implementation of PSR-17/PSR-18. Except, of course, for testing. All that should be configured by user. One way to achieve this is using php-http/discovery.

php-http/discovery does not force you to use any of the old HTTP Plug Interfaces that are now deprecated.

Thank you for your time and your thoughts.

<!-- gh-comment-id:475762813 --> @eclipxe13 commented on GitHub (Mar 22, 2019): Ok, I will not insist on this. But I think you are missing the point that this is **provide only standards**. > Users of existing libraries won't need this library They could, existing libraries based on HTTP Plug are obsolete now by HTTP Plug itself, and they will search for PSR compliant code as HTTP Plug is moving in that way. This suggestion is to have more clients on PSR-17 & PSR-18 available. This is not going backwards and as you can see in the example code, is promoting only PSR-17 & PSR-18, is not promoting any non-PSR or HTTP Plug interfaces. In my case, as a library creator, I will not use a direct implementation of PSR-17/PSR-18. Except, of course, for testing. All that should be configured by user. One way to achieve this is using `php-http/discovery`. `php-http/discovery` does not force you to use any of the old HTTP Plug Interfaces that are now deprecated. Thank you for your time and your thoughts.
Author
Owner

@codemasher commented on GitHub (Mar 22, 2019):

I still don't get the whole point of lazy loading a http client library - for Message factories, i can understand - these have strictly defined functionality. PSR-18 only provides sendRequest() - the rest is completely up to the http client library, that may require settings and all, making the point of a client discovery extremely wonky. Provide the http client of your choice - fin.

Edit: i'm pretty sure that was the point to not include some kind of discovery in PSR-18.

<!-- gh-comment-id:475774221 --> @codemasher commented on GitHub (Mar 22, 2019): I still don't get the whole point of lazy loading a http client library - for Message factories, i can understand - these have strictly defined functionality. PSR-18 only provides `sendRequest()` - the rest is completely up to the http client library, that may require settings and all, making the point of a client discovery extremely wonky. Provide the http client of your choice - fin. Edit: i'm pretty sure that was the point to not include some kind of discovery in PSR-18.
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/php-httpinterface#3
No description provided.