/api/vendor/guzzle/guzzle/docs/webservice-client/using-the-service-builder.rst
ReStructuredText | 316 lines | 244 code | 72 blank | 0 comment | 0 complexity | 6f75a767df1bf01f8a8d13638011677b MD5 | raw file
- =======================
- Using a service builder
- =======================
- The best way to instantiate Guzzle web service clients is to let Guzzle handle building the clients for you using a
- ServiceBuilder. A ServiceBuilder is responsible for creating concrete client objects based on configuration settings
- and helps to manage credentials for different environments.
- You don't have to use a service builder, but they help to decouple your application from concrete classes and help to
- share configuration data across multiple clients. Consider the following example. Here we are creating two clients that
- require the same API public key and secret key. The clients are created using their ``factory()`` methods.
- .. code-block:: php
- use MyService\FooClient;
- use MyService\BarClient;
- $foo = FooClient::factory(array(
- 'key' => 'abc',
- 'secret' => '123',
- 'custom' => 'and above all'
- ));
- $bar = BarClient::factory(array(
- 'key' => 'abc',
- 'secret' => '123',
- 'custom' => 'listen to me'
- ));
- The redundant specification of the API keys can be removed using a service builder.
- .. code-block:: php
- use Guzzle\Service\Builder\ServiceBuilder;
- $builder = ServiceBuilder::factory(array(
- 'services' => array(
- 'abstract_client' => array(
- 'params' => array(
- 'key' => 'abc',
- 'secret' => '123'
- )
- ),
- 'foo' => array(
- 'extends' => 'abstract_client',
- 'class' => 'MyService\FooClient',
- 'params' => array(
- 'custom' => 'and above all'
- )
- ),
- 'bar' => array(
- 'extends' => 'abstract_client',
- 'class' => 'MyService\FooClient',
- 'params' => array(
- 'custom' => 'listen to me'
- )
- )
- )
- ));
- $foo = $builder->get('foo');
- $bar = $builder->get('bar');
- You can make managing your API keys even easier by saving the service builder configuration in a JSON format in a
- .json file.
- Creating a service builder
- --------------------------
- A ServiceBuilder can source information from an array, an PHP include file that returns an array, or a JSON file.
- .. code-block:: php
- use Guzzle\Service\Builder\ServiceBuilder;
- // Source service definitions from a JSON file
- $builder = ServiceBuilder::factory('services.json');
- Sourcing data from an array
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Data can be source from a PHP array. The array must contain an associative ``services`` array that maps the name of a
- client to the configuration information used by the service builder to create the client. Clients are given names
- which are used to identify how a client is retrieved from a service builder. This can be useful for using multiple
- accounts for the same service or creating development clients vs. production clients.
- .. code-block:: php
- $services = array(
- 'includes' => array(
- '/path/to/other/services.json',
- '/path/to/other/php_services.php'
- ),
- 'services' => array(
- 'abstract.foo' => array(
- 'params' => array(
- 'username' => 'foo',
- 'password' => 'bar'
- )
- ),
- 'bar' => array(
- 'extends' => 'abstract.foo',
- 'class' => 'MyClientClass',
- 'params' => array(
- 'other' => 'abc'
- )
- )
- )
- );
- A service builder configuration array contains two top-level array keys:
- +------------+---------------------------------------------------------------------------------------------------------+
- | Key | Description |
- +============+=========================================================================================================+
- | includes | Array of paths to JSON or PHP include files to include in the configuration. |
- +------------+---------------------------------------------------------------------------------------------------------+
- | services | Associative array of defined services that can be created by the service builder. Each service can |
- | | contain the following keys: |
- | | |
- | | +------------+----------------------------------------------------------------------------------------+ |
- | | | Key | Description | |
- | | +============+========================================================================================+ |
- | | | class | The concrete class to instantiate that implements the | |
- | | | | ``Guzzle\Common\FromConfigInterface``. | |
- | | +------------+----------------------------------------------------------------------------------------+ |
- | | | extends | The name of a previously defined service to extend from | |
- | | +------------+----------------------------------------------------------------------------------------+ |
- | | | params | Associative array of parameters to pass to the factory method of the service it is | |
- | | | | instantiated | |
- | | +------------+----------------------------------------------------------------------------------------+ |
- | | | alias | An alias that can be used in addition to the array key for retrieving a client from | |
- | | | | the service builder. | |
- | | +------------+----------------------------------------------------------------------------------------+ |
- +------------+---------------------------------------------------------------------------------------------------------+
- The first client defined, ``abstract.foo``, is used as a placeholder of shared configuration values. Any service
- extending abstract.foo will inherit its params. As an example, this can be useful when clients share the same username
- and password.
- The next client, ``bar``, extends from ``abstract.foo`` using the ``extends`` attribute referencing the client from
- which to extend. Additional parameters can be merged into the original service definition when extending a parent
- service.
- .. important::
- Each client that you intend to instantiate must specify a ``class`` attribute that references the full class name
- of the client being created. The class referenced in the ``class`` parameter must implement a static ``factory()``
- method that accepts an array or ``Guzzle\Common\Collection`` object and returns an instantiated object.
- Sourcing from a PHP include
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- You can create service builder configurations using a PHP include file. This can be useful if you wish to take
- advantage of an opcode cache like APC to speed up the process of loading and processing the configuration. The PHP
- include file is the same format as an array, but you simply create a PHP script that returns an array and save the
- file with the .php file extension.
- .. code-block:: php
- <?php return array('services' => '...');
- // Saved as config.php
- This configuration file can then be used with a service builder.
- .. code-block:: php
- $builder = ServiceBuilder::factory('/path/to/config.php');
- Sourcing from a JSON document
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- You can use JSON documents to serialize your service descriptions. The JSON format uses the exact same structure as
- the PHP array syntax, but it's just serialized using JSON.
- .. code-block:: javascript
- {
- "includes": ["/path/to/other/services.json", "/path/to/other/php_services.php"],
- "services": {
- "abstract.foo": {
- "params": {
- "username": "foo",
- "password": "bar"
- }
- },
- "bar": {
- "extends": "abstract.foo",
- "class": "MyClientClass",
- "params": {
- "other": "abc"
- }
- }
- }
- }
- Referencing other clients in parameters
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If one of your clients depends on another client as one of its parameters, you can reference that client by name by
- enclosing the client's reference key in ``{}``.
- .. code-block:: javascript
- {
- "services": {
- "token": {
- "class": "My\Token\TokenFactory",
- "params": {
- "access_key": "xyz"
- }
- },
- "client": {
- "class": "My\Client",
- "params": {
- "token_client": "{token}",
- "version": "1.0"
- }
- }
- }
- }
- When ``client`` is constructed by the service builder, the service builder will first create the ``token`` service
- and then inject the token service into ``client``'s factory method in the ``token_client`` parameter.
- Retrieving clients from a service builder
- -----------------------------------------
- Clients are referenced using a customizable name you provide in your service definition. The ServiceBuilder is a sort
- of multiton object-- it will only instantiate a client once and return that client for subsequent retrievals. Clients
- are retrieved by name (the array key used in the configuration) or by the ``alias`` setting of a service.
- Here's an example of retrieving a client from your ServiceBuilder:
- .. code-block:: php
- $client = $builder->get('foo');
- // You can also use the ServiceBuilder object as an array
- $client = $builder['foo'];
- Creating throwaway clients
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
- You can get a "throwaway" client (a client that is not persisted by the ServiceBuilder) by passing ``true`` in the
- second argument of ``ServiceBuilder::get()``. This allows you to create a client that will not be returned by other
- parts of your code that use the service builder. Instead of passing ``true``, you can pass an array of configuration
- settings that will override the configuration settings specified in the service builder.
- .. code-block:: php
- // Get a throwaway client and overwrite the "custom" setting of the client
- $foo = $builder->get('foo', array(
- 'custom' => 'in this world there are rules'
- ));
- Getting raw configuration settings
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- You can get the raw configuration settings provided to the service builder for a specific service using the
- ``getData($name)`` method of a service builder. This method will null if the service was not found in the service
- builder or an array of configuration settings if the service was found.
- .. code-block:: php
- $data = $builder->getData('foo');
- echo $data['key'] . "\n";
- echo $data['secret'] . "\n";
- echo $data['custom'] . "\n";
- Adding a plugin to all clients
- ------------------------------
- You can add a plugin to all clients created by a service builder using the ``addGlobalPlugin($plugin)`` method of a
- service builder and passing a ``Symfony\Component\EventDispatcher\EventSubscriberInterface`` object. The service builder
- will then attach each global plugin to every client as it is created. This allows you to, for example, add a LogPlugin
- to every request created by a service builder for easy debugging.
- .. code-block:: php
- use Guzzle\Plugin\Log\LogPlugin;
- // Add a debug log plugin to every client as it is created
- $builder->addGlobalPlugin(LogPlugin::getDebugPlugin());
- $foo = $builder->get('foo');
- $foo->get('/')->send();
- // Should output all of the data sent over the wire
- .. _service-builder-events:
- Events emitted from a service builder
- -------------------------------------
- A ``Guzzle\Service\Builder\ServiceBuilder`` object emits the following events:
- +-------------------------------+--------------------------------------------+-----------------------------------------+
- | Event name | Description | Event data |
- +===============================+============================================+=========================================+
- | service_builder.create_client | Called when a client is created | * client: The created client object |
- +-------------------------------+--------------------------------------------+-----------------------------------------+
- .. code-block:: php
- use Guzzle\Common\Event;
- use Guzzle\Service\Builder\ServiceBuilder;
- $builder = ServiceBuilder::factory('/path/to/config.json');
- // Add an event listener to print out each client client as it is created
- $builder->getEventDispatcher()->addListener('service_builder.create_client', function (Event $e) {
- echo 'Client created: ' . get_class($e['client']) . "\n";
- });
- $foo = $builder->get('foo');
- // Should output the class used for the "foo" client