Skip to content

Commit a661c32

Browse files
authored
Merge pull request #4 from programmatordev/1.x
1.x
2 parents 8d2b990 + 77c5899 commit a661c32

File tree

3 files changed

+80
-173
lines changed

3 files changed

+80
-173
lines changed

Diff for: README.md

+64-80
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,20 @@ A library for creating SDKs in PHP with support for:
1313
- Event listeners;
1414
- ...and more.
1515

16+
All methods are public for full end user hackability 🔥.
17+
1618
## Requirements
1719

1820
- PHP 8.1 or higher.
1921

2022
## Installation
2123

22-
You can install the library via [Composer](https://getcomposer.org/):
24+
Install the library via [Composer](https://getcomposer.org/):
2325

2426
```bash
2527
composer require programmatordev/php-api-sdk
2628
```
2729

28-
To use the library, use Composer's [autoload](https://getcomposer.org/doc/01-basic-usage.md#autoloading):
29-
30-
```php
31-
require_once 'vendor/autoload.php';
32-
```
33-
3430
## Basic Usage
3531

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

366362
- [`addPostRequestHandler`](#addpostrequesthandler)
367363
- [`addResponseContentsHandler`](#addresponsecontentshandler)
364+
- [Event Priority](#event-priority)
365+
- [Event Propagation](#event-propagation)
368366

369367
#### `addPostRequestHandler`
370368

@@ -455,11 +453,65 @@ class YourApi extends Api
455453
}
456454
```
457455

458-
### HTTP Client (PSR-18) and HTTP Factories (PSR-17)
456+
#### Event Priority
457+
458+
It is possible to add multiple listeners for the same event and set the order in which they will be executed.
459+
By default, they will be executed in the same order as they are added, but you can set a `priority` to control that order.
460+
Event listeners are then executed from the highest priority to the lowest:
461+
462+
```php
463+
use ProgrammatorDev\Api\Api;
464+
use ProgrammatorDev\Api\Event\PostRequestEvent;
465+
466+
class YourApi extends Api
467+
{
468+
public function __construct()
469+
{
470+
// two event listeners are added,
471+
// but the second is executed first (higher priority) even though it was added after
472+
473+
// executed last (lower priority)
474+
$this->addResponseContentsHandler(
475+
handler: function(PostRequestEvent $event) { ... },
476+
priority: 0
477+
);
478+
479+
// executed first (higher priority)
480+
$this->addResponseContentsHandler(
481+
handler: function(PostRequestEvent $event) { ... },
482+
priority: 10
483+
);
484+
}
485+
}
486+
```
487+
488+
#### Event Propagation
489+
490+
In some cases, you may want to stop the event flow and prevent listeners from being called.
491+
For that, you can use the `stopPropagation()` method:
492+
493+
```php
494+
use ProgrammatorDev\Api\Api;
495+
use ProgrammatorDev\Api\Event\PostRequestEvent;
496+
497+
class YourApi extends Api
498+
{
499+
public function __construct()
500+
{
501+
$this->addResponseContentsHandler(function(PostRequestEvent $event) {
502+
// stop propagation so future listeners of this event will not be called
503+
$event->stopPropagation();
504+
});
505+
506+
// this listener will not be called
507+
$this->addResponseContentsHandler(function(PostRequestEvent $event) {
508+
// ...
509+
});
510+
}
511+
}
512+
```
459513

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

464516
- [HTTP client and HTTP factory adapters](#http-client-and-http-factory-adapters)
465517
- [Plugin system](#plugin-system)
@@ -502,7 +554,6 @@ If you don't want to rely on the discovery of implementations, you can set the o
502554
```php
503555
use ProgrammatorDev\Api\Api;
504556
use ProgrammatorDev\Api\Builder\ClientBuilder;
505-
use Http\Client\Common\EmulatedHttpAsyncClient
506557
use Symfony\Component\HttpClient\Psr18Client;
507558
use Nyholm\Psr7\Factory\Psr17Factory;
508559

@@ -526,30 +577,12 @@ class YourApi extends Api
526577
}
527578
```
528579

529-
The same for the end user:
530-
531-
```php
532-
$api = new YourApi();
533-
534-
$client = new Psr18Client();
535-
$requestFactory = $streamFactory = new Psr17Factory();
536-
537-
$api->setClientBuilder(
538-
new ClientBuilder(
539-
client: $client,
540-
requestFactory: $requestFactory,
541-
streamFactory: $streamFactory
542-
)
543-
);
544-
```
545-
546580
#### Plugin System
547581

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

551-
Since plugin order matters, a plugin is added with a priority level,
552-
and are executed in descending order from highest to lowest.
585+
Since plugin order matters, a plugin is added with a priority level, and are executed in descending order from highest to lowest.
553586

554587
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).
555588

@@ -598,23 +631,8 @@ class YourApi extends Api
598631
}
599632
```
600633

601-
The same for the end user:
602-
603-
```php
604-
$api = new YourApi();
605-
606-
$api->getClientBuilder()->addPlugin(
607-
plugin: new RetryPlugin(['retries' => 3])
608-
priority: 12
609-
);
610-
```
611-
612634
### Cache (PSR-6)
613635

614-
> [!IMPORTANT]
615-
> The methods in this section are all public.
616-
> The purpose for that is to allow the end user to configure their own cache adapter.
617-
618636
This library allows configuring the cache layer of the client for making API requests.
619637
It uses a standard PSR-6 implementation and provides methods to fine-tune how HTTP caching behaves:
620638
- [PSR-6 compatible implementations](https://packagist.org/providers/psr/cache-implementation)
@@ -686,27 +704,8 @@ class YourApi extends Api
686704
}
687705
```
688706

689-
The same for the end user:
690-
691-
```php
692-
$api = new YourApi();
693-
694-
$pool = new FilesystemAdapter();
695-
696-
$api->setCacheBuilder(
697-
new CacheBuilder(
698-
pool: $pool,
699-
ttl: 3600
700-
)
701-
);
702-
```
703-
704707
### Logger (PSR-3)
705708

706-
> [!IMPORTANT]
707-
> The methods in this section are all public.
708-
> The purpose for that is to allow the end user to configure their own logger adapter.
709-
710709
This library allows configuring a logger to save data for making API requests.
711710
It uses a standard PSR-3 implementation and provides methods to fine-tune how logging behaves:
712711
- [PSR-3 compatible implementations](https://packagist.org/providers/psr/log-implementation)
@@ -764,21 +763,6 @@ class YourApi extends Api
764763
}
765764
```
766765

767-
The same for the end user:
768-
769-
```php
770-
$api = new YourApi();
771-
772-
$logger = new Logger('api');
773-
$logger->pushHandler(new StreamHandler('/logs/api.log'));
774-
775-
$api->setLoggerBuilder(
776-
new LoggerBuilder(
777-
logger: $logger
778-
)
779-
);
780-
```
781-
782766
### Configure Options
783767

784768
It is very common for APIs to offer different options (like language, timezone, etc.).

Diff for: src/Api.php

+14-14
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function __construct()
5555
* @throws ConfigException If a base URL has not been set.
5656
* @throws ClientException
5757
*/
58-
protected function request(
58+
public function request(
5959
string $method,
6060
string $path,
6161
array $query = [],
@@ -138,50 +138,50 @@ private function configurePlugins(): void
138138
}
139139
}
140140

141-
protected function getBaseUrl(): ?string
141+
public function getBaseUrl(): ?string
142142
{
143143
return $this->baseUrl;
144144
}
145145

146-
protected function setBaseUrl(string $baseUrl): self
146+
public function setBaseUrl(string $baseUrl): self
147147
{
148148
$this->baseUrl = $baseUrl;
149149

150150
return $this;
151151
}
152152

153-
protected function getQueryDefault(string $name): mixed
153+
public function getQueryDefault(string $name): mixed
154154
{
155155
return $this->queryDefaults[$name] ?? null;
156156
}
157157

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

162162
return $this;
163163
}
164164

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

169169
return $this;
170170
}
171171

172-
protected function getHeaderDefault(string $name): mixed
172+
public function getHeaderDefault(string $name): mixed
173173
{
174174
return $this->headerDefaults[$name] ?? null;
175175
}
176176

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

181181
return $this;
182182
}
183183

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

@@ -224,33 +224,33 @@ public function setLoggerBuilder(?LoggerBuilder $loggerBuilder): self
224224
return $this;
225225
}
226226

227-
protected function getAuthentication(): ?Authentication
227+
public function getAuthentication(): ?Authentication
228228
{
229229
return $this->authentication;
230230
}
231231

232-
protected function setAuthentication(?Authentication $authentication): self
232+
public function setAuthentication(?Authentication $authentication): self
233233
{
234234
$this->authentication = $authentication;
235235

236236
return $this;
237237
}
238238

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

243243
return $this;
244244
}
245245

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

250250
return $this;
251251
}
252252

253-
protected function buildPath(string $path, array $parameters): string
253+
public function buildPath(string $path, array $parameters): string
254254
{
255255
foreach ($parameters as $parameter => $value) {
256256
$path = \str_replace(

0 commit comments

Comments
 (0)