Skip to content
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

Make methods public #3

Merged
merged 3 commits into from
May 3, 2024
Merged
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
143 changes: 64 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,20 @@ A library for creating SDKs in PHP with support for:
- Event listeners;
- ...and more.

All methods are public for full end user hackability 🔥.

## Requirements

- PHP 8.1 or higher.

## Installation

You can install the library via [Composer](https://getcomposer.org/):
Install the library via [Composer](https://getcomposer.org/):

```bash
composer require programmatordev/php-api-sdk
```

To use the library, use Composer's [autoload](https://getcomposer.org/doc/01-basic-usage.md#autoloading):

```php
require_once 'vendor/autoload.php';
```

## Basic Usage

Just extend your API library with the `Api` class and have fun coding:
Expand Down Expand Up @@ -365,6 +361,8 @@ class YourApi extends Api

- [`addPostRequestHandler`](#addpostrequesthandler)
- [`addResponseContentsHandler`](#addresponsecontentshandler)
- [Event Priority](#event-priority)
- [Event Propagation](#event-propagation)

#### `addPostRequestHandler`

Expand Down Expand Up @@ -455,11 +453,65 @@ class YourApi extends Api
}
```

### HTTP Client (PSR-18) and HTTP Factories (PSR-17)
#### Event Priority

It is possible to add multiple listeners for the same event and set the order in which they will be executed.
By default, they will be executed in the same order as they are added, but you can set a `priority` to control that order.
Event listeners are then executed from the highest priority to the lowest:

```php
use ProgrammatorDev\Api\Api;
use ProgrammatorDev\Api\Event\PostRequestEvent;

class YourApi extends Api
{
public function __construct()
{
// two event listeners are added,
// but the second is executed first (higher priority) even though it was added after

// executed last (lower priority)
$this->addResponseContentsHandler(
handler: function(PostRequestEvent $event) { ... },
priority: 0
);

// executed first (higher priority)
$this->addResponseContentsHandler(
handler: function(PostRequestEvent $event) { ... },
priority: 10
);
}
}
```

#### Event Propagation

In some cases, you may want to stop the event flow and prevent listeners from being called.
For that, you can use the `stopPropagation()` method:

```php
use ProgrammatorDev\Api\Api;
use ProgrammatorDev\Api\Event\PostRequestEvent;

class YourApi extends Api
{
public function __construct()
{
$this->addResponseContentsHandler(function(PostRequestEvent $event) {
// stop propagation so future listeners of this event will not be called
$event->stopPropagation();
});

// this listener will not be called
$this->addResponseContentsHandler(function(PostRequestEvent $event) {
// ...
});
}
}
```

> [!IMPORTANT]
> The methods in this section are all public.
> The purpose for that is to allow the end user to configure their own HTTP client, HTTP factories and plugins.
### HTTP Client (PSR-18) and HTTP Factories (PSR-17)

- [HTTP client and HTTP factory adapters](#http-client-and-http-factory-adapters)
- [Plugin system](#plugin-system)
Expand Down Expand Up @@ -525,30 +577,12 @@ class YourApi extends Api
}
```

The same for the end user:

```php
$api = new YourApi();

$client = new Psr18Client();
$requestFactory = $streamFactory = new Psr17Factory();

$api->setClientBuilder(
new ClientBuilder(
client: $client,
requestFactory: $requestFactory,
streamFactory: $streamFactory
)
);
```

#### Plugin System

This library enables attaching plugins to the HTTP client.
A plugin modifies the behavior of the client by intercepting the request and response flow.

Since plugin order matters, a plugin is added with a priority level,
and are executed in descending order from highest to lowest.
Since plugin order matters, a plugin is added with a priority level, and are executed in descending order from highest to lowest.

Check all the [available plugins](https://docs.php-http.org/en/latest/plugins/index.html) or [create your own](https://docs.php-http.org/en/latest/plugins/build-your-own.html).

Expand Down Expand Up @@ -597,23 +631,8 @@ class YourApi extends Api
}
```

The same for the end user:

```php
$api = new YourApi();

$api->getClientBuilder()->addPlugin(
plugin: new RetryPlugin(['retries' => 3])
priority: 12
);
```

### Cache (PSR-6)

> [!IMPORTANT]
> The methods in this section are all public.
> The purpose for that is to allow the end user to configure their own cache adapter.

This library allows configuring the cache layer of the client for making API requests.
It uses a standard PSR-6 implementation and provides methods to fine-tune how HTTP caching behaves:
- [PSR-6 compatible implementations](https://packagist.org/providers/psr/cache-implementation)
Expand Down Expand Up @@ -685,27 +704,8 @@ class YourApi extends Api
}
```

The same for the end user:

```php
$api = new YourApi();

$pool = new FilesystemAdapter();

$api->setCacheBuilder(
new CacheBuilder(
pool: $pool,
ttl: 3600
)
);
```

### Logger (PSR-3)

> [!IMPORTANT]
> The methods in this section are all public.
> The purpose for that is to allow the end user to configure their own logger adapter.

This library allows configuring a logger to save data for making API requests.
It uses a standard PSR-3 implementation and provides methods to fine-tune how logging behaves:
- [PSR-3 compatible implementations](https://packagist.org/providers/psr/log-implementation)
Expand Down Expand Up @@ -763,21 +763,6 @@ class YourApi extends Api
}
```

The same for the end user:

```php
$api = new YourApi();

$logger = new Logger('api');
$logger->pushHandler(new StreamHandler('/logs/api.log'));

$api->setLoggerBuilder(
new LoggerBuilder(
logger: $logger
)
);
```

### Configure Options

It is very common for APIs to offer different options (like language, timezone, etc.).
Expand Down
28 changes: 14 additions & 14 deletions src/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function __construct()
* @throws ConfigException If a base URL has not been set.
* @throws ClientException
*/
protected function request(
public function request(
string $method,
string $path,
array $query = [],
Expand Down Expand Up @@ -138,50 +138,50 @@ private function configurePlugins(): void
}
}

protected function getBaseUrl(): ?string
public function getBaseUrl(): ?string
{
return $this->baseUrl;
}

protected function setBaseUrl(string $baseUrl): self
public function setBaseUrl(string $baseUrl): self
{
$this->baseUrl = $baseUrl;

return $this;
}

protected function getQueryDefault(string $name): mixed
public function getQueryDefault(string $name): mixed
{
return $this->queryDefaults[$name] ?? null;
}

protected function addQueryDefault(string $name, mixed $value): self
public function addQueryDefault(string $name, mixed $value): self
{
$this->queryDefaults[$name] = $value;

return $this;
}

protected function removeQueryDefault(string $name): self
public function removeQueryDefault(string $name): self
{
unset($this->queryDefaults[$name]);

return $this;
}

protected function getHeaderDefault(string $name): mixed
public function getHeaderDefault(string $name): mixed
{
return $this->headerDefaults[$name] ?? null;
}

protected function addHeaderDefault(string $name, mixed $value): self
public function addHeaderDefault(string $name, mixed $value): self
{
$this->headerDefaults[$name] = $value;

return $this;
}

protected function removeHeaderDefault(string $name): self
public function removeHeaderDefault(string $name): self
{
unset($this->headerDefaults[$name]);

Expand Down Expand Up @@ -224,33 +224,33 @@ public function setLoggerBuilder(?LoggerBuilder $loggerBuilder): self
return $this;
}

protected function getAuthentication(): ?Authentication
public function getAuthentication(): ?Authentication
{
return $this->authentication;
}

protected function setAuthentication(?Authentication $authentication): self
public function setAuthentication(?Authentication $authentication): self
{
$this->authentication = $authentication;

return $this;
}

protected function addPostRequestHandler(callable $handler, int $priority = 0): self
public function addPostRequestHandler(callable $handler, int $priority = 0): self
{
$this->eventDispatcher->addListener(PostRequestEvent::class, $handler, $priority);

return $this;
}

protected function addResponseContentsHandler(callable $handler, int $priority = 0): self
public function addResponseContentsHandler(callable $handler, int $priority = 0): self
{
$this->eventDispatcher->addListener(ResponseContentsEvent::class, $handler, $priority);

return $this;
}

protected function buildPath(string $path, array $parameters): string
public function buildPath(string $path, array $parameters): string
{
foreach ($parameters as $parameter => $value) {
$path = \str_replace(
Expand Down
Loading
Loading