Use middleware to decorate method calls within your application code.

Overview

Laravel Middlewarize

🎀 Chain of Responsibility Design Pattern In Laravel Apps 🎀


Onion

Maintainability Quality Score Latest Stable Version Code Coverage Software License


You can use middlewares to decorate any method calls on any object.

🔥 Installation:

composer require imanghafoori/laravel-middlewarize

▶️ How to use:

Put the \Imanghafoori\Middlewarize\Middlewarable trait on your class.

For example consider a simple repository class:

class UserRepository
{
    use Middlewarable;     //   <----  Use "Middlewarable" trait on your class
    
    public function find($id) 
    {
        return User::find($id);   //   <----  we wanna cache it, right?
    }
    ...
}

▶️ Define a Middleware:

class CacheMiddleware
{
    public function handle($data, $next, $key, $ttl)
    {
        // 1. This part runs before method call
        if (Cache::has($key)) {
            return Cache::get($key);
        }
        
        $value = $next($data);  // <--- 2. Runs the actual method
        
       
        Cache::put($key, $value, $ttl);  // <-- 3. This part runs after method
        
        return $value;
    }
}

Since middlewares are resolved out of the laravel container, you can pass any abstract string as a middleware and bind it on the IOC:

public function boot()
{
    app()->singleton('cacher', CacheMiddleware::class);  // <---- Optional step
}

▶️ Use the Middleware:

Cleaned controller will look like this:

public function show($id, UserRepository $repo)
{
    $cachedUser = $repo
        ->middleware('cacher:fooKey,60')
        ->find($id);
}

Easy Peasy Yeah ?!

You totally separate the cache concern into a new class.

So let's compare...

Before:

Before utilizing middlewares our code was like this:

public function show($id, UserRepository $repo)
{
    if (Cache::has('user.'.$id)) {
        return Cache::get('user.'.$id); // <--- extra fluff around ->find($id)
    }
        
    $value = $repo->find($id);  //   <--- important method call here.

    Cache::put('user.'.$id, $value, 60); // <--- extra fluff around ->find($id)
        
    return $value;
}

▶️ Overriding default Middleware method:

public function show($id, UserRepository $repo)
{
    $cachedUser = $repo
        ->middleware('[email protected]:fooKey,60')  // <--- Overrides default "handle" method name
        ->find($id);
}

▶️ Multiple middlewares:

public function show($id, UserRepository $repo)
{
    $cachedUser = $repo->middleware(['middle1', 'middle2', 'middle3'])->find($id);
}

The order of execution is like that:

Start ===> ( middle1 -> middle2 -> middle_3 ( find ) middle_3 -> middle2 -> middle1 ) ===> result !!!

▶️ Middlewares on facades ?!

You wanna use facades to call the repo ?! No problem.

$cachedUser = UserRepositoryFacade::middleware('cacher:fooKey,60 seconds')->find($id);

▶️ Objects as middlewares:

You can also use objects as middlewares for more eloborated scenarios.

$obj = new CacheMiddleware('myCacheKey', etc...);   //   <---- you send depedencies to it.

$repo->middleware($obj)->find($id);

▶️ Middleware on static methods:

User::find($id);       //  <--- Sample static method call

User::middlewared('cache:key,10')->find($id); // <--- you can have a decorated call

// also you must put 'middlewarable' trait on User model.

▶️ Testing:

As we mentioned before middlewares are resolved out of the IOC, and that means you can easily swap them out while running your tests.

class NullCacheMiddleware
{
    public function handle($data, $next, $key, $ttl)
    {
        return $next($data); // <--- this "null middleware" does nothing.
    }
}


public function testSomeThing()
{
    app()->singleton('cacher', NullCacheMiddleware::class);  // <--- this causes to replace the cache middleware
    
    $this->get('/home');
}

Here we have neutralized the middleware to do "nothing" while the tests are running.

▶️ What happens if exception is thrown from your method?

It is important to know if you throw an exception in your method, the post middlewares still execute and the value of $value = $next(data) would be the thrown exception. The exception is rethrown when all middlewares finished executing.


🙋 Contributing:

If you find an issue, or have a better way to do something, feel free to open an issue or a pull request.


⭐ Your Stars Make Us Do More ⭐

As always if you found this package useful and you want to encourage us to maintain and work on it. Just press the star button to declare your willing.


More from the author:

Laravel Widgetize

💎 A minimal yet powerful package to give a better structure and caching opportunity for your laravel apps.


Laravel HeyMan

💎 It allows to write expressive code to authorize, validate and authenticate.


Laravel Terminator

💎 A minimal yet powerful package to give you opportunity to refactor your controllers.


Laravel AnyPass

💎 It allows you login with any password in local environment only.


Eloquent Relativity

💎 It allows you to decouple your eloquent models to reach a modular structure


Logic will get you from a to z, imagination will take you everywhere.

"Albert Einstein"

You might also like...
PSR-15 middleware to geolocate the client using the ip address

middlewares/geolocation ![SensioLabs Insight][ico-sensiolabs] Middleware to geolocate the client using the ip address and Geocoder and save the result

A PSR-15 middleware adapter for react/http

A PSR-15 middleware adapter for react/http Wraps PSR-15 middleware into coroutines using RecoilPHP making them usable within react/http as middleware.

A PSR-15 middleware to handle content negotiation

Content negotiation middleware Motivation Packages like middlewares/negotiation do a very good job to detect the correct content type based on the Acc

PSR-15 compatible middleware for Whoops, the pretty error handler

PSR-15 middleware for Whoops A PSR-15 compatible middleware for Whoops, the fantastic pretty error handler for PHP. Installation You can install the l

Middleware to provide IP filtering

middlewares/firewall Middleware to provide IP filtering using M6Web/Firewall. Requirements PHP = 7.2 A PSR-7 http library A PSR-15 middleware dispatc

Stepup Middleware - This component is part of "Step-up Authentication as-a Service".

Step-up Middleware This component is part of "Step-up Authentication as-a Service". See Stepup-Deploy for an overview and installation instructions fo

An internal redirect mechanism for PSR-15 middleware stacks

HTTP Request Forwarder The aim of this library is to make it possible to pass the HTTP request to another handler, creating a so-called internal redir

Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application

CORS Middleware for Laravel Implements https://github.com/asm89/stack-cors for Laravel About The laravel-cors package allows you to send Cross-Origin

Easily integrate custom-made NPS (Net Promoter Score) into your application
Easily integrate custom-made NPS (Net Promoter Score) into your application

Laravel NPS Easily integrate custom-made NPS (Net Promoter Score) to your application. Installation You can install the package via composer: composer

Comments
  • Bump symfony/mime from 4.3.3 to 4.4.4

    Bump symfony/mime from 4.3.3 to 4.4.4

    Bumps symfony/mime from 4.3.3 to 4.4.4.

    Release notes

    Sourced from symfony/mime's releases.

    v4.4.4

    Changelog (https://github.com/symfony/mime/compare/v4.4.3...v4.4.4)

    • no changes

    v4.3.11

    Changelog (https://github.com/symfony/mime/compare/v4.3.10...v4.3.11)

    • no changes
    Changelog

    Sourced from symfony/mime's changelog.

    CHANGELOG

    4.4.0

    • [BC BREAK] Removed NamedAddress (Address now supports a name)
    • Added PHPUnit constraints
    • Added AbstractPart::asDebugString()
    • Added Address::fromString()
    Commits
    • 2250346 Merge branch '4.3' into 4.4
    • 50f65ca Update year in license files
    • 010cc48 bug #34032 [Mime] Fixing multidimensional array structure with FormDataPart (...
    • 89da7b6 Merge branch '4.3' into 4.4
    • 22aecf6 [Mime] fix guessing mime-types of files with leading dash
    • bf6913d Merge branch '4.3' into 4.4
    • 3c0e197 [4.3] Remove unused local variables
    • 86fe792 minor #33963 Add .gitignore to .gitattributes (reedy)
    • 51d5b0e Changing the multipart form-data behavior to use the form name as an array, w...
    • ae5a66b Merge branch '4.3' into 4.4
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump symfony/http-foundation from 4.3.3 to 4.4.4

    Bump symfony/http-foundation from 4.3.3 to 4.4.4

    Bumps symfony/http-foundation from 4.3.3 to 4.4.4.

    Release notes

    Sourced from symfony/http-foundation's releases.

    v4.4.4

    Changelog (https://github.com/symfony/http-foundation/compare/v4.4.3...v4.4.4)

    • bug #35305  Fix stale-if-error behavior, add tests (mpdude)

    v4.3.11

    Changelog (https://github.com/symfony/http-foundation/compare/v4.3.10...v4.3.11)

    • bug #35305  Fix stale-if-error behavior, add tests (mpdude)
    Changelog

    Sourced from symfony/http-foundation's changelog.

    CHANGELOG

    5.1.0

    • added Cookie::withValue, Cookie::withDomain, Cookie::withExpires, Cookie::withPath, Cookie::withSecure, Cookie::withHttpOnly, Cookie::withRaw, Cookie::withSameSite
    • Deprecate Response::create(), JsonResponse::create(), RedirectResponse::create(), and StreamedResponse::create() methods (use __construct() instead)
    • added Request::preferSafeContent() and Response::setContentSafe() to handle "safe" HTTP preference according to RFC 8674
    • made the Mime component an optional dependency

    5.0.0

    • made Cookie auto-secure and lax by default
    • removed classes in the MimeType namespace, use the Symfony Mime component instead
    • removed method UploadedFile::getClientSize() and the related constructor argument
    • made Request::getSession() throw if the session has not been set before
    • removed Response::HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL
    • passing a null url when instantiating a RedirectResponse is not allowed

    4.4.0

    • passing arguments to Request::isMethodSafe() is deprecated.
    • ApacheRequest is deprecated, use the Request class instead.
    • passing a third argument to HeaderBag::get() is deprecated, use method all() instead
    • [BC BREAK] PdoSessionHandler with MySQL changed the type of the lifetime column, make sure to run ALTER TABLE sessions MODIFY sess_lifetime INTEGER UNSIGNED NOT NULL to update your database.
    • PdoSessionHandler now precalculates the expiry timestamp in the lifetime column, make sure to run CREATE INDEX EXPIRY ON sessions (sess_lifetime) to update your database to speed up garbage collection of expired sessions.
    • added SessionHandlerFactory to create session handlers with a DSN
    • added IpUtils::anonymize() to help with GDPR compliance.

    4.3.0

    • added PHPUnit constraints: RequestAttributeValueSame, ResponseCookieValueSame, ResponseHasCookie, ResponseHasHeader, ResponseHeaderSame, ResponseIsRedirected, ResponseIsSuccessful, and ResponseStatusCodeSame
    • deprecated MimeTypeGuesserInterface and ExtensionGuesserInterface in favor of Symfony\Component\Mime\MimeTypesInterface.
    • deprecated MimeType and MimeTypeExtensionGuesser in favor of Symfony\Component\Mime\MimeTypes.
    • deprecated FileBinaryMimeTypeGuesser in favor of Symfony\Component\Mime\FileBinaryMimeTypeGuesser.
    • deprecated FileinfoMimeTypeGuesser in favor of Symfony\Component\Mime\FileinfoMimeTypeGuesser.
    ... (truncated)
    Commits
    • 491a20d Merge branch '4.3' into 4.4
    • 90af881 Merge branch '3.4' into 4.3
    • 3bdf327 [HttpKernel] Fix stale-if-error behavior, add tests
    • c339987 Merge branch '4.3' into 4.4
    • d7fde62 Merge branch '3.4' into 4.3
    • f3abd07 Update links to documentation
    • 45285ab Update year in license files
    • 1047801 Merge branch '4.3' into 4.4
    • bb19a17 Merge branch '3.4' into 4.3
    • de7e6cd X-Accel Nginx URL updated
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
Releases(v1.1.6)
Owner
Iman
Coding is sport, it is art, it is science.
Iman
PSR-7 middleware foundation for building and dispatching middleware pipelines

laminas-stratigility From "Strata", Latin for "layer", and "agility". This package supersedes and replaces phly/conduit. Stratigility is a port of Sen

Laminas Project 45 Nov 8, 2022
The perfect starting point to integrate Algolia within your PHP project

⚡️ A fully-featured and blazing-fast PHP API client to interact with Algolia.

Algolia 623 Nov 21, 2022
PSR-15 middleware to use Whoops as error handler

middlewares/whoops Middleware to use Whoops as error handler. Requirements PHP >= 7.2 A PSR-7 http library A PSR-15 middleware dispatcher Installation

Middlewares 31 Jun 23, 2022
This project was built to connect WHMCS with GridPane.com's API service so we can create sites within WHMCS.

GridPane Server Module for WHMCS This project was built to connect WHMCS with GridPane.com's API service so we can create sites within WHMCS. Discliam

null 10 Sep 2, 2021
Shopware plugin to show a variant switch on the product listing and within the (checkout) cart.

Variant switch for Shopware 6 A plugin for Shopware 6 Features Show variant switch on product listing card Variant switch when hovering a variant prop

Shape & Shift 17 Aug 26, 2022
A list of all the Belgian stations and their properties used within the iRail project

All stations in Belgium We try to maintain a list of all the stations in Belgium using CSV so everyone can help to maintain it on github. Furthermore,

null 33 Nov 16, 2022
Provides a Middleware to integration Tideways into Symfony Messenger Processing

Tideways Middleware for Symfony Messenger This package is currently under development and might be moved into the Tideways PHP Extension or stay indep

Tideways 6 Jul 5, 2022
Disable Google's FLoC with help of PSR-15 middleware

Disable Google's FLoC with PSR-15 middleware This package will help you disable Google's FLoC. Installation You can install the package via composer:

P7V 9 Apr 1, 2022
A simple and flexible PHP middleware dispatcher based on PSR-7, PSR-11, and PSR-15

Woohoo Labs. Harmony Woohoo Labs. Harmony is a PSR-15 compatible middleware dispatcher. Harmony was born to be a totally flexible and almost invisible

Woohoo Labs. 153 Sep 5, 2022
A lightweight middleware to make api routing session capable.

Laravel stateless session A lightweight middleware to make api routing session capable. Installing $ composer require overtrue/laravel-stateless-sessi

安正超 17 Jul 6, 2022