Skip to content

Commit

Permalink
Merge pull request #10 from php-http/refactor-doc
Browse files Browse the repository at this point in the history
reorganizing the documentation
  • Loading branch information
dbu committed Oct 29, 2015
2 parents c2e2b1c + db09618 commit a292396
Show file tree
Hide file tree
Showing 13 changed files with 270 additions and 178 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# HTTP Adapter Documentation
# PHP-HTTP Documentation

[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)


**This is the documentation repository of the HTTP Adapter software components**
**This is the documentation repository of the PHP-HTTP software components**

Browse the documentation on [Read the Docs](http://php-http.readthedocs.org/).
44 changes: 14 additions & 30 deletions docs/discovery.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,46 @@
# Discovery

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/adapter-implementation` or `psr/http-message-implementation`.
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`.


Currently available discovery services:

- HTTP Adapter Discovery
- HTTP client Discovery
- PSR-7 Message Factory Discovery
- PSR-7 URI Factory Discovery

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.


## HTTP Adapter Discovery
## HTTP Client Discovery

This type of discovery finds installed HTTP Adapters.

Currently available adapters:

- [Guzzle 6](https://github.com/php-http/guzzle6-adapter)
- [Guzzle 5](https://github.com/php-http/guzzle5-adapter)
This type of discovery finds installed HTTP Clients.

``` php
use Http\Adapter\HttpAdapter;
use Http\Discovery\HttpAdapterDiscovery;
use Http\Client\HttpClient;
use Http\Discovery\HttpClientDiscovery;

class MyClass
{
/**
* @var HttpAdapter
* @var HttpClient
*/
protected $httpAdapter;
protected $httpClient;

/**
* @param HttpAdapter|null $httpAdapter to do HTTP requests.
* @param HttpClient|null $httpClient to do HTTP requests.
*/
public function __construct(HttpAdapter $httpAdapter = null)
public function __construct(HttpClient $httpClient = null)
{
$this->httpAdapter = $httpAdapter ?: HttpAdapterDiscovery::find();
$this->httpClient = $httpClient ?: HttpClientDiscovery::find();
}
}
```


## PSR-7 Message Factory Discovery

This type of discovery finds installed [PSR-7](http://www.php-fig.org/psr/psr-7/) Message implementations and their factories.

Currently available factories:

- [Guzzle](https://github.com/guzzle/psr7) factory
- [Diactoros](https://github.com/zendframework/zend-diactoros) factory

This type of discovery finds installed [PSR-7](http://www.php-fig.org/psr/psr-7/) Message implementations and their (factories)[message-factory.md].

``` php
use Http\Message\MessageFactory;
Expand All @@ -74,16 +63,11 @@ class MyClass
}
```


## PSR-7 URI Factory Discovery

This type of discovery finds installed [PSR-7](http://www.php-fig.org/psr/psr-7/) URI implementations and their factories.

Currently available factories:

- [Guzzle](https://github.com/guzzle/psr7) factory
- [Diactoros](https://github.com/zendframework/zend-diactoros) factory


``` php
use Http\Message\UriFactory;
use Http\Discovery\UriFactoryDiscovery;
Expand Down Expand Up @@ -111,7 +95,7 @@ class MyClass
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:

``` php
HttpAdapterDiscovery::register('Acme\MyAdapter', true);
HttpClientDiscovery::register('Acme\MyClient', true);
```

- `class`: The class that is instantiated. This class MUST NOT require any constructor arguments.
Expand Down
53 changes: 53 additions & 0 deletions docs/httplug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Httplug HTTP client abstraction

Httplug is an abstraction for HTTP clients. There are two main use cases:

1. Usage in a project
2. Usage in a reusable package

In both cases, the client 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`.

See the (tutorial)[tutorial.md] for a concrete example.


## Httplug implementations

Httplug implementations typically are either HTTP clients of their own, or they are 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.

See (packagist)[https://packagist.org/providers/php-http/client-implementation] for the full list of implementations.

Note: Until Httplug 1.0 becomes stable, we will focus on the Guzzle6 adapter.

## Usage in a project

When writing an application, you should require a concrete client implementation. The client will in turn depend on `php-http/httplug`.

A few things should be taken into consideration before choosing an adapter:

- It is possible that some other dependency already has an HTTP Client requirement like Guzzle 6. It can be confusing to have more than one HTTP Client installed, so always check your other requirements and choose an adapter based on that.


## 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), 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`. There is no package with that name, but all clients and adapters implementing Httplug declare that they provide this virtual package.

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)[discovery.md] 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.

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)[message-factory.md] system.
86 changes: 17 additions & 69 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,87 +1,35 @@
# HTTP Adapter
# PHP-HTTP Httplug

**This is the documentation for HTTP Adapter and it's software components.**
**This is the documentation for the Httplug HTTP client abstraction and the other PHP-HTTP components.**

The HTTP Adapter abstracts from PHP HTTP clients that are based on [PSR-7](http://www.php-fig.org/psr/psr-7/).
It allows you to write reusable libraries and applications that need a HTTP client without binding to a specific implementation.
[PSR-7](http://www.php-fig.org/psr/psr-7/) defines interfaces for HTTP requests and responses. However, it does not define how to create a request or how to send a request. Httplug abstracts from HTTP clients written in PHP, offering a simple interface. It also brings a implementation-independent plugin system to build pipelines regardless of the HTTP client implementation used. The message factory provides an implementation independent way to instantiate `Psr\RequestInterface` objects.

## 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 be really stable, 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 adapters).
Httplug allows you to write reusable libraries and applications that need a HTTP client without binding to a specific implementation. When all packages used in an application only specify Httplug, the application developers can chose the client that fits best for their project and use the same client with all packages.

in 2015 a decision has been made to move the library to it's own organization, so PHP HTTP was born.
There are clients implementing the Httplug `Http\Client\HttpClient` interface directly, and adapter packages that implement the interface and forward the calls to HTTP clients not implementing the interface.


## Getting started

HTTP Adapter is separated into several components:

- Adapter contract
- Client contract
- Adapter client
- Adapter implementations
- Helpers


### Installation

There are many strategies how adapters and other components can be installed. However they are the same in one thing: they can be installed via [Composer](http://getcomposer.org/):

``` bash
$ composer require php-http/adapter
```


#### Installation in a reusable package
Read our [tutorial](tutorial.md).

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 it is always a good idea not to rely on a concrete implementation (like Guzzle), but only require some implementation of an HTTP Adapter. With Composer, it is possible:
## Overview

``` json
{
"require": {
"php-http/adapter-implementation": "^1.0"
}
}
```
PHP-HTTP is separated into several packages:

This allows the end user to choose a concrete implementation when installs the package. Of course, during development a concrete implementation is needed:
- [Httplug](httplug.md), the HTTP client abstraction to send PSR-7 requests without binding to a specific implementation;
- [Message Factory](message-factory.md) to create PSR-7 requests without binding to a specific implementation;
- [Discovery](discovery.md) to automatically locate a suitable Httplug implementation and PSR-7 message and URI factories.
- [Utilities](utils.md) convenience tools to simplify working with Httplug in your applications.

See (package overview)[package-overview.md] for a complete list.

``` json
{
"require-dev": {
"php-http/guzzle6-adapter": "^1.0"
}
}
```

## History

Another good practice if the package works out-of-the-box, no or only minimal configuration is needed. While not requiring a concrete implementation is great, it also means that the end user would have to always inject the installed adapter (which is the right, but not a convenient solution). To solve this, there is a discovery components which finds and resolves other installed components:

``` json
{
"require": {
"php-http/discovery": "^1.0"
}
}
```

Read more about it in the [Discovery](discovery.md) part.


#### Installation in an end user package

When installing in an application or a non-reusable package, requiring the virtual package doesn't really make sense. However there are a few things which should be taken into consideration before choosing an adapter:

- It is possible that some other package already has an HTTP Client requirement. It can be confusing to have more than one HTTP Client installed, so always check your other requirements and choose an adapter based on that.
- Some adapters support parallel requests, some only emulate them. If parallel requests are needed, use one which supports it.

Installing an implementation is easy:
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).

``` bash
$ composer require php-http/*-adapter
```
In 2015, a decision has been made to move the library to it's own organization, so PHP HTTP was born.

_Replace * with any supported adapter name_
See (migrating)[migrating.md] for a guide how to migrate your code from the Ivory adapter to Httplug.
7 changes: 5 additions & 2 deletions docs/message-factory.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

## Rationale

The FIG was pretty straightforward by NOT putting any construction logic into PSR-7. However there is a need for that. This does not try to be the "de facto" way to do message construction, but tries to provide an easy way to construct messages by following already existing patterns. (For example: `MessageFactory` accepts parameters in the order they appear in a request/response: method, uri, protocol version, headers, body (in case of a request)).
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. In the case of reusable libraries, an application could end up installing several request 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 by following already existing patterns. (For example: `MessageFactory` accepts parameters in the order they appear in a request/response: method, uri, protocol version, headers, body (in case of a request)).


## Usage
Expand All @@ -20,8 +22,9 @@ This package provides interfaces for PSR-7 factories including:
- `ClientContextFactory` (Combines `MessageFactory`, `StreamFactory` and `UriFactory`)


A 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.
A [virtual package](virtual-package.md) ([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.

The adapter repositories provide wrapper classes for those factories to implement the `Http\Message\MessageFactory` interface.

### General usage

Expand Down
21 changes: 21 additions & 0 deletions docs/migrating.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 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. For a list of the packages, see the (package overview)[package-overview.md]

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.
48 changes: 48 additions & 0 deletions docs/package-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Overview of PHP-HTTP packages

All packages are installed via [Composer](http://getcomposer.org/).


## httplug

**Interfaces for HTTP Client**

- Namespace: `Http\Client`
- Repository: https://github.com/php-http/httplug
- Documentation: (Httplug)[httplug.md]


## message-factory

**Abstraction to create PSR-7 requests without binding to a specific implementation**

- Namespace: `Http\Message`
- Repository: https://github.com/php-http/message-factory
- Documentation: [Message Factory](message-factory.md)


## *-client, *-adapter

**Each client implementation is separated into its own package. This allows for clean requirement specification.**

- Implementations: https://packagist.org/providers/php-http/client-implementation

The clients are either full HTTP clients or adapters to wrap the Httplug Client interface around existing HTTP clients that do not implement the interface.


## discovery

**Discovery service to find installed resources (httplug implementation, message factory)**

- Namespace: `Http\Discovery`
- Repository: https://github.com/php-http/discovery
- Documentation: (Discovery)[discovery.md]


## utils

**Utility classes for HTTP consumers**

- Namespace: `Http\Utils`
- Repository: https://github.com/php-http/utils
- Documentation: (Utils)[utils.md]
5 changes: 5 additions & 0 deletions docs/plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Plugin System

The plugin system will allow to manipulate requests and responses inside a `HttpClient`.

TODO: finalize system and document.

0 comments on commit a292396

Please sign in to comment.