Git Product home page Git Product logo

guzzle-bundle's Introduction

Latest Version on Packagist Software License Build Status Total Downloads

Requirements | Install | Usage | Contributing | Security | License | About

GuzzleBundle

The Mapudo GuzzleBundle allows integrating Guzzle into Symfony projects.

The main features of this bundle are:

  • Easy addition of custom middleware and event listeners
  • Close to 100% test coverage
  • Written from the ground up for PHP 7
  • Built-in middleware for
    • Logging via Monolog on a separate guzzle channel
    • Request debugging via Symfony Profiler (styled with Bootstrap) and DebugBar
    • Event dispatching via Symfony Event Framework

Why yet another Guzzle Bundle? We simply weren't happy with the code quality and middleware integration of existing bundles and our issues were not addressed by their maintainers.

Requirements

  • PHP 7.0 and newer
  • Symfony ~2.8|~3.0|~4.0

Install

Via Composer

$ composer require mapudo/guzzle-bundle

Usage

Activating the bundle

Register the bundle in your AppKernel.php.

// app/AppKernel.php
...
new Mapudo\Bundle\GuzzleBundle\GuzzleBundle(), 
...

Configuration

Configure the bundle via app/config.yml. You can define multiple clients and set basic options.

guzzle:
    clients:
        test_client:
            base_uri: 'https://example.com/path'
            headers:
                Accept: 'application/json'
                Accept-Language: 'de'
            request_options:
                allow_redirects: true
                cert:
                    - '/path/to/cert.pem'
                    - 'password'
        another_client:
            base_uri: 'https://another.example.com/root/child'
            headers:
                X-Auth: 'token'

All request_options documented in the Guzzle documentation can be configured for clients, except for the following which can only be set on individual requests:

  • body
  • cookies
  • debug
  • form_params
  • json
  • multipart
  • on_headers
  • on_stats
  • progress
  • sink

Clients defined in the configuration are then registered by the bundle's CompilerPass and you can afterwards access them from the container by name. For the above cases, we would have two clients which we can access with guzzle.client.test_client and guzzle.client.another_client.

Making requests

Making requests is easy and essentially the same as using Guzzle directly. As described above, you can also set request_options here that are not available to configure via the config.

<?php
$client = $container->get('guzzle.client.test_client');
$moreOptions = ['on_stats' => function (\GuzzleHttp\TransferStats $stats) {
    echo $stats->getEffectiveUri() . "\n";
    echo $stats->getTransferTime() . "\n";
}];
$client->requestAsync(\Symfony\Component\HttpFoundation\Request::METHOD_GET, '/path/without/base_uri', $moreOptions);

Note: Clear your cache after adding a new log handler or a middleware so that the CompilerPass is run again.

Logging

The CompilerPass registers a logging middleware which defines a guzzle logging channel. By default all Monolog handlers defined in your config will log these requests. To disable logging for specific handlers add !guzzle to the channel list of the handler.

monolog:
   handlers:
       main:
           channels: [!guzzle]

It is also possible to log request data into the Symfony profiler and debug toolbar. To do to this, activate the built-in profiler handler with the following configuration:

monolog:
    handlers:
        my_debug_handler:
            type: service
            id: mapudo_bundle_guzzle.log_handler.symfony_profiler_handler
            level: debug
            channels: [guzzle]
        ## add additional handlers as needed
        # my_other_handler:
            # ...
            # channels: [guzzle]

After adding this handler you need to rebuild the assets so your Profiler is styled, e.g. with assets:install. Here you can select which client's request to be shown. Symfony Profiler

Log into specific channels

Per default the LogMiddleware logs into the "guzzle" channel. If you want that a different handler is used (dependent on the channel) you can define a service tag for this.

YAML

mapudo_frontend.mapudo_api.log_middleware:
    class: Mapudo\Bundle\GuzzleBundle\Middleware\LogMiddleware
    tags:
        - { name: guzzle.middleware, method: log, client: mapudo_api, channel: timings }

As you can see, the tag now contain a "channel" node. If configured like this, the guzzle client mapudo_api will have the LogMiddleware as a middleware injected that uses a/multiple logger which log into the timings channel.

Important

Please note, that the service id of the LogMiddleware must contain the name log_middleware since the compiler pass checks if the service definition contains this name to retrieve the channel.

Add your own Logging

This bundle uses Symfony's normalizer to normalize the request and response objects before passing them to the logger. This allows you to handle the requests and responses as an array. If you want to work with objects instead, the bundle provides a request and response denormalizer which morphs the arrays into corresponding objects.

For example, to write your own handler, take the response and request array out of the given context and denormalize them.

<?php
if ($record['context']) {
    $response = null;
    if (!empty($record['context']['response'])) {
        $response = $this->responseDenormalizer->denormalize($record['context']['response'], Response::class);
    }
    if (!empty($record['context']['request'])) {
        /** @var Request $request */
        $request = $this->requestDenormalizer->denormalize($record['context']['request'], Request::class);
        $request->setResponse($response);
    }
}

or just do what you want.

Middleware

This bundle comes with two middleware services already implemented. One to dispatch events and one to log with given handlers.

Add your own Middleware

The bundle supports registering Middlewares by using __invoke() or creating a custom method.

The CompilerPass searches for services which are tagged with guzzle.middleware. A tag method is optional to define which method should be executed if you don't use __invoke() in your middleware. You need to add the tag client with the name of the client. However, if you want to create a middleware for all clients you can omit the tag.

YAML

services:
    guzzle.middleware.my_middleware:
        class: exampleClass
        tags:
            - { name: guzzle.middleware, method: addMyMiddleware, client: test_client }

XML

<services>
    <service id="guzzle.middleware.my_middleware" class="exampleClass">
        <tag name="guzzle.middleware" method="addMyMiddleware" client="test_client"/>
    </service>
</services>

Events

Add your own Event Listeners

The CompilerPass searches for services tagged with kernel.event_listener. A tag event is also required to define on which event to listen to. You are allowed to use either guzzle_event.pre_transaction or guzzle_event.post_transaction. Unlike middleware, a client name is required here.

YAML

services:
    guzzle.event.my_event:
        class: exampleClass
        tags:
            - { name: kernel.event_listener, event: guzzle_event.pre_transaction, client: test_client }

XML

<services>
    <service id="guzzle.event.my_event" class="exampleClass">
        <tag name="kernel.event_listener" event="guzzle_event.pre_transaction" client="test_client"/>
    </service>
</services>

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email mailto:[email protected] instead of using the issue tracker.

License

The MIT License (MIT). Please see License File for more information.

About

This bundle was authored at Mapudo, the online materials marketplace. We're hiring!

guzzle-bundle's People

Contributors

advancingu avatar cjost1988 avatar kobelobster avatar mablae avatar phpjob avatar piotr-zuralski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

guzzle-bundle's Issues

Enable prioritizing middleware

Actual:

  • Middleware cannot be prioritized and it cannot be assured which middleware will be loaded first

Expected:

  • Middleware can be prioritized.

Drop Symfony <= 3.2 support

Since Symfony 3.2 has an EOL at the end of january, we should change the composer.json to only support Symfony >= 3.3

Support for Symfony 5

Currently in composer.json max Symfony version supported by bundle is 4.*. Please provide compatibility for Symfony 5.

FYI: we use fork with |~5.0 added and it works, so probably it's all that needs to be done.

Add travis-ci

Actual:

  • There is no set up CI for checking code that will be pushed to this repository

Expected:

  • Code pushed to this repository shall be checked via CI

Profiler still does not work with Symfony >= 3.4

symfony new mapudo 3.4
cd mapudo
composer require mapudo/guzzle-bundle
// apply default configuration from your README.md and enable bundle in AppKernel
// fire $this->container->get('guzzle.client.test_client')->request('get', 'https://jsonplaceholder.typicode.com/posts/1');

When you open profiler,

UnexpectedValueException:
The profiler template "GuzzleBundle::debug.html.twig" for data collector "guzzle" does not exist.

  at vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php:108
  at Symfony\Bundle\WebProfilerBundle\Profiler\TemplateManager->getNames(object(Profile))
     (vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php:54)
  at Symfony\Bundle\WebProfilerBundle\Profiler\TemplateManager->getName(object(Profile), 'request')
     (vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php:114)
  at Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController->panelAction(object(Request), '74e873')
     (vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:151)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:68)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php:202)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (web/app_dev.php:29)
  at require('/home/gadelat/Documents/mapudo/web/app_dev.php')
     (vendor/symfony/symfony/src/Symfony/Bundle/WebServerBundle/Resources/router.php:42)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.