Skip to content

Fix broken HttpMethodsClient with PSR RequestFactory #202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 19, 2020
Merged

Fix broken HttpMethodsClient with PSR RequestFactory #202

merged 4 commits into from
Jul 19, 2020

Conversation

GrahamCampbell
Copy link
Contributor

@GrahamCampbell GrahamCampbell commented Jul 18, 2020

Q A
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? yes
Related tickets fixes #201
License MIT

The PSR request factory doesn't know anything about headers or body, and these parameters are silently thrown away!

In order to avoid these, we must set them on the request afterwards. Note that by doing this we have revealed a hidden dependency on a stream factory. I have allowed for this in BC-preserving manner.

Copy link
Contributor

@dbu dbu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, thanks! one question about how to handle BC

{
if (!$requestFactory instanceof RequestFactory && !$requestFactory instanceof RequestFactoryInterface) {
throw new \TypeError(
sprintf('%s::__construct(): Argument #2 ($requestFactory) must be of type %s|%s, %s given', self::class, RequestFactory::class, RequestFactoryInterface::class, get_debug_type($requestFactory))
);
}

if (!$requestFactory instanceof RequestFactory && null === $streamFactory) {
@trigger_error(sprintf('Passing a %s without a %s to %s::__construct() is deprecated as of version 2.3 and will be disallowed in version 3.0. A stream factory is required to create a request with a string body.', RequestFactoryInterface::class, StreamFactoryInterface::class, self::class));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i assume that in next major, we might want to only support the psr factory, to move forward? then we could simply make the stream factory a required argument... (no need to change anything here, just a thought ;-) )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so too. I am thinking once the old interfaces are all marked as deprecated in the future (https://github.com/php-http/message-factory/blob/master/src/ResponseFactory.php doesn't have a deprecation annotation yet), we can come back here to this constructor and also add a futher deprecation warning for if a psr request factory is not passed. Then yeh, in the next major version make all prams typed with psr interfaces, and all required.

$headers,
$body
));
if (!is_string($uri) && !$uri instanceof UriInterface) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is not a BC break, even if the caller didn't have strict typing and expected stuff to be cast to a string at runtime, because this file itself has strict typing and was previously forwarding the parameter as is, so the result would still be a type error later, but just a more obscure error message. Including an early guard here will help callers correct their error, and also checking the uri and body are the correct types here mean our logic later on within the private createRequest function is a little simpler than it would have otherwise been.

@GrahamCampbell
Copy link
Contributor Author

Good call about the empty string. I've allowed that case through without setting the body. :)

@GrahamCampbell
Copy link
Contributor Author

GrahamCampbell commented Jul 19, 2020

After this is merged, don't tag a release yet. I am going to add phpstan to the CI in a separate PR, and see if I can detect any further bugs. phpstan would have prevented this bug, for example.

@dbu dbu merged commit 788697e into php-http:master Jul 19, 2020
@dbu
Copy link
Contributor

dbu commented Jul 19, 2020

thanks!

@dbu
Copy link
Contributor

dbu commented Jul 19, 2020

phpstan is a good idea for sure. i don't know if it would have spotted this particular issue, because the factory can have one or the other type, and the call was correct for one type.

@GrahamCampbell
Copy link
Contributor Author

It would have warned us that we could possibly be passing too many parameters, if we had the analysis level turned up high enough (actually, level 2 or higher). It'd have insisted we did an instanceof check:

image

image

@GrahamCampbell GrahamCampbell deleted the methods-client-fix branch July 19, 2020 11:19
acrobat added a commit to KnpLabs/php-github-api that referenced this pull request Aug 11, 2020
This PR was merged into the 3.0.x-dev branch.

Discussion
----------

~Depends on php-http/client-common#202 EDIT: merged and released.

Commits
-------

d934db0 Fix the HTTP methods client
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HttpMethodsClient not working with PSR-17
2 participants