@@ -10,8 +10,6 @@ Install the plugin client in your project with Composer_:
1010
1111 $ composer require php-http/plugins
1212
13-
14-
1513 How it works
1614------------
1715
@@ -69,105 +67,61 @@ The recommended way to order plugins is the following:
6967
7068.. note ::
7169
72- There can be exceptions to these rules. For example,
73- for security reasons you might not want to log the authentication information (like `Authorization ` header)
74- and choose to put the Authentication Plugin after the Logger Plugin.
75-
76- Implement your own
77- ------------------
70+ There can be exceptions to these rules. For example, for security reasons you might not want
71+ to log the authentication information (like ``Authorization `` header) and choose to put the
72+ :doc: `Authentication Plugin <authentication >` after the doc:`Logger Plugin <logger> `.
7873
79- When writing your own Plugin, you need to be aware that the Plugin Client is async first.
80- This means that every plugin must be written with Promises. More about this later.
8174
82- Each plugin must implement the ``Http\Client\Plugin\Plugin `` interface.
75+ Configuration Options
76+ ---------------------
8377
84- This interface defines the `` handleRequest `` method that allows to modify behavior of the call::
78+ The PluginClient accepts an array of configuration options that can tweak its behavior.
8579
86- /**
87- * Handles the request and returns the response coming from the next callable.
88- *
89- * @param RequestInterface $request Request to use.
90- * @param callable $next Callback to call to have the request, it muse have the request as it first argument.
91- * @param callable $first First element in the plugin chain, used to to restart a request from the beginning.
92- *
93- * @return Promise
94- */
95- public function handleRequest(RequestInterface $request, callable $next, callable $first);
80+ .. _plugin-client.max-restarts :
9681
97- The `` $request `` comes from an upstream plugin or Plugin Client itself.
98- You can replace it and pass a new version downstream if you need.
82+ `` max_restarts ``: int (default 10)
83+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9984
100- .. note ::
101-
102- Be aware that the request is immutable .
85+ To prevent issues with faulty plugins or endless redirects, the `` PluginClient `` injects a security
86+ check to the start of the plugin chain. If the same request is restarted more than specified by
87+ that value, execution is aborted and an error is raised .
10388
104- The ``$next `` callable is the next plugin in the execution chain. When you need to call it, you must pass the ``$request ``
105- as the first argument of this callable.
89+ .. _plugin-client.libraries :
10690
107- For example a simple plugin setting a header would look like this::
91+ Libraries that Require Plugins
92+ ------------------------------
10893
109- public function handleRequest(RequestInterface $request, callable $next, callable $first)
110- {
111- $newRequest = $request->withHeader('MyHeader', 'MyValue');
94+ When :doc: `writing a library based on HTTPlug <../httplug/library-developers >`, you might require
95+ specific plugins to be active. The recommended way for doing this is to provide a factory method
96+ for the ``PluginClient `` that your library users should use. This allows them to inject their own
97+ plugins or configure a different client. For example::
11298
113- return $next($newRequest);
114- }
99+ $myApiClient = new My\Api\Client('https://api.example.org', My\Api\HttpClientFactory::create('john', 's3cr3t'));
115100
116- The ``$first `` callable is the first plugin in the chain. It allows you to completely reboot the execution chain, or send
117- another request if needed, while still going through all the defined plugins.
118- Like in case of the ``$next `` callable, you must pass the ``$request `` as the first argument::
101+ use Http\Client\HttpClient;
102+ use Http\Discovery\HttpClientDiscovery;
119103
120- public function handleRequest(RequestInterface $request, callable $next, callable $first)
104+ class HttpClientFactory
121105 {
122- if ($someCondition) {
123- $newRequest = new Request();
124- $promise = $first($newRequest);
125-
126- // Use the promise to do some jobs ...
106+ /**
107+ * Build the HTTP client to talk with the API.
108+ *
109+ * @param string $user Username
110+ * @param string $pass Password
111+ * @param HttpClient $client Base HTTP client
112+ *
113+ * @return HttpClient
114+ */
115+ public static function create($user, $pass, HttpClient $client = null)
116+ {
117+ if (!$client) {
118+ $client = HttpClientDiscovery::find();
119+ }
120+ return new PluginClient($client, [
121+ new Http\Client\Plugin\ErrorPlugin(),
122+ new AuthenticationPlugin(
123+ // This API has it own authentication algorithm
124+ new ApiAuthentication(Client::AUTH_OAUTH_TOKEN, $user, $pass)
125+ ),
126+ ]);
127127 }
128-
129- return $next($request);
130- }
131-
132- .. warning ::
133-
134- In this example the condition is not superfluous:
135- you need to have some way to not call the ``$first `` callable each time
136- or you will end up in an infinite execution loop.
137-
138- The ``$next `` and ``$first `` callables will return a :doc: `/components/promise `.
139- You can manipulate the ``ResponseInterface `` or the ``Exception `` by using the
140- ``then `` method of the promise::
141-
142- public function handleRequest(RequestInterface $request, callable $next, callable $first)
143- {
144- $newRequest = $request->withHeader('MyHeader', 'MyValue');
145-
146- return $next($request)->then(function (ResponseInterface $response) {
147- return $response->withHeader('MyResponseHeader', 'value');
148- }, function (Exception $exception) {
149- echo $exception->getMessage();
150-
151- throw $exception;
152- });
153- }
154-
155- .. warning ::
156-
157- Contract for the ``Http\Promise\Promise `` is temporary until a
158- PSR _ is released. Once it is out, we will use this PSR in HTTPlug and
159- deprecate the old contract.
160-
161- To better understand the whole process check existing implementations in the
162- `plugin repository `_.
163-
164- Contribution
165- ------------
166-
167- We are always open to contributions. Either in form of Pull Requests to the core package or self-made plugin packages.
168- We encourage everyone to prefer sending Pull Requests, however we don't promise that every plugin gets
169- 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
170- the core as small as possible with the most widely used plugin implementations.
171-
172- .. _PSR : https://groups.google.com/forum/?fromgroups#!topic/php-fig/wzQWpLvNSjs
173- .. _plugin repository : https://github.com/php-http/plugins
0 commit comments