-
Notifications
You must be signed in to change notification settings - Fork 56
Refactor #39
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
Refactor #39
Changes from 2 commits
6d41a3d
bf2b8ea
97f4dab
e578b59
04dcb67
f66383f
a9a86f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Message Factory | ||
|
||
**Factory interfaces for PSR-7 HTTP Message.** | ||
|
||
|
||
## Rationale | ||
|
||
While it should be possible to use every PSR-7 aware HTTP client with any RequestInterface implementation, | ||
creating the request objects will still tie an application to a specific implementation. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/an application/the code/ ? we have to work hard on consistent wording: application is the thing the end user writes. the largest issue right here however is third party libraries. |
||
In the case of reusable libraries, an application could end up installing several request implementations. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If each reusable library is tied to a specific message implementation, an application could en up installing several message implementations. |
||
The factories abstract away from this. | ||
|
||
The FIG was pretty straightforward by NOT putting any construction logic into PSR-7. | ||
The `MessageFactory` aims to provide an easy way to construct messages. | ||
|
||
|
||
## Usage | ||
|
||
This package provides interfaces for PSR-7 factories including: | ||
|
||
- `MessageFactory` | ||
- `ServerRequestFactory` - WIP (PRs welcome) | ||
- `StreamFactory` | ||
- `UploadedFileFactory` - WIP (PRs welcome) | ||
- `UriFactory` | ||
|
||
|
||
A [virtual package](/httplug/virtual-package) ([php-http/message-factory-implementation](https://packagist.org/providers/php-http/message-factory-implementation)) | ||
MAY be introduced which MUST be versioned together with this package. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how do you mean may? does it exist or not? if it does not exist we should not confuse the reader. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At the time I wrote this, I didn't have an exact idea whether we should have a virtual package or not. Ideally message factories should come together with message implementations, so I would say we don't need a virtual package here. Also, we have our factories in the discovery layer. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i agree. lets try without it at least for now. most of the time it will
be the same adapter anyways.
|
||
|
||
The adapter repositories provide wrapper classes for those factories to | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. link to the adapters here? and why wrapper? i would say they provide these factories. (whether they do it by means of forwarding to other factories or by using what about clients, do they also provide factories? does every adapter provide factories? or are we creating confusion here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Honestly, I have no idea what this is. 😛 Probably it was about somehow wrapping specific implementations, but makes no sense. |
||
implement the `Http\Message\MessageFactory` interface. | ||
|
||
|
||
### General usage | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't get what this section is trying to explain. lets remove it (or add a concrete example) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tries to explain how to generally implement a Factory, but probably makes no sense. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. its a different layer of information. i think we should focus on how to
use the factories here
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree, removed it (which is not visible from email). |
||
|
||
``` php | ||
use Http\Message\SomeFactory; | ||
|
||
class MyFactory implements SomeFactory | ||
{ | ||
|
||
} | ||
``` |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# HTTPlug HTTP client abstraction | ||
|
||
HTTPlug is an abstraction for HTTP clients. There are two main use cases: | ||
|
||
1. Usage in a project/application | ||
2. Usage in a reusable package | ||
|
||
In both cases, the `Http\Client\HttpClient` provides a `sendRequest` method to send a PSR-7 `RequestInterface` | ||
and returns a PSR-7 `ResponseInterface`or throws an exception that implements `Http\Client\Exception`. | ||
|
||
There is also the `Http\Client\HttpAsyncClient` which provides the `sendAsyncRequest` method to send | ||
a request asynchronously and returns a `Http\Client\Promise`. | ||
|
||
It can be used later to retrieve a PSR-7 `ResponseInterface` or an exception that implements `Http\Client\Exception`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/It can be used later to retrieve/The promise allows to specify handlers for/ |
||
|
||
|
||
<p class="text-warning"> | ||
Contract for the `Http\Client\Promise` is temporary until | ||
[PSR is released](https://groups.google.com/forum/?fromgroups#!topic/php-fig/wzQWpLvNSjs). | ||
Once it is out, we will use this PSR in the main client and deprecate the old contract. | ||
</p> | ||
|
||
|
||
See the [tutorial](tutorial.md) for a concrete example. | ||
|
||
|
||
## HTTPlug implementations | ||
|
||
HTTPlug implementations typically are either HTTP clients of their own, or adapters wrapping existing clients | ||
like Guzzle 6. In the latter case, they will depend on the required client implementation, | ||
so you only need to require the adapter and not the actual client. | ||
|
||
|
||
There are two kind of implementations: | ||
|
||
- [php-http/client-implementation](https://packagist.org/providers/php-http/client-implementation): | ||
the synchronous implementation that waits for the response / error before returning from the `sendRequest` method. | ||
- [php-http/async-client-implementation](https://packagist.org/providers/php-http/async-client-implementation): | ||
the asynchronous implementation that immediately returns a `Http\Client\Promise`, | ||
allowing to send several requests in parallel and handling responses later. | ||
|
||
Check links above for the full list of implementations. | ||
|
||
<p class="text-warning"> | ||
Note: Until HTTPlug 1.0 becomes stable, we will focus on the Guzzle6 adapter. | ||
</p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i would say lets remove this box |
||
|
||
|
||
## Usage in a project | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Usage in an application ? |
||
|
||
When writing an application, you need to require a concrete | ||
[implementation](https://packagist.org/providers/php-http/client-implementation). | ||
|
||
See [virtual package](virtual-package.md) for more information on the topic of working with HTTPlug implementations. | ||
|
||
|
||
## Installation in a reusable package | ||
|
||
In many cases, packages are designed to be reused from the very beginning. | ||
For example, API clients are usually used in other packages/applications, not on their own. | ||
|
||
In these cases, they should **not rely on a concrete implementation** (like Guzzle 6), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/In these cases, they/Reusable packages/ |
||
but only require any implementation of HTTPlug. HTTPlug uses the concept of virtual packages. | ||
Instead of depending on only the interfaces, which would be missing an implementation, | ||
or depending on one concrete implementation, you should depend on the virtual package `php-http/client-implementation` | ||
or `php-http/async-client-implementation`. There is no package with that name, | ||
but all clients and adapters implementing HTTPlug declare that they provide one of this virtual package or both. | ||
|
||
You need to edit the `composer.json` of your package to add the virtual package. | ||
For development (installing the package standalone, running tests), | ||
add a concrete implementation in the `require-dev` section to make the project installable: | ||
|
||
``` json | ||
... | ||
"require": { | ||
"php-http/client-implementation": "^1.0" | ||
}, | ||
"require-dev": { | ||
"php-http/guzzle6-adapter": "^1.0" | ||
}, | ||
... | ||
``` | ||
|
||
For extra convenience, you can use the [Discovery Component](/components/discovery) system to free the user of your | ||
package from having to instantiate the client. | ||
You should however always accept injecting the client instance to allow the user to configure the client as needed. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we add a code sample here? i think this stays rather theoretical There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is explained in the Discover documentation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. then lets link to that example. maybe add to the paragraph above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The discovery component is already linked above. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i know, but i think we could be more explicit
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks, i think this is better, yes.
|
||
Users of your package will have to select a concrete adapter in their project to make your package installable. | ||
Best point them to the [virtual package](virtual-package.md) howto page. | ||
|
||
To be able to send requests, you should not depend on a specific PSR-7 implementation, | ||
but use the [Message Factory Component](/components/message-factory) system. | ||
|
||
|
||
### Framework Integration | ||
|
||
HTTPlug can be used in any PHP based project. | ||
Nonetheless, we provide particular integration for some popular frameworks: | ||
|
||
- [HttplugBundle](https://github.com/php-http/HttplugBundle/) integration with the Symfony framework. | ||
|
||
|
||
## History | ||
|
||
This project has been started by [Eric Geloen](https://github.com/egeloen) as | ||
Ivory Http Adapter](https://github.com/egeloen/ivory-http-adapter). It never made it to a stable release, | ||
but it relied on PSR-7 which was not stable either that time. Because of the constantly changing PSR-7, | ||
Eric had to rewrite the library over and over again (at least the message handling part, | ||
which in most cases affected every adapter as well). | ||
|
||
In 2015, a decision has been made to move the library to it's own organization, so PHP HTTP was born. | ||
|
||
See [migrating](migrating.md) for a guide how to migrate your code from the Ivory adapter to HTTPlug. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Migrating to HTTPlug | ||
|
||
If you currently use a concrete HTTP client implementation or the Ivory Http Adapter, | ||
migrating to Httplug should not be very hard. | ||
|
||
|
||
## Migrating from Ivory Http Adapter | ||
|
||
The monolithic ivory package has been separated into several smaller, more specific packages. | ||
|
||
Instead of `Ivory\HttpAdapter\PsrHttpAdapter`, use `Http\Client\HttpClient`. | ||
The HttpClient simply has a method to send requests. | ||
|
||
If you used the `Ivory\HttpAdapter\HttpAdapter`, have a look at the [Utilities](utils.md) | ||
and use the `Http\Client\Utils\HttpMethodsClient` which wraps any HttpClient and provides the convenience methods | ||
to send requests without creating RequestInterface instances. | ||
|
||
|
||
## Migrating from Guzzle | ||
|
||
Replace usage of `GuzzleHttp\ClientInterface` with `Http\Client\HttpClient`. | ||
The `send` method is called `sendRequest`. | ||
Instead of the `$options` argument, configure the client appropriately during set up. | ||
If you need different settings, create different instances of the client. | ||
You can use [plugins](plugins.md) to further tune your client. | ||
|
||
If you used the `request` method, have a look at the [Utilities](utils.md) and | ||
use the `Http\Client\Utils\HttpMethodsClient` which wraps any HttpClient and provides the convenience methods | ||
to send requests without creating RequestInterface instances. | ||
|
||
Asynchronous request support will land in HTTPlug soon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why remove the phpdoc explanation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it's an addition. The example code is pretty clean I think. I can add it back if you think it adds any value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.