Skip to content

Commit f76ccf6

Browse files
committed
Merge pull request #39 from php-http/refactor
Refactor documentation
2 parents f4072ba + a9a86f7 commit f76ccf6

22 files changed

+326
-287
lines changed

docs/discovery.md renamed to docs/components/discovery.md

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
# Discovery
22

3-
The discovery service is a set of static classes which allows to find and use installed resources. This is useful in libraries that want to offer zero-configuration services and rely only on the virtual packages, e.g. `php-http/client-implementation` or `psr/http-message-implementation`.
4-
3+
The discovery service is a set of static classes which allows to find and use installed resources.
4+
This is useful in libraries that want to offer zero-configuration services and rely only on the virtual packages.
55

66
Currently available discovery services:
77

88
- HTTP Client Discovery
99
- PSR-7 Message Factory Discovery
1010
- PSR-7 URI Factory Discovery
11+
- PSR-7 Stream Factory Discovery
12+
13+
The principle is always the same: you call the static `find` method on the discovery service if no explicit
14+
implementation was specified. The discovery service will try to locate a suitable implementation.
15+
If no implementation is found, an `Http\Discovery\NotFoundException` is thrown.
1116

12-
The principle is always the same: you call the static `find` method on the discovery service if no explicit implementation was specified. The discovery service will try to locate a suitable implementation. If no implementation is found, an `Http\Discovery\NotFoundException` is thrown.
1317

1418
## Installation
1519

1620
```
1721
$ composer require php-http/discovery
1822
```
1923

24+
2025
## HTTP Client Discovery
2126

2227
This type of discovery finds an HTTP Client implementation.
@@ -42,6 +47,7 @@ class MyClass
4247
}
4348
```
4449

50+
4551
## HTTP Async Client Discovery
4652

4753
This type of discovery finds a HTTP Async Client implementation.
@@ -67,9 +73,11 @@ class MyClass
6773
}
6874
```
6975

76+
7077
## PSR-7 Message Factory Discovery
7178

72-
This type of discovery finds a [message factory](message-factory.md) for a [PSR-7](http://www.php-fig.org/psr/psr-7/) Message implementation.
79+
This type of discovery finds a [message factory](message-factory.md)
80+
for a [PSR-7](http://www.php-fig.org/psr/psr-7/) Message implementation.
7381

7482
``` php
7583
use Http\Message\MessageFactory;
@@ -95,7 +103,7 @@ class MyClass
95103

96104
## PSR-7 URI Factory Discovery
97105

98-
This type of discovery finds a uri factory for a [PSR-7](http://www.php-fig.org/psr/psr-7/) URI implementation.
106+
This type of discovery finds a URI factory for a [PSR-7](http://www.php-fig.org/psr/psr-7/) URI implementation.
99107

100108
``` php
101109
use Http\Message\UriFactory;
@@ -121,14 +129,17 @@ class MyClass
121129

122130
## Integrating your own implementation with the discovery mechanism
123131

124-
The `php-http/discovery` has built-in support for some implementations. To use a different implementation or override the default when several implementations are available in your codebase, you can register a class explicitly with the corresponding discovery service. For example:
132+
The `php-http/discovery` has built-in support for some implementations.
133+
To use a different implementation or override the default when several implementations are available in your codebase,
134+
you can register a class explicitly with the corresponding discovery service. For example:
125135

126136
``` php
127137
HttpClientDiscovery::register('Acme\MyClient', true);
128138
```
129139

130140
- `class`: The class that is instantiated. This class MUST NOT require any constructor arguments.
131-
- `condition`: The condition that is evaluated to boolean to decide whether the class can be instantiated. The following types are allowed:
141+
- `condition`: The condition that is evaluated to boolean to decide whether the class can be instantiated.
142+
The following types are allowed:
132143
- string: Checked for class existence
133144
- callable: Called and evaluated to boolean
134145
- boolean: Can be true or false
@@ -141,8 +152,10 @@ Classes registered manually are put on top of the list.
141152

142153
### Writing your own discovery
143154

144-
Each discovery service is based on the `ClassDiscovery` and has to specify a `cache` property and a `class` property to specify classes for the corresponding service.
145-
Since they are static, this properties need to be redeclared in each discovery class. If `ClassDiscovery` would declare them, they would be shared between the discovery classes which would make no sense.
155+
Each discovery service is based on the `ClassDiscovery` and has to specify a `cache` property and a `class` property
156+
to specify classes for the corresponding service. Since they are static, this properties need to be redeclared
157+
in each discovery class. If `ClassDiscovery` would declare them,
158+
they would be shared between the discovery classes which would make no sense.
146159

147160
Here is an example discovery:
148161

docs/components/message-factory.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Message Factory
2+
3+
**Factory interfaces for PSR-7 HTTP Message.**
4+
5+
6+
## Rationale
7+
8+
While it should be possible to use every PSR-7 aware HTTP client with any RequestInterface implementation,
9+
creating the request objects will still tie the code to a specific implementation.
10+
If each reusable library is tied to a specific message implementation,
11+
an application could end up installing several message implementations.
12+
The factories abstract away from this.
13+
14+
The FIG was pretty straightforward by NOT putting any construction logic into PSR-7.
15+
The `MessageFactory` aims to provide an easy way to construct messages.
16+
17+
18+
## Usage
19+
20+
This package provides interfaces for PSR-7 factories including:
21+
22+
- `MessageFactory`
23+
- `ServerRequestFactory` - WIP (PRs welcome)
24+
- `StreamFactory`
25+
- `UploadedFileFactory` - WIP (PRs welcome)
26+
- `UriFactory`

docs/httplug.md

Lines changed: 0 additions & 69 deletions
This file was deleted.

docs/httplug/index.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# HTTPlug HTTP client abstraction
2+
3+
HTTPlug is an abstraction for HTTP clients. There are two main use cases:
4+
5+
1. Usage in a project/application
6+
2. Usage in a reusable package
7+
8+
In both cases, the `Http\Client\HttpClient` provides a `sendRequest` method to send a PSR-7 `RequestInterface`
9+
and returns a PSR-7 `ResponseInterface`or throws an exception that implements `Http\Client\Exception`.
10+
11+
There is also the `Http\Client\HttpAsyncClient` which provides the `sendAsyncRequest` method to send
12+
a request asynchronously and returns a `Http\Client\Promise`.
13+
14+
The promise allows to specify handlers for a PSR-7 `ResponseInterface`
15+
or an exception that implements `Http\Client\Exception`.
16+
17+
18+
<p class="text-warning">
19+
Contract for the `Http\Client\Promise` is temporary until
20+
[PSR is released](https://groups.google.com/forum/?fromgroups#!topic/php-fig/wzQWpLvNSjs).
21+
Once it is out, we will use this PSR in the main client and deprecate the old contract.
22+
</p>
23+
24+
25+
See the [tutorial](tutorial.md) for a concrete example.
26+
27+
28+
## HTTPlug implementations
29+
30+
HTTPlug implementations typically are either HTTP clients of their own, or adapters wrapping existing clients
31+
like Guzzle 6. In the latter case, they will depend on the required client implementation,
32+
so you only need to require the adapter and not the actual client.
33+
34+
35+
There are two kind of implementations:
36+
37+
- [php-http/client-implementation](https://packagist.org/providers/php-http/client-implementation):
38+
the synchronous implementation that waits for the response / error before returning from the `sendRequest` method.
39+
- [php-http/async-client-implementation](https://packagist.org/providers/php-http/async-client-implementation):
40+
the asynchronous implementation that immediately returns a `Http\Client\Promise`,
41+
allowing to send several requests in parallel and handling responses later.
42+
43+
Check links above for the full list of implementations.
44+
45+
46+
## Usage in an application
47+
48+
When writing an application, you need to require a concrete
49+
[implementation](https://packagist.org/providers/php-http/client-implementation).
50+
51+
See [virtual package](virtual-package.md) for more information on the topic of working with HTTPlug implementations.
52+
53+
54+
## Installation in a reusable package
55+
56+
In many cases, packages are designed to be reused from the very beginning.
57+
For example, API clients are usually used in other packages/applications, not on their own.
58+
59+
Reusable packages should **not rely on a concrete implementation** (like Guzzle 6),
60+
but only require any implementation of HTTPlug. HTTPlug uses the concept of virtual packages.
61+
Instead of depending on only the interfaces, which would be missing an implementation,
62+
or depending on one concrete implementation, you should depend on the virtual package `php-http/client-implementation`
63+
or `php-http/async-client-implementation`. There is no package with that name,
64+
but all clients and adapters implementing HTTPlug declare that they provide one of this virtual package or both.
65+
66+
You need to edit the `composer.json` of your package to add the virtual package.
67+
For development (installing the package standalone, running tests),
68+
add a concrete implementation in the `require-dev` section to make the project installable:
69+
70+
``` json
71+
...
72+
"require": {
73+
"php-http/client-implementation": "^1.0"
74+
},
75+
"require-dev": {
76+
"php-http/guzzle6-adapter": "^1.0"
77+
},
78+
...
79+
```
80+
81+
For extra convenience, you can use the [Discovery Component](/components/discovery) system to free the user of your
82+
package from having to instantiate the client.
83+
You should however always accept injecting the client instance to allow the user to configure the client as needed.
84+
You can find an example in the [Discovery Component](/components/discovery) documentation.
85+
86+
Users of your package will have to select a concrete adapter in their project to make your package installable.
87+
Best point them to the [virtual package](virtual-package.md) howto page.
88+
89+
To be able to send requests, you should not depend on a specific PSR-7 implementation,
90+
but use the [Message Factory Component](/components/message-factory) system.
91+
92+
93+
### Framework Integration
94+
95+
HTTPlug can be used in any PHP based project.
96+
Nonetheless, we provide particular integration for some popular frameworks:
97+
98+
- [HttplugBundle](https://github.com/php-http/HttplugBundle/) integration with the Symfony framework.
99+
100+
101+
## History
102+
103+
This project has been started by [Eric Geloen](https://github.com/egeloen) as
104+
Ivory Http Adapter](https://github.com/egeloen/ivory-http-adapter). It never made it to a stable release,
105+
but it relied on PSR-7 which was not stable either that time. Because of the constantly changing PSR-7,
106+
Eric had to rewrite the library over and over again (at least the message handling part,
107+
which in most cases affected every adapter as well).
108+
109+
In 2015, a decision has been made to move the library to it's own organization, so PHP HTTP was born.
110+
111+
See [migrating](migrating.md) for a guide how to migrate your code from the Ivory adapter to HTTPlug.

docs/httplug/migrating.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Migrating to HTTPlug
2+
3+
If you currently use a concrete HTTP client implementation or the Ivory Http Adapter,
4+
migrating to Httplug should not be very hard.
5+
6+
7+
## Migrating from Ivory Http Adapter
8+
9+
The monolithic ivory package has been separated into several smaller, more specific packages.
10+
11+
Instead of `Ivory\HttpAdapter\PsrHttpAdapter`, use `Http\Client\HttpClient`.
12+
The HttpClient simply has a method to send requests.
13+
14+
If you used the `Ivory\HttpAdapter\HttpAdapter`, have a look at the [Utilities](utils.md)
15+
and use the `Http\Client\Utils\HttpMethodsClient` which wraps any HttpClient and provides the convenience methods
16+
to send requests without creating RequestInterface instances.
17+
18+
19+
## Migrating from Guzzle
20+
21+
Replace usage of `GuzzleHttp\ClientInterface` with `Http\Client\HttpClient`.
22+
The `send` method is called `sendRequest`.
23+
Instead of the `$options` argument, configure the client appropriately during set up.
24+
If you need different settings, create different instances of the client.
25+
You can use [plugins](plugins.md) to further tune your client.
26+
27+
If you used the `request` method, have a look at the [Utilities](utils.md) and
28+
use the `Http\Client\Utils\HttpMethodsClient` which wraps any HttpClient and provides the convenience methods
29+
to send requests without creating RequestInterface instances.
30+
31+
Asynchronous request support will land in HTTPlug soon.

0 commit comments

Comments
 (0)