AthenaeumAthenaeum
Packages
  • next
  • current
  • v9.x
  • v8.x
  • v7.x
  • v6.x
  • v5.x
  • v4.x
  • v3.x
  • v2.x
  • v1.x
Changelog
GitHub
Packages
  • next
  • current
  • v9.x
  • v8.x
  • v7.x
  • v6.x
  • v5.x
  • v4.x
  • v3.x
  • v2.x
  • v1.x
Changelog
GitHub
  • Version 6.x

    • Release Notes
    • Upgrade Guide
    • New to this...
    • Contribution Guide
    • Security Policy
    • Code of Conduct
    • Origin
  • ACL

    • Introduction
    • How to install
    • Setup
    • Permissions
    • Roles
    • Users
    • Cached Permissions
  • Audit

    • Audit
    • How to install
    • Setup
    • Recording
    • Events
  • Circuits

    • Circuits
    • How to install
    • Setup
    • Usage
    • Events
  • Collections

    • Collections
    • How to install
    • Summation

      • Summation Collection
      • Items Processor
  • Config

    • Configuration Loader
    • How to install
    • Setup
    • Load Configuration Files
    • Custom File Parsers
  • Console

    • Command and Schedule Registration
    • How to install
    • Setup
    • Commands
    • Schedules
  • Container

    • IoC Service Container
    • How to install
    • Container
    • List Resolver
  • Core

    • Athenaeum Core Application
    • How to install
    • Setup
    • Usage

      • Configuration
      • Service Providers
      • Service Container
      • Events
      • Caching
      • Logging
      • Console
      • Task Scheduling
      • Exception Handling
      • Extending Core Application
      • Testing
  • Database

    • Introduction
    • How to install
    • Models

      • Instantiatable
      • Sluggable
    • Query

      • Criteria (Query Filter)
  • Dto

    • Data Transfer Object (DTO)
    • How to install
    • Create Interface
    • Implement DTO
    • How to use
    • Populate
    • Export
    • Json
    • Serialization
    • Nested DTOs
    • Array DTO
  • ETags

    • ETags
    • How to install
    • Setup
    • Usage
    • Generators

      • Default Generator
      • Custom Generator
    • Eloquent Models
    • Macros
  • Events

    • Register Listeners and Subscribers
    • How to install
    • Setup
    • Listeners
    • Subscribers
  • Filters

    • Search Filter Utilities
    • Prerequisites
    • How to install
    • Setup
    • Processor
    • Filters Builder
    • Predefined Resources

      • Search Processor
      • Sorting Processor
      • Constraints Processor
      • Matching Processor
    • Tip: Create a base builder
  • Flysystem

    • Introduction
    • Database Adapter

      • Introduction
      • How to install
      • Setup
      • Data Deduplication
      • MIME-Type Detection
  • Http

    • Api

      • Http API
      • How to install
      • Setup
      • Resources

        • Introduction
        • Timestamps
        • Self-Link
        • Relations
        • Registrar
      • Middleware

        • Introduction
        • Request Must Be Json
        • Capture Fields To Select
    • Clients

      • Http Clients
      • How to install
      • Setup
      • Basic Usage
      • Available Methods

        • Fluent Api
        • Protocol Version
        • Base Uri
        • Http Method and Uri
        • Headers
        • Accept & Content-Type
        • Authentication
        • Http Query
        • Payload Format
        • Payload
        • Attachments
        • Cookies
        • Response Expectations
        • Middleware
        • Conditions
        • Criteria
        • Redirects
        • Timeout
        • Debugging
        • Logging
        • Driver Options
        • Driver
      • Http Query Builder

        • Introduction
        • Select
        • Where
        • Dates
        • Include
        • Pagination
        • Sorting
        • Raw Expressions
        • Custom Grammar
    • Cookies

      • Http Cookies
      • How to install
      • Usage
    • Messages

      • Http Messages
      • How to install
      • Serializers
  • Maintenance

    • Modes

      • Maintenance Modes
      • How to install
      • Setup
      • Basic Usage
      • Available Drivers
  • Mime Types

    • MIME-Types
    • How to install
    • Setup
    • Usage
    • Drivers

      • Available Drivers
      • File Info
  • Properties

    • Properties Overload
    • How to install
    • Usage
    • Naming Convention
    • Properties Visibility
  • Redmine

    • Redmine Api Client
    • How to install
    • Setup
    • General Usage

      • Supported Operations
      • Fetch list of resources
      • Find
      • Fetch
      • Create new record
      • Update existing record
      • Delete existing record
      • Relations
    • Available Resources

      • Predefined Resources
      • Attachments
      • Enumerations
      • Issue Relations
      • Users
      • User Groups
      • Roles
      • Project Memberships
      • Versions (Milestones)
      • Issue Categories
      • Trackers
  • Service

    • Service Registrar
    • How to install
    • How to use
  • Streams

    • Streams
    • How to install
    • Setup
    • How to use

      • Introduction
      • Open and Close
      • Raw Resource
      • Seeking
      • Reading
      • Writing
      • Size
      • Truncate
      • Flush
      • Hash
      • MIME-Type
      • Output
      • Locking
      • Transactions
      • Meta
      • Misc
  • Support

    • Introduction
    • How to install
    • Laravel Aware-of Helpers

      • How to use
      • Enforce Via Interface
      • Custom Default
      • Pros and Cons
      • Available Helpers
    • Aware-of Properties

      • Generator
      • Available Aware-of Helpers
    • Live Templates
  • Testing

    • Introduction
    • How to install
    • Test Cases
    • Testing Aware-of Helpers
  • Utils

    • Introduction
    • How to install
    • Array
    • Duration
    • Json
    • Math
    • Memory
    • Method Helper
    • Invoker
    • Populatable
    • String
    • Version
  • Validation

    • Introduction
    • How to install
    • Setup
    • Rules

      • Alpha-Dash-Dot
      • Semantic Version
You are viewing documentation for an outdated version. It is no longer supported!

Middleware

Inspired by PSR-15: HTTP Server Request Handlers, the Http Client is able to process outgoing requests and incoming responses, using middleware.

  • Create Middleware
  • Apply Middleware
    • Add List of Middleware
  • Via Configuration
    • Arguments for Middleware
  • Obtain Request Builder in Middleware

Create Middleware

To create a custom middleware component, you must inherit from the Middleware interface.

namespace Acme\Middleware;

use Aedart\Contracts\Http\Clients\Middleware;
use Aedart\Contracts\Http\Clients\Requests\Handler;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Acme\Logger\ResponseLogger;

class LogsResponse implements Middleware
{
    public function process(RequestInterface $request, Handler $handler): ResponseInterface
    {
        $response = $handler->handle($request);

        ResponseLogger::log($response);

        return $response;
    }
}

Differs from PSR-15

If you are familiar with PSR-15, you will immediately notice the similarity between the above shown middleware example, and the one defined in PST-15. Currently, it is not possible to use the same middleware component(s), as for PSR-15. This is because Psr\Http\Server\MiddlewareInterface relies on ServerRequestInterface. In other words, it was designed to process incoming server requests, and not outgoing requests. Therefore, to avoid confusion and misuse of PSR-15, custom Middleware and Handler components have been added to this package.

Even so, the Middleware and Handler from this package offer the same look & feel, as those defined by PSR-15.

Differs from Guzzle

You should not confuse this middleware mechanism with Guzzle's Handlers and Middleware. While they might overlap in purpose and functionality, they are distinctively two different mechanisms.

It is possible to use both mechanisms. If so, then you should know that Guzzle's handlers and middleware will always be executed first. See Guzzle's documentation for additional information.

Apply Middleware

To apply middleware use the withMiddleware() method.

use Acme\Middleware\LogsResponse;

$response = $client
        ->withMiddleware(new LogsResponse())
        ->get('/weather');

Add List of Middleware

You may also provide a list of middleware, using the same method.

use Acme\Middleware\SetsAuthenticationHeaders;
use Acme\Middleware\LimitsResults;
use Acme\Middleware\LogsResponse;

// Will automatically resolve provided class paths...
$response = $client
        ->withMiddleware([
            SetsAuthenticationHeaders::class,
            LimitsResults::class,
            LogsResponse::class
        ])
        ->get('/weather');

Via Configuration

Alternatively, you may also specify a list of middleware in your configuration.

<?php

return [

    'profiles' => [

        'default' => [
            'driver' => \Aedart\Http\Clients\Drivers\DefaultHttpClient::class,
            'options' => [
                
                'middleware' => [
                    \Acme\Middleware\SetsAuthenticationHeaders::class,
                    \Acme\Middleware\LimitsResults::class,
                    \Acme\Middleware\LogsResponse::class
                ]

                // ... remaining not shown ...
            ]
        ],
    ],
];

Arguments for Middleware

Behind the scene, the List Resolver is used, to resolve middleware. This means that you can provide custom arguments for your middleware component, directly from the configuration.

The following hypothetical example assumes that each middleware component accepts one or more arguments. When resolved, each middleware instance will be provided with the arguments defined in the configuration.

<?php

return [

    'profiles' => [

        'default' => [
            'driver' => \Aedart\Http\Clients\Drivers\DefaultHttpClient::class,
            'options' => [
                
                'middleware' => [
                    \Acme\Middleware\SetsAuthenticationHeaders::class => [
                        'token' => env('WEATHER_SERVICE_TOKEN')
                    ],
                    \Acme\Middleware\LimitsResults::class => [
                        'maxResults' => 25,
                    ],
                    \Acme\Middleware\LogsResponse::class => [
                        'maxEntries' => 15,
                        'path' => storage_path('/logs/weather-service-responses.log')
                    ]
                ]

                // ... remaining not shown ...
            ]
        ],
    ],
];

Obtain Request Builder in Middleware

Should your middleware require the Http Request Builder instance, then just inherit from the HttpRequestBuilderAware interface. When resolved, the Builder will automatically be injected into your middleware.

use Aedart\Contracts\Http\Clients\Middleware;
use Aedart\Contracts\Http\Clients\Requests\Builders\HttpRequestBuilderAware;
use Aedart\Contracts\Http\Clients\Requests\Handler;
use Aedart\Http\Clients\Traits\HttpRequestBuilderTrait;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

class LogsResponse implements
    Middleware,
    HttpRequestBuilderAware
{
    use HttpRequestBuilderTrait;

    public function process(RequestInterface $request, Handler $handler): ResponseInterface
    {
        // Obtain builder
        $builder = $this->getHttpRequestBuilder();

        // ... remaining not shown ...
    }
}

Warning

The Builder is no longer able to alter the outgoing request, during middleware processing. It can, however, be used to obtain settings and options.

Edit page
Last Updated: 16/02/2023, 09:10
Contributors: Alin Eugen Deac, alin
Prev
Response Expectations
Next
Conditions