Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions src/Http/BatchRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Saloon\Http;

use Saloon\Contracts\ArrayStore as ArrayStoreContract;
use Saloon\Repositories\ArrayStore;

abstract class BatchRequest
{
/**
* Request Headers
*/
protected ArrayStoreContract $requests;

/**
* Get all requests.
*
* @return ArrayStoreContract
*/
public function getRequests(): ArrayStoreContract
{
return $this->requests ??= new ArrayStore($this->defaultRequests());
}

/**
* Add a request dynamically.
*
* @param Request $request
* @return void
*/
public function addRequest(Request $request): void
{
$this->requests->add(uniqid('request_', true), $request);
}

/**
* Get default requests.
*
* @return array<Request>
*/
protected function defaultRequests(): array
{
return [];
}

/**
* Process the batch of responses.
*
* @param array<Response> $responses
* @return mixed
*/
abstract public function processResponses(array $responses): mixed;
}
4 changes: 2 additions & 2 deletions src/Http/Connector.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use Saloon\Traits\Connector\SendsRequests;
use Saloon\Traits\Auth\AuthenticatesRequests;
use Saloon\Traits\RequestProperties\HasTries;
use Saloon\Traits\Responses\HasCustomResponses;
use Saloon\Traits\Responses\HasResponseClass;
use Saloon\Traits\Request\CreatesDtoFromResponse;
use Saloon\Traits\RequestProperties\HasRequestProperties;

Expand All @@ -23,7 +23,7 @@ abstract class Connector
use CreatesDtoFromResponse;
use AuthenticatesRequests;
use HasRequestProperties;
use HasCustomResponses;
use HasResponseClass;
use ManagesExceptions;
use HandlesPsrRequest;
use HasMockClient;
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use Saloon\Traits\ManagesExceptions;
use Saloon\Traits\Auth\AuthenticatesRequests;
use Saloon\Traits\RequestProperties\HasTries;
use Saloon\Traits\Responses\HasCustomResponses;
use Saloon\Traits\Responses\HasResponseClass;
use Saloon\Traits\Request\CreatesDtoFromResponse;
use Saloon\Traits\RequestProperties\HasRequestProperties;

Expand All @@ -24,7 +24,7 @@ abstract class Request
use CreatesDtoFromResponse;
use AuthenticatesRequests;
use HasRequestProperties;
use HasCustomResponses;
use HasResponseClass;
use ManagesExceptions;
use HandlesPsrRequest;
use HasMockClient;
Expand Down
50 changes: 35 additions & 15 deletions src/Traits/Connector/SendsRequests.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

namespace Saloon\Traits\Connector;

use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\Utils;
use LogicException;
use Saloon\Exceptions\Request\FatalRequestException;
use Saloon\Exceptions\Request\RequestException;
use Saloon\Http\BatchRequest;
use Saloon\Http\Faking\MockClient;
use Saloon\Http\PendingRequest;
use Saloon\Http\Pool;
use Saloon\Http\Request;
use Saloon\Http\Response;
use GuzzleHttp\Promise\Utils;
use GuzzleHttp\Promise\Promise;
use Saloon\Http\PendingRequest;
use Saloon\Http\Faking\MockClient;
use GuzzleHttp\Promise\PromiseInterface;
use Saloon\Exceptions\Request\RequestException;
use Saloon\Exceptions\Request\FatalRequestException;

trait SendsRequests
{
Expand All @@ -29,7 +29,7 @@ trait SendsRequests
public function send(Request $request, ?MockClient $mockClient = null, ?callable $handleRetry = null): Response
{
if (is_null($handleRetry)) {
$handleRetry = static fn (): bool => true;
$handleRetry = static fn(): bool => true;
}

$attempts = 0;
Expand Down Expand Up @@ -126,17 +126,37 @@ public function send(Request $request, ?MockClient $mockClient = null, ?callable
/**
* Send a request asynchronously
*/
public function sendAsync(Request $request, ?MockClient $mockClient = null): PromiseInterface
public function sendAsync(Request|BatchRequest $request, ?MockClient $mockClient = null): PromiseInterface
{
$sender = $this->sender();

// We'll wrap the following logic in our own Promise which means we won't
// build up our PendingRequest until the promise is actually being sent
// this is great because our middleware will only run right before
// the request is sent.

return Utils::task(function () use ($request, $mockClient, $sender) {
$pendingRequest = $this->createPendingRequest($request, $mockClient)->setAsynchronous(true);
if ($request instanceof Request) {
return $this->prepareAsyncRequest($request, $mockClient);
}

$requests = array_map(
fn($singleRequest) => $this->prepareAsyncRequest($singleRequest, $mockClient),
$request->getRequests()->all()
);

return Utils::all($requests)->then(fn(array $responses) => $request->processResponses($responses));
}

/**
* Prepare an asynchronous task for sending the request.
*
* @param Request $request
* @param MockClient|null $mockClient
* @return PromiseInterface
*/
protected function prepareAsyncRequest(Request $request, MockClient $mockClient = null): PromiseInterface
{
return Utils::task(function () use ($request, $mockClient) {
$pendingRequest = $this->createPendingRequest($request, $mockClient)
->setAsynchronous(true);

// We need to check if the Pending Request contains a fake response.
// If it does, then we will create the fake response. Otherwise,
Expand All @@ -147,10 +167,10 @@ public function sendAsync(Request $request, ?MockClient $mockClient = null): Pro
if ($pendingRequest->hasFakeResponse()) {
$requestPromise = $this->createFakeResponse($pendingRequest);
} else {
$requestPromise = $sender->sendAsync($pendingRequest);
$requestPromise = $this->sender()->sendAsync($pendingRequest);
}

$requestPromise->then(fn (Response $response) => $pendingRequest->executeResponsePipeline($response));
$requestPromise->then(fn(Response $response) => $pendingRequest->executeResponsePipeline($response));

return $requestPromise;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@

namespace Saloon\Traits\Responses;

trait HasCustomResponses
trait HasResponseClass
{
/**
* Specify a default response.
* Specify a default response class.
*
* When null or an empty string, the response on the sender will be used.
*
* @var class-string<\Saloon\Http\Response>|null
*/
protected ?string $response = null;
protected ?string $responseClass = null;

/**
* Resolve the custom response class
Expand All @@ -22,6 +22,6 @@ trait HasCustomResponses
*/
public function resolveResponseClass(): ?string
{
return $this->response ?? null;
return $this->responseClass ?? null;
}
}
Loading