mollie-api-php
mollie-api-php copied to clipboard
Allow PSR-18 Http Clients
Specifications
- API Version: 2.63.0
Describe the issue
Hi,
I was wondering if you guys could add PSR18 (https://github.com/php-fig/http-client) as supported option for Http Clients.
The reason I'm asking is I'd like to use something like https://docs.php-http.org/en/latest/clients/mock-client.html in integration tests to mock mollie responses.
Sadly it currently only seems to support Guzzle's ClientInterface and your own one.
Hi @KDederichs,
thanks for your suggestion. I will discuss this internally.
Nevertheless, this would be a breaking change and therefore won’t be included in any release before v3, which is scheduled for early next year.
How about adding a Mollie\Api\HttpAdapter\PSR18MollieHttpAdapter here that implements the Mollie\Api\HttpAdapter\ MollieHttpAdapterInterface, which in turn accepts a PSR18 enabled client on the constructor? I think that way it's possible to introduce PSR18 support without a breaking change.
@KDederichs would you need PSR17 support as well (RequestFactoryInterface, StreamFactoryInterface)?
For example (not tested):
<?php
namespace Mollie\Api\HttpAdapter;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\RequestInterface;
use Mollie\Api\Exceptions\ApiException;
class PSR18MollieHttpAdapter implements MollieHttpAdapterInterface
{
/**
* @var ClientInterface
*/
private $httpClient;
/**
* @var RequestFactoryInterface
*/
private $requestFactory;
/**
* @var StreamFactoryInterface
*/
private $streamFactory;
/**
* PSR18MollieHttpAdapter constructor.
*
* @param ClientInterface $httpClient
* @param RequestFactoryInterface $requestFactory
* @param StreamFactoryInterface $streamFactory
*/
public function __construct(ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory)
{
$this->httpClient = $httpClient;
$this->requestFactory = $requestFactory;
$this->streamFactory = $streamFactory;
}
/**
* {@inheritdoc}
*/
public function send($httpMethod, $url, $headers, $httpBody)
{
try {
$request = $this->createRequest($httpMethod, $url, $headers, $httpBody);
$response = $this->httpClient->sendRequest($request);
$body = (string) $response->getBody();
return json_decode($body);
} catch (\Exception $e) {
throw new ApiException("Error while sending request to Mollie API: " . $e->getMessage(), 0, $e);
}
}
/**
* {@inheritdoc}
*/
public function versionString()
{
return 'PSR18MollieHttpAdapter';
}
/**
* Create a PSR-7 request.
*
* @param string $httpMethod
* @param string $url
* @param string|array $headers
* @param string $httpBody
* @return RequestInterface
*/
private function createRequest($httpMethod, $url, $headers, $httpBody)
{
$request = $this->requestFactory->createRequest($httpMethod, $url);
if (is_array($headers)) {
foreach ($headers as $name => $value) {
$request = $request->withHeader($name, $value);
}
} else {
// Assuming headers is a string in the form of 'Header-Name: Header-Value'
$headerLines = explode("\r\n", $headers);
foreach ($headerLines as $line) {
list($name, $value) = explode(': ', $line, 2);
$request = $request->withHeader($name, $value);
}
}
$stream = $this->streamFactory->createStream($httpBody);
$request = $request->withBody($stream);
return $request;
}
}
That looks like it would work yeah.
@Naoray what do you think?