Skip to content

Add initial documentation #38

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

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/contribution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Contribution

We are always open to contributions. Either in form of Pull Requests to the core package or self-made plugin packages.
We encourage everyone to prefer sending Pull Requests, however we don't promise that every plugin gets
merged into the core. If this is the case, it is not because we think your work is not good enough. We try to keep
the core as small as possible with the most widely used plugin implementations.

Even if we think that a plugin is not suitable for the core, we want to help you sharing your work with the community.
You can always open a Pull Request to place a link and a small description of your plugin on the
[Third Party Plugins](third-party-plugins.md) page. In special cases,
we might offer you to host your package under the PHP HTTP namespace.

For more details about contribution, please see our
[contribution guide](http://docs.httplug.io/en/latest/contributing/).
6 changes: 6 additions & 0 deletions docs/css/extra.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Exclude first title from TOC
*/
li.toctree-l3:first-child {
display: none;
}
Binary file added docs/favicon.ico
Binary file not shown.
92 changes: 92 additions & 0 deletions docs/implement-your-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Implement your own

When writing your own Plugin, you need to be aware that the Plugin Client is async first.
This means that every plugin must be written with Promises. More about this later.

Each plugin must implement the `Http\Client\Plugin\Plugin` interface.

This interface defines the `handleRequest` method that allows to modify behavior of the call:

```php
/**
* Handles the request and returns the response coming from the next callable.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this actually true? I mean a plugin could also replace the response coming from the next callable (for example, to filter it), couldn't it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you also do something like that (modifying the response) in one example below.

*
* @param RequestInterface $request Request to use.
* @param callable $next Callback to call to have the request, it muse have the request as it first argument.
* @param callable $first First element in the plugin chain, used to to restart a request from the beginning.
*
* @return Promise
*/
public function handleRequest(RequestInterface $request, callable $next, callable $first);
```

The `$request` comes from an upstream plugin or Plugin Client itself.
You can replace it and pass a new version downstream if you need.

!!! note "Note:"
Be aware that the request is immutable.


The `$next` callable is the next plugin in the execution chain. When you need to call it, you must pass the `$request`
as the first argument of this callable.

For example a simple plugin setting a header would look like this:

``` php
public function handleRequest(RequestInterface $request, callable $next, callable $first)
{
$newRequest = $request->withHeader('MyHeader', 'MyValue');

return $next($newRequest);
}
```

The `$first` callable is the first plugin in the chain. It allows you to completely reboot the execution chain, or send
other request if needed, while still going through all the defined plugins.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[...] another request [...] or [...] other requests [...]

Like in case of the `$next` callable, you must pass the `$request` as the first argument.

```
public function handleRequest(RequestInterface $request, callable $next, callable $first)
{
if ($someCondition) {
$newRequest = new Request();
$promise = $first($newRequest);

// Use the promise do some jobs ...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[...] promise to do [...]

}

return $next($request);
}
```

!!! warning "Warning:"
In this example the condition is not superfluous:
you need to have some way to not call the `$first` callable each time
or you will end up in an infinite execution loop.

The `$next` and `$first` callable will return a Promise (defined in `php-http/promise`).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

callables

You can manipulate the `ResponseInterface` or the `Exception` by using the `then` method of the promise.

```
public function handleRequest(RequestInterface $request, callable $next, callable $first)
{
$newRequest = $request->withHeader('MyHeader', 'MyValue');

return $next($request)->then(function (ResponseInterface $response) {
return $response->withHeader('MyResponseHeader', 'value');
}, function (Exception $exception) {
echo $exception->getMessage();

throw $exception;
});
}
```

!!! warning "Warning:"
Contract for the `Http\Promise\Promise` is temporary until
[PSR is released](https://groups.google.com/forum/?fromgroups#!topic/php-fig/wzQWpLvNSjs).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[...] until a PSR [...]

Once it is out, we will use this PSR in HTTPlug and deprecate the old contract.


To better understand the whole process check existing implementations in the
[plugin repository](https://github.com/php-http/plugins).
79 changes: 79 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# HTTPlug Plugins

[HTTPlug](http://httplug.io) is an HTTP Client abstraction layer for PHP.

The plugin system allows to wrap a Client and add some processing logic prior to and/or after sending the actual
request or you can even start a completely new request. This gives you full control over what happens in your workflow.


## Install

Install the plugin client in your project with [Composer](https://getcomposer.org/):

``` bash
$ composer require "php-http/plugins"
```


## How it works

In the plugin package, you can find the following content:

- the Plugin Client itself which acts as a wrapper around any kind of HTTP Client (sync/async)
- a Plugin interface
- a set of core plugins (see the full list in the left side navigation)

The Plugin Client accepts an HTTP Client implementation and an array of plugins.

Let's see an example:

``` php
use Http\Discovery\HttpClientDiscovery;
use Http\Client\Plugin\PluginClient;
use Http\Client\Plugin\RetryPlugin;
use Http\Client\Plugin\RedirectPlugin;

$retryPlugin = new RetryPlugin();
$redirectPlugin = new RedirectPlugin();

$pluginClient = new PluginClient(
HttpClientDiscovery::find(),
[
$retryPlugin,
$redirectPlugin,
]
);
```

The Plugin Client accepts and implements both `Http\Client\HttpClient` and `Http\Client\HttpAsyncClient`, so you can use
both ways to send a request. In case the passed client implements only one of these interfaces, the Plugin Client
"emulates" the other behavior as a fallback.

It is important, that the order of plugins matter. During the request, plugins are called in the order they have
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

matters

been added, from first to last. Once a response has been received, they are called again in a reversed order,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[...] in reversed order [...]

from last to first.

In case of our previous example, the execution chain will look like this:

```
Request ---> PluginClient ---> RetryPlugin ---> RedirectPlugin ---> HttpClient ----
| (processing call)
Response <--- PluginClient <--- RetryPlugin <--- RedirectPlugin <--- HttpClient <---
```

In order to have correct behavior over the global process, you need to understand well how each plugin used,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[...] plugin is used [...]

and manage a correct order when passing the array to the Plugin Client.

Retry Plugin will be best at the end to optimize the retry process, but it can also be good
to have it as the first plugin, if one of the plugins is inconsistent and may need a retry.

The recommended way to order plugins is the following:

1. Plugins that modify the request should be at the beginning (like Authentication or Cookie Plugin)
2. Plugins which intervene in the workflow should be in the "middle" (like Retry or Redirect Plugin)
3. Plugins which log information should be last (like Logger or History Plugin)

!!! note "Note:"
There can be exceptions to these rules. For example,
for security reasons you might not want to log the authentication information (like `Authorization` header)
and choose to put the Authentication Plugin after the Logger Plugin.
23 changes: 23 additions & 0 deletions docs/plugins/authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Authentication Plugin

This plugin uses the [authentication component](http://docs.httplug.io/en/latest/components/authentication/)
from `php-http/message` to authenticate requests sent through the client.


``` php
use Http\Discovery\HttpClientDiscovery;
use Http\Message\Authentication\BasicAuth;
use Http\Plugins\PluginClient;
use Http\Plugins\AuthenticationPlugin;

$authentication = new BasicAuth('username', 'password');
$authenticationPlugin = new AuthenticationPlugin($authentication);

$pluginClient = new PluginClient(
HttpClientDiscovery::find(),
[$authenticationPlugin]
);
```

Check the [authentication component documentation](http://docs.httplug.io/en/latest/components/authentication/)
for the list of available authentication methods.
3 changes: 3 additions & 0 deletions docs/plugins/cookie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Cookie Plugin

TODO: explain the cookie plugin
3 changes: 3 additions & 0 deletions docs/plugins/encoding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Encoding Plugin

TODO: explain the encoding plugin
3 changes: 3 additions & 0 deletions docs/plugins/error.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Error Plugin

TODO: explain the error plugin
3 changes: 3 additions & 0 deletions docs/plugins/redirect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Redirect Plugin

TODO: explain the redirect plugin
3 changes: 3 additions & 0 deletions docs/plugins/retry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Retry Plugin

TODO: explain the retry plugin
3 changes: 3 additions & 0 deletions docs/plugins/stopwatch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Stopwatch Plugin

TODO: explain the stopwatch plugin
1 change: 1 addition & 0 deletions docs/third-party-plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Third Party Plugins
11 changes: 11 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
site_name: HTTPlug Plugins Documentation
site_favicon: favicon.ico
copyright: © 2015 PHP HTTP Team
theme: readthedocs
extra_css:
- css/extra.css
markdown_extensions:
- toc:
permalink: true
- sane_lists
- admonition