Skip to content

Commit 2ded870

Browse files
authored
Provide PSR-18 adapter (#19)
* Provide PSR-18 compatibility using an adapter #11 * Collapse code examples in documentation
1 parent f08c56d commit 2ded870

File tree

8 files changed

+1121
-219
lines changed

8 files changed

+1121
-219
lines changed

README.md

Lines changed: 204 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -11,162 +11,256 @@ __Table of contents__
1111
* [Get channel information](#get-channel-information)
1212
* [Delete a channel](#delete-a-channel)
1313
* [Nchan status information](#nchan-status-information)
14-
* [Use with authentication](#use-with-authentication)
15-
* [Exchange the provided http client](#exchange-the-provided-http-client)
14+
* [Authorize requests](#authorize-requests)
15+
* [PSR-18 compatibility](#psr-18-compatibility)
1616

1717
## Overview
1818

1919
This is a PHP client for [https://nchan.io](https://nchan.io).
2020

21-
This library provides a http client which has some authentication features. If you need more, you can for sure
22-
exchange this library with another like guzzle. Take a look below to
23-
"[Exchange the provided http client](#exchange-the-provided-http-client)".
24-
2521
## Installation and requirements
2622

2723
```
2824
composer require marein/php-nchan-client
2925
```
3026

31-
If you use the provided http client (default if you don't set anything),
32-
you must enable the php configuration
27+
If you want to use the
28+
[PSR-18 adapter](#psr-18-compatibility),
29+
install a library that implements PSR-18 http client
30+
([see here](https://packagist.org/providers/psr/http-client-implementation))
31+
and a library that implements PSR-17 http factories
32+
([see here](https://packagist.org/providers/psr/http-factory-implementation)).
33+
34+
If you want to use the built-in http client (default if you don't set anything),
35+
enable the php configuration
3336
[allow_url_fopen](http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen).
3437

3538
## Usage
3639

37-
### Publish a message
38-
39-
```php
40-
<?php
41-
42-
namespace {
40+
The following code examples use the built-in http client.
4341

44-
use Marein\Nchan\Api\Model\PlainTextMessage;
45-
use Marein\Nchan\Nchan;
46-
47-
include '/path/to/autoload.php';
48-
49-
$nchan = new Nchan('http://my-nchan-domain');
50-
$channel = $nchan->channel('/path-to-publisher-endpoint');
51-
$channelInformation = $channel->publish(
52-
new PlainTextMessage(
53-
'my-message-name',
54-
'my message content'
55-
)
56-
);
42+
### Publish a message
5743

58-
// Nchan returns some channel information after publishing a message.
59-
var_dump($channelInformation);
60-
}
61-
```
44+
<details>
45+
<summary>Show code</summary>
6246

63-
### Get channel information
47+
```php
48+
<?php
6449

65-
```php
66-
<?php
50+
namespace {
6751

68-
namespace {
52+
use Marein\Nchan\Api\Model\PlainTextMessage;
53+
use Marein\Nchan\Nchan;
6954

70-
use Marein\Nchan\Nchan;
55+
include '/path/to/autoload.php';
7156

72-
include '/path/to/autoload.php';
57+
$nchan = new Nchan('http://my-nchan-domain');
58+
$channel = $nchan->channel('/path-to-publisher-endpoint');
59+
$channelInformation = $channel->publish(
60+
new PlainTextMessage(
61+
'my-message-name',
62+
'my message content'
63+
)
64+
);
7365

74-
$nchan = new Nchan('http://my-nchan-domain');
75-
$channel = $nchan->channel('/path-to-publisher-endpoint');
76-
$channelInformation = $channel->information();
66+
// Nchan returns some channel information after publishing a message.
67+
var_dump($channelInformation);
68+
}
69+
```
70+
</details>
7771

78-
var_dump($channelInformation);
79-
}
80-
```
72+
### Get channel information
8173

82-
### Delete a channel
74+
<details>
75+
<summary>Show code</summary>
8376

84-
```php
85-
<?php
77+
```php
78+
<?php
8679

87-
namespace {
80+
namespace {
8881

89-
use Marein\Nchan\Nchan;
82+
use Marein\Nchan\Nchan;
9083

91-
include '/path/to/autoload.php';
84+
include '/path/to/autoload.php';
9285

93-
$nchan = new Nchan('http://my-nchan-domain');
94-
$channel = $nchan->channel('/path-to-publisher-endpoint');
95-
$channel->delete();
96-
}
97-
```
86+
$nchan = new Nchan('http://my-nchan-domain');
87+
$channel = $nchan->channel('/path-to-publisher-endpoint');
88+
$channelInformation = $channel->information();
9889

99-
### Nchan status information
90+
var_dump($channelInformation);
91+
}
92+
```
93+
</details>
10094

101-
First you have to create a location with the `nchan_stub_status directive`. Then you can query it.
95+
### Delete a channel
10296

103-
```php
104-
<?php
97+
<details>
98+
<summary>Show code</summary>
10599

106-
namespace {
100+
```php
101+
<?php
107102

108-
use Marein\Nchan\Nchan;
103+
namespace {
109104

110-
include '/path/to/autoload.php';
105+
use Marein\Nchan\Nchan;
111106

112-
$nchan = new Nchan('http://my-nchan-domain');
113-
$status = $nchan->status('/path-to-status-location');
114-
$statusInformation = $status->information();
107+
include '/path/to/autoload.php';
115108

116-
var_dump($statusInformation);
117-
}
118-
```
109+
$nchan = new Nchan('http://my-nchan-domain');
110+
$channel = $nchan->channel('/path-to-publisher-endpoint');
111+
$channel->delete();
112+
}
113+
```
114+
</details>
119115

120-
### Use with authentication
116+
### Nchan status information
121117

122-
Nchan gives you the possibility to authenticate endpoints with the `nchan_authorize_request` directive.
123-
The provided http client supports basic and bearer authentication. It needs to be setup as follows.
118+
Endpoints with the `nchan_stub_status` directive can be queried as follows.
124119

125-
```php
126-
<?php
120+
<details>
121+
<summary>Show code</summary>
127122

128-
namespace {
123+
```php
124+
<?php
129125

130-
use Marein\Nchan\HttpAdapter\HttpStreamWrapperClient;
131-
use Marein\Nchan\HttpAdapter\BasicAuthenticationCredentials;
132-
use Marein\Nchan\HttpAdapter\BearerAuthenticationCredentials;
133-
use Marein\Nchan\Nchan;
126+
namespace {
134127

135-
include '/path/to/autoload.php';
128+
use Marein\Nchan\Nchan;
136129

137-
// Client with basic authentication
138-
$adapter = new HttpStreamWrapperClient(
139-
new BasicAuthenticationCredentials('nchan', 'password')
140-
);
130+
include '/path/to/autoload.php';
141131

142-
// Client with bearer authentication
143-
$adapter = new HttpStreamWrapperClient(
144-
new BearerAuthenticationCredentials('my-token')
145-
);
132+
$nchan = new Nchan('http://my-nchan-domain');
133+
$status = $nchan->status('/path-to-status-location');
134+
$statusInformation = $status->information();
146135

147-
$nchan = new Nchan('http://my-nchan-domain', $adapter);
148-
}
136+
var_dump($statusInformation);
137+
}
149138
```
139+
</details>
150140

151-
The
152-
`\Marein\Nchan\HttpAdapter\HttpStreamWrapperClient`
153-
class constructor takes an implementation of type
154-
`\Marein\Nchan\HttpAdapter\Credentials`.
155-
As long as you implement that interface, you can build your own authentication
156-
method. Take a look at
157-
`\Marein\Nchan\HttpAdapter\BasicAuthenticationCredentials`
158-
to see how this works.
159-
160-
## Exchange the provided http client
161-
162-
Sometimes, the provided client is not enough and you want to use features from other libraries like guzzle.
163-
You can exchange the http client easily because of the
164-
`\Marein\Nchan\Http\Client`
165-
interface. I've created a guzzle adapter
166-
for those who want to use guzzle. This is also a good example to look at, if you want to use another library. The
167-
guzzle adapter lives at
168-
[marein/php-nchan-client-guzzle-adapter](https://github.com/marein/php-nchan-client-guzzle-adapter).
169-
170-
Another good reason to exchange the provided client is to gain performance, since the client uses the http stream wrapper
171-
from php. There is a little overhead because the tcp connection gets closed after each request. Other implementations,
172-
like guzzle, can keep the connection alive.
141+
### Authorize requests
142+
143+
Endpoints with the `nchan_authorize_request` directive must be authorized.
144+
The constructor of the
145+
[built-in http client](/src/HttpAdapter/HttpStreamWrapperClient.php)
146+
takes an implementation of type
147+
[Credentials](/src/HttpAdapter/Credentials.php).
148+
This library comes with 2 built-in implementations,
149+
[BasicAuthenticationCredentials](/src/HttpAdapter/BasicAuthenticationCredentials.php)
150+
and
151+
[BearerAuthenticationCredentials](/src/HttpAdapter/BearerAuthenticationCredentials.php).
152+
153+
<details>
154+
<summary>Show code</summary>
155+
156+
```php
157+
<?php
158+
159+
namespace {
160+
161+
use Marein\Nchan\HttpAdapter\BasicAuthenticationCredentials;
162+
use Marein\Nchan\HttpAdapter\BearerAuthenticationCredentials;
163+
use Marein\Nchan\HttpAdapter\HttpStreamWrapperClient;
164+
use Marein\Nchan\Nchan;
165+
166+
include '/path/to/autoload.php';
167+
168+
// Client with basic authentication
169+
$adapter = new HttpStreamWrapperClient(
170+
new BasicAuthenticationCredentials('nchan', 'password')
171+
);
172+
173+
// Client with bearer authentication
174+
$adapter = new HttpStreamWrapperClient(
175+
new BearerAuthenticationCredentials('my-token')
176+
);
177+
178+
$nchan = new Nchan('http://my-nchan-domain', $adapter);
179+
}
180+
```
181+
</details>
182+
183+
If you use another http client through the
184+
[PSR-18 adapter](#psr-18-compatibility),
185+
the respective http client has its own extension points to modify the request before it is sent.
186+
187+
## PSR-18 compatibility
188+
189+
This library comes with a PSR-18 compatible
190+
[adapter](/src/HttpAdapter/Psr18ClientAdapter.php).
191+
There are good reasons not to use the built-in client.
192+
It's based on the http stream wrapper and `file_get_contents`.
193+
This closes the TCP connection after each request.
194+
Other clients, see below, can keep the connection open.
195+
196+
The following example uses
197+
[guzzlehttp/guzzle](https://packagist.org/packages/guzzlehttp/guzzle)
198+
and
199+
[guzzlehttp/psr7](https://packagist.org/packages/guzzlehttp/psr7).
200+
201+
<details>
202+
<summary>Show code</summary>
203+
204+
```php
205+
<?php
206+
207+
namespace {
208+
209+
use GuzzleHttp\Client;
210+
use GuzzleHttp\Psr7\HttpFactory;
211+
use Marein\Nchan\HttpAdapter\Psr18ClientAdapter;
212+
use Marein\Nchan\Nchan;
213+
214+
include '/path/to/autoload.php';
215+
216+
$nchan = new Nchan(
217+
'http://my-nchan-domain',
218+
new Psr18ClientAdapter(
219+
new Client(),
220+
new HttpFactory(),
221+
new HttpFactory()
222+
)
223+
);
224+
}
225+
```
226+
</details>
227+
228+
The following code example uses
229+
[symfony/http-client](https://packagist.org/packages/symfony/http-client)
230+
and
231+
[nyholm/psr7](https://packagist.org/packages/nyholm/psr7).
232+
233+
<details>
234+
<summary>Show code</summary>
235+
236+
```php
237+
<?php
238+
239+
namespace {
240+
241+
use Marein\Nchan\HttpAdapter\Psr18ClientAdapter;
242+
use Marein\Nchan\Nchan;
243+
use Nyholm\Psr7\Factory\Psr17Factory;
244+
use Symfony\Component\HttpClient\HttpClient;
245+
use Symfony\Component\HttpClient\Psr18Client;
246+
247+
include '/path/to/autoload.php';
248+
249+
// Symfony itself needs an adapter to be PSR-18 compliant.
250+
$httpClient = new Psr18Client(
251+
HttpClient::create(),
252+
new Psr17Factory(),
253+
new Psr17Factory()
254+
);
255+
256+
$nchan = new Nchan(
257+
'http://my-nchan-domain',
258+
new Psr18ClientAdapter(
259+
$httpClient,
260+
$httpClient,
261+
$httpClient
262+
)
263+
);
264+
}
265+
```
266+
</details>

composer.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,17 @@
2020
},
2121
"require": {
2222
"php": "^7.4 || ^8.0",
23-
"ext-json": "*"
23+
"ext-json": "*",
24+
"psr/http-client": "^1.0",
25+
"psr/http-message": "^1.0",
26+
"psr/http-factory": "^1.0"
2427
},
2528
"require-dev": {
2629
"phpunit/phpunit": "^9.5",
2730
"symfony/process": "^5.4",
2831
"squizlabs/php_codesniffer": "^3.6",
29-
"phpstan/phpstan": "^1.2"
32+
"phpstan/phpstan": "^1.2",
33+
"symfony/http-client": "^5.4",
34+
"nyholm/psr7": "^1.5"
3035
}
3136
}

0 commit comments

Comments
 (0)