1
1
Discovery
2
2
=========
3
3
4
- The discovery service is a set of static classes which allows to find and use installed resources.
5
- This is useful in libraries that want to offer zero-configuration services and rely only on the virtual packages.
4
+ The discovery service allows to find and use installed resources.
5
+ Under the hood it uses `Puli `_ for the discovery logic. All of our packages provide Puli resources.
6
+ Discovery is simply a convenience wrapper to statically access clients and factories for when
7
+ Dependency Injection is not an option. Discovery is useful in libraries that want to offer
8
+ zero-configuration services relying on the virtual packages. If you have Dependency Injection available,
9
+ using Puli directly is more elegant (see for example the Symfony HttplugBundle).
6
10
7
11
Currently available discovery services:
8
12
9
13
- HTTP Client Discovery
14
+ - HTTP Async Client Discovery
10
15
- PSR-7 Message Factory Discovery
11
16
- PSR-7 URI Factory Discovery
12
17
- PSR-7 Stream Factory Discovery
@@ -15,14 +20,34 @@ The principle is always the same: you call the static ``find`` method on the dis
15
20
implementation was specified. The discovery service will try to locate a suitable implementation.
16
21
If no implementation is found, an ``Http\Discovery\NotFoundException `` is thrown.
17
22
18
-
19
23
Installation
20
24
------------
21
25
26
+ There are two kinds of installation:
27
+
28
+ - In a reusable library
29
+ - In an application
30
+
31
+ In both cases you have to install the discovery package itself:
32
+
22
33
.. code-block :: bash
23
34
24
35
$ composer require php-http/discovery
25
36
37
+ As mentioned above, discovery relies on Puli. In order to use discovery, you need to also set up Puli.
38
+ The easiest way is installing the composer-plugin which automatically configures all the composer packages to act as
39
+ Puli modules:
40
+
41
+ .. code-block :: bash
42
+
43
+ $ composer require puli/composer-plugin
44
+
45
+ This is only necessary in an application. However, you might also want to install the composer-plugin as a development
46
+ dependency in reusable libraries as well (for example to use discovery in tests).
47
+
48
+ Read more about setting up Puli in their `official documentation `_.
49
+
50
+
26
51
HTTP Client Discovery
27
52
---------------------
28
53
@@ -123,53 +148,89 @@ This type of discovery finds a URI factory for a PSR-7_ URI implementation::
123
148
Integrating your own implementation with the discovery mechanism
124
149
----------------------------------------------------------------
125
150
126
- The ``php-http/discovery `` has built-in support for some implementations.
127
- To use a different implementation or override the default when several implementations are available in your code base,
128
- you can register a class explicitly with the corresponding discovery service. For example::
129
-
130
- HttpClientDiscovery::register('Acme\MyClient', true);
131
-
132
- - ``class ``: The class that is instantiated. This class MUST NOT require any constructor arguments.
133
- - ``condition ``: The condition that is evaluated to boolean to decide whether the class can be instantiated.
151
+ When you are working on an HTTP Client or Message Factory, you can easily make your class discoverable:
152
+ you have to configure it as a Puli resource (`binding `_ in Puli terminology).
134
153
135
- The following types are allowed:
136
- - string: Checked for class existence
137
- - callable: Called and evaluated to boolean
138
- - boolean: Can be true or false
139
- - any other: considered false
154
+ A binding must have a type, called `binding-type `_. All of our interfaces are registered as binding types.
140
155
141
- The condition can also be omitted. In that case the class is used as the condition ( to check for existence).
156
+ For example: a client `` Http\Client\MyClient `` should be bind to `` Http\Client\HttpClient ``
142
157
143
- Classes registered manually are put on top of the list .
158
+ Puli uses a `` puli.json `` file for configuration (placed in the package root) .
144
159
145
- Writing your own discovery
146
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
160
+ An example for a client's bindings::
147
161
148
- Each discovery service is based on the ``ClassDiscovery `` and has to specify a ``cache `` property and a ``class `` property
149
- to specify classes for the corresponding service. Since they are static, this properties need to be re-declared
150
- in each discovery class. If ``ClassDiscovery `` would declare them,
151
- they would be shared between the discovery classes which would make no sense.
152
-
153
- Here is an example discovery::
162
+ {
163
+ "version": "1.0",
164
+ "name": "php-http/guzzle6-adapter",
165
+ "bindings": {
166
+ "04b5a002-71a8-473d-a8df-75671551b84a": {
167
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
168
+ "class": "Http\\Adapter\\Guzzle6\\Client",
169
+ "type": "Http\\Client\\HttpClient"
170
+ },
171
+ "9c856476-7f6b-43df-a740-15420a5f839c": {
172
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
173
+ "class": "Http\\Adapter\\Guzzle6\\Client",
174
+ "type": "Http\\Client\\HttpAsyncClient"
175
+ }
176
+ }
177
+ }
154
178
155
- use Http\Discovery\ClassDiscovery;
179
+ And another for :doc: ` message factories < /message/message-factory >`::
156
180
157
- class MyDiscovery extends ClassDiscovery
158
181
{
159
- // IMPORTANT: not declared in the parent to avoid overwritting
160
- protected static $cache;
161
-
162
- // IMPORTANT: not declared in the parent
163
- protected static $classes = [];
182
+ "version": "1.0",
183
+ "name": "php-http/message",
184
+ "bindings": {
185
+ "2438c2d0-0658-441f-8855-ddaf0f87d54d": {
186
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
187
+ "class": "Http\\Message\\MessageFactory\\GuzzleMessageFactory",
188
+ "type": "Http\\Message\\MessageFactory",
189
+ "parameters": {
190
+ "depends": "GuzzleHttp\\Psr7\\Request"
191
+ }
192
+ },
193
+ "253aa08c-d705-46e7-b1d2-e28c97eef792": {
194
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
195
+ "class": "Http\\Message\\MessageFactory\\GuzzleMessageFactory",
196
+ "type": "Http\\Message\\RequestFactory",
197
+ "parameters": {
198
+ "depends": "GuzzleHttp\\Psr7\\Request"
199
+ }
200
+ },
201
+ "273a34f9-62f4-4ba1-9801-b1284d49ff89": {
202
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
203
+ "class": "Http\\Message\\StreamFactory\\GuzzleStreamFactory",
204
+ "type": "Http\\Message\\StreamFactory",
205
+ "parameters": {
206
+ "depends": "GuzzleHttp\\Psr7\\Stream"
207
+ }
208
+ },
209
+ "304b83db-b594-4d83-ae75-1f633adf92f7": {
210
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
211
+ "class": "Http\\Message\\UriFactory\\GuzzleUriFactory",
212
+ "type": "Http\\Message\\UriFactory",
213
+ "parameters": {
214
+ "depends": "GuzzleHttp\\Psr7\\Uri"
215
+ }
216
+ }
217
+ "a018af27-7590-4dcf-83a1-497f95604cd6": {
218
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
219
+ "class": "Http\\Message\\MessageFactory\\GuzzleMessageFactory",
220
+ "type": "Http\\Message\\ResponseFactory",
221
+ "parameters": {
222
+ "depends": "GuzzleHttp\\Psr7\\Response"
223
+ }
224
+ }
225
+ }
164
226
}
165
227
166
- A start value can be defined for the ``classes `` property in the following structure::
167
228
168
- [
169
- [
170
- 'class' => 'MyClass',
171
- 'condition' => 'MyCondition',
172
- ],
173
- ]
229
+ Puli provides a CLI tool for configuring bindings. It is necessary, because each binding must have a unique identifier.
230
+ Read more in Puli's documentation (`Providing Resources `_).
174
231
175
- The condition is as described above for ``register ``.
232
+ .. _`Puli` : http://puli.io
233
+ .. _official documentation : http://docs.puli.io/en/latest
234
+ .. _`binding` : http://docs.puli.io/en/latest/glossary.html#glossary-binding
235
+ .. _`binding-type` : http://docs.puli.io/en/latest/glossary.html#glossary-binding-type
236
+ .. _Providing Resources : http://docs.puli.io/en/latest/discovery/providing-resources.html
0 commit comments