Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<?php
namespace JustSteveKing\Transporter;
use Illuminate\Http\Client\PendingRequest;
class CreateTodoRequest extends Request
{
protected string $method = 'POST';
protected string $baseUrl = 'https://jsonplaceholder.typicode.com';
protected string $path = '/todos';
protected array $data = [
'completed' => false,
];
protected function withRequest(PendingRequest $request): void
{
$request->withToken('foobar');
}
}
<?php
namespace JustSteveKing\Transporter;
class ListTodosRequest extends Request
{
protected string $method = 'GET';
protected string $path = '/todos';
protected string $baseUrl = 'https://jsonplaceholder.typicode.com';
}
<?php
namespace JustSteveKing\Transporter;
use BadMethodCallException;
use Illuminate\Http\Client\Factory as HttpFactory;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Str;
use Illuminate\Support\Stringable;
use OutOfBoundsException;
/**
* @mixin \Illuminate\Http\Client\PendingRequest
*/
abstract class Request
{
protected PendingRequest $request;
protected string $method;
protected string $path;
protected string $baseUrl;
protected array $query = [];
protected array $data = [];
public static function for(...$args): self
{
return app(static::class, $args);
}
public function __construct(HttpFactory $http)
{
$this->request = $http->baseUrl($this->baseUrl);
$this->withRequest($this->request);
}
public function withData(array $data): self
{
$this->data = array_merge($this->data, $data);
return $this;
}
public function withQuery(array $query): self
{
$this->query = array_merge($this->query, $query);
return $this;
}
public function send(): Response
{
$url = (string) Str::of($this->path())
->when(
!empty($this->query),
fn(Stringable $path): Stringable => $path->append('?', http_build_query($this->query))
);
switch (mb_strtoupper($this->method)) {
case 'GET':
return $this->request->get($this->path(), $this->query);
case 'POST':
return $this->request->post($url, $this->data);
case 'PUT':
return $this->request->put($url, $this->data);
case 'PATCH':
return $this->request->patch($url, $this->data);
case 'DELETE':
return $this->request->delete($url, $this->data);
case 'HEAD':
return $this->request->head($this->path(), $this->query);
default:
throw new OutOfBoundsException();
}
}
protected function withRequest(PendingRequest $request): void
{
// do something with the initialized request
}
protected function path(): string
{
return $this->path;
}
public function __call(string $name, array $arguments): self
{
if (method_exists($this->request, $name)) {
call_user_func_array([$this->request, $name], $arguments);
return $this;
}
throw new BadMethodCallException();
}
}
<?php
namespace JustSteveKing\Transporter;
use Illuminate\Http\Client\Factory as HttpFactory;
class ShowTodoRequest extends Request
{
protected string $method = 'GET';
protected string $baseUrl = 'https://jsonplaceholder.typicode.com';
protected int $todoId;
public function __construct(HttpFactory $http, int $todoId)
{
parent::__construct($http);
$this->todoId = $todoId;
}
protected function path(): string
{
return "/todos/{$this->todoId}";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment