Skip to content

Commit

Permalink
Merge pull request #4 from dbu/discovery
Browse files Browse the repository at this point in the history
restructure discovery documentation - Fix #1, Fix #2
  • Loading branch information
sagikazarmark committed Aug 23, 2015
2 parents 83fd630 + 5e5f584 commit 8094668
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 62 deletions.
117 changes: 58 additions & 59 deletions docs/discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,64 +6,10 @@ The discovery service is a set of static classes which allows to find and use in
Currently available discovery services:

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


## General

Discoveries in general are really similar. In fact, the code behind them is exactly the same.

Here is an example dummy discovery:

``` php
use Http\Discovery\ClassDiscovery;

class MyDiscovery extends ClassDiscovery
{
// IMPORTANT: not declared in the parent to avoid overwritting
protected static $cache;

// IMPORTANT: not declared in the parent
protected static $classes = [];
}
```

A start value can be defined for the `classes` property in the following structure:

``` php
[
[
'class' => 'MyClass',
'condition' => 'MyCondition',
],
]
```

- `class`: The class that is instantiated. There MUST NOT be any constructor arguments.
- `condition`: The condition that is evaluated to boolean to decide whether the resource is available. The following types are allowed:
- string: Checked for class existence
- callable: Called and evaluated to boolean
- boolean: Evaluated as is
- any other: evaluated to false

By declaring a start value for `classes` only string conditions are allowed, however the `register` method allows any type of arguments:

``` php
MyDiscovery::register('MyClass', true);
```

Classes registered manually are put on top of the list.

The condition can also be omitted. In that case the class is used as the condition (to check for existence).

The last thing to do is to find the first available resource:

```php
$myClass = MyDiscovery::find();
```

If no classes can be found, an `Http\Discovery\NotFoundException` is thrown.
The principle is always the same: you call a static find method if no explicit implementation was specified. Find will try to locate the service that is enabled. If no service is enabled, an `Http\Discovery\NotFoundException` is thrown.


## HTTP Adapter Discovery
Expand Down Expand Up @@ -94,7 +40,7 @@ class MyClass
```


## Message Factory Discovery
## 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.

Expand Down Expand Up @@ -125,7 +71,7 @@ class MyClass
}
```

## URI Factory Discovery
## 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.

Expand Down Expand Up @@ -155,3 +101,56 @@ class MyClass
}
}
```


## Integrating your own implementation with the discovery mechanism

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);
```

- `class`: The class that is instantiated. This class MUST NOT require any constructor arguments.
- `condition`: The condition that is evaluated to boolean to decide whether the class can be instantiated. The following types are allowed:
- string: Checked for class existence
- callable: Called and evaluated to boolean
- boolean: Can be true or false
- any other: considered false

The condition can also be omitted. In that case the class is used as the condition (to check for existence).

Classes registered manually are put on top of the list.


### Writing your own discovery

Each discovery service is based on the `ClassDiscovery` and has to specify a `cache` field and a `class` field to specify classes for the corresponding service. The fields 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.

Here is an example discovery:

``` php
use Http\Discovery\ClassDiscovery;

class MyDiscovery extends ClassDiscovery
{
// IMPORTANT: not declared in the parent to avoid overwritting
protected static $cache;

// IMPORTANT: not declared in the parent
protected static $classes = [];
}
```

A start value can be defined for the `classes` property in the following structure:

``` php
[
[
'class' => 'MyClass',
'condition' => 'MyCondition',
],
]
```

The condition is as described above for `register`.
8 changes: 5 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

**This is the documentation for HTTP Adapter and it's software 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.

## History

Expand Down Expand Up @@ -71,10 +73,10 @@ 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, using a virtual package doesn't really make sense. However there are a few things which should be taken into consideration before choosing an adapter:
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 doesn't worth to install more than one HTTP Clients, so always check your other requirements and choose an adapter based on that.
- Some adapters support paralell requests, some only emulate them. If paralell requests are needed, use one which supports it.
- 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:

Expand Down

0 comments on commit 8094668

Please sign in to comment.