Using Rate Limiting on Method Calls With Laravel
– Part 2

As seen in the previous article in series Rate Limiting Method Calls with Laravel, the proxy pattern is tremendously useful for a variety of programming challenges. While the first part described what the proxy pattern is and gave some examples and context for when to use the proxy pattern, this follow-up article will focus on the practical side of the implementation details.


Looking for Part 1?: Learn more about the design of the proxy pattern and other similar patterns including the adapter, decorator, and façade. After brushing up on Using Rate Limiting on Method Calls With Laravel Part 1 come back here for a more in depth understanding of how to implement the pattern using a rate limiter.

Set Up the Model

To get started, it is important to create the data model. This example will use a Photo model, which might be used by a content management system (CMS) or a blogging application. The actual creation of a Photo is not a costly unit of work, but for the purposes of this article it will be. To make this a bit more realistic, just assume that the business simply wants to implement a rule that prevents a user from posting too many photos in a given period of time. Perhaps they need to limit photos because a usability study showed that the operation was too taxing on server performance, or because too many uploads led to negative user interaction across the network. Here is an example of Laravel's excellent active-record ORM Eloquent-based Photo model:

Pro Tip: Throughout this article all of the DocBlocks and other comment blocks have been removed to keep the examples abbreviated. Good developers should always document their code: code is not complete until it is documented. See the example code on Artisans Collaborative's Github for complete code samples.

class App\Photo extends Eloquent
{
    protected $table = 'photos';

    protected $fillable = [
        'caption',
        'exif',
        'path',
        'size',
        'type',
    ];
}

With the Eloquent-based model, a call to Photo::create($attributes) would perform the necessary unit of work and then return to the parent method a Photo object. While it would be possible to rate limit this model method, there are multiple ways to save an Eloquent model. While internally all these methods make calls to save(), rate limiting a non-standard interface leads to an undesired coupling of the proxy service to its proxied model implementation. Coupling to the model directly makes the code more brittle, for example substituting the Eloquent-based model with a Jessenger-based model. Instead, we create a more consistent interface that we can rely upon to perform the rate limiting. This naturally points to the need for a repository class to encapsulate and organize model interactions.

Use a Repository Class

The repository pattern is an abstraction layer between the data access layer and the business logic layer of an application so that a unit of work can be encapsulated and decoupled from a specific implementation. The main programming benefit of a repository is that interactions between Controllers and Models in the MVC (or HMVC) are defined by an interface and separated by the implementation of the repository. This makes changes to the Models and the data access layers much more flexible. It also organizes code, which would otherwise be shoved into a Model or a Controller, into a convenient unit-of-work layer that keeps both the Model and the Controller thin.

Truth be told, Laravel's Eloquent ORM behaves similarly to a repository class because of its active-record nature and the database adapters it supports. Repository classes are found more commonly in other frameworks that do not provide an active record implementation or that use simpler data models. As mentioned earlier, if the Photo model was backed by a Jessenger-based class or perhaps a custom Guzzle customer for an HTTP-based model, then a repository makes more sense. Getting comfortable with using the repository pattern will help avoid making costly rewrites later as the application code scales.

The best way to start with the repository pattern is to define a contract that the customer code (the controller) can rely on. This contract is the interface that the repository class will implement. It is this interface that extracts the specifics of the data access layer from the customer. The controller will not need to know that it is interacting with an Eloquent-based model. The controller only needs to know that the repository will accept the call and return an expected type of response.

Here is the create() method interface for the repository class:

interface App\Contracts\PhotoRepository
{
    /**
     * Save and return a new Photo model.
     *
     * @param  array $attributes
     *
     * @return \App\Photo
     */
    public function create(array $attributes);
}

Now that there is a defined interface for the repository class, the application can use Laravel's Inversion of Control (IoC) container to resolve the appropriate implementation out of the container. The important takeaway with this interface is the fact that this method appropriates attributes that should be assigned to the created Photo model and then returns that same model after it has been persisted to storage. This is the unit of work that for business reasons needs to be rate limited.

This contract is coupled to the Photo model itself, which we know is an Eloquent-based model. To reduce coupling, it would be a good idea to make the Photo model implement an interface itself and then the @return hint would be changed to this interface name instead. This extra layer of complexity would result in no benefit to the immediate code, which is why it is not shown here. It may, however, create a bit more reliability as the codebase evolves. Either way, the PhotoRepository interface makes sure the customer controller code does not know anything about the implementation of the repository class.

All that is left is to implement the logic that accesses the data layer. Since the repository is going to pass calls to an Eloquent-based model, the repository will receive its Photo model as a constructor argument. When the repository is resolved out of the IoC container, Laravel will inject the Photo model into the PhotoRepository making it easy to add the necessary model manipulations.

class App\Repositories\PhotoRepository implements App\Contracts\PhotoRepository
{
    protected $model;

    public function __construct(App\Photo $model)
    {
        $this->model = $model;
    }

    public function create(array $attributes)
    {
        $model = $this->model->newInstance();
        $model->fill($attributes);
        $model->save();

        return $model;
    }
}

The constructor receives its Photo model and assigns it to the $model property on the PhotoRepository. This basic dependency injection pattern makes swapping out one Photo model implementation with another very efficient as all the logic inside the create() method simply has to refer to the $model property to perform its manipulations.

The create() method receives its array of $attributes and fills in a new instance of the underlying Photo model. While it is possible to hydrate the model within the call to newInstance() for clarity, it is often better to use the long-hand. A good developer will make functionality as transparent as possible, as this keeps the knowledge overhead of the system to a minimum. Take note of the fact that the $attributes are not optional since the business logic surrounding that model cannot be created without providing their necessary attributes at the runtime level. It is still possible to pass in an empty array of attributes, so be sure to validate the model before saving. For model validation, we recommend the esensi/model package. Finally, notice that after the model saved, it returned, making the method adhere with the create() method signature from the PhotoRepository contract.

Now that the application has an implementation of the PhotoRepository contract, the container system needs to know that whenever the controller asks for a PhotoRepository contract it needs to return the implementation it just created. This is known as binding an interface to an implementation. With Laravel, this is done using a service provider class. The PhotoRepository will be a service provided to the application. By binding the repository into the container with the contract name, any other customer code can resolve the repository as needed by requesting it with the contract name. Since Laravel uses PSR-4 namespacing, this means that any injection of App\Contracts\PhotoRepository will resolve to App\Repositories\PhotoRepository by the container service.

Below is the PhotoServiceProvider, which will be used to perform the binding:

use App\Contracts\PhotoRepository as PhotoRepositoryInterface;
use App\Repositories\PhotoRepository;

class App\Providers\PhotoServiceProvider extends Illuminate\Support\ServiceProvider
{
    public function register()
    {
        $this->app->bind(PhotoRepositoryInterface::class, PhotoRepository::class);
    }
}

Notice that in the PhotoServiceProvider, the use statements also perform local aliasing. This is to get around the class name conflict between the contract and the implementation of the PhotoRepository. Some developers just suffix the class name of the contract class with Interface, as in PhotoRepositoryInterface, to not have to use this aliasing method. While there is no right way, it can look wrong to those who do not understand how Laravel's IoC container service works when seeing an interface injected as a dependency.

The last thing to do is to let Laravel know that this PhotoServiceProvider is available, which is a matter of adding an entry to the providers key within the config/app.php file. It is also possible to do the binding within the default AppServiceProvider, in which case the PhotoServiceProvider is not needed, and adding the class to the list or providers could be skipped:

'providers' => [
    // ... add to the end of the existing list
    App\Providers\PhotoServiceProvider::class,
],

Create an API Controller

Going back to the original description given in Part 1 of this article, the customer code in the application would typically be a controller class. As also pointed out, in an HMVC there are times this controller layer of business logic does not actually exist in a controller class but rather in an API class or even in an Artisan console command. The example that follows takes the more common example found in an HMVC organized application where UI controllers make calls to the API controller.

The application will first need a PhotoApi controller. This customer class will forward input data to the PhotoRepository as marshaling inputs is the primary responsibility of an API controller:

use Illuminate\Http\Request;

class App\Http\Apis\PhotoApi
{
    protected $repository;

    public function __construct(App\Contracts\PhotoRepository $repository)
    {
        $this->repository = $repository;
    }

    public function store(Request $form)
    {
        return $this->repository->create($form->inputs());
    }
}

Pro Tip: After a project grows to any reasonable size, the use of the basic App\Http\Controllers namespace becomes unwieldy for all the UI controllers and API controllers. Consider instead of using App\Http\Apis as the namespace for all API controllers and App\Http\Controllers as the namespace for all UI controllers.

Notice that PhotoApi uses the same dependency injection pattern as the PhotoRepository. This time, however, the PhotoRepository is being injected into the PhotoApi and assigned to the $repository property. Once again, this makes methods like store() purposefully ignorant of the specific repository being called. Using the PhotoRepository contract type hint within the constructor ensures that whatever is injected adheres to the interface or is at least resolved out of the container.

The actual store() method is nothing particularly interesting. Calls forwarded by API routes to the API controller usually involve a payload of form inputs, which get passed as arguments to the repository method. Sometimes there are a few repository method calls that are coordinated by the controller, but the API controller usually only concerns itself with the requests and not the responses.

To provide a public access endpoint to the API layer, a simple route binding needs to be setup. Since this PhotoApi uses the store() method (a resourceful word choice) and maps to the PhotoRepository create() method (a CRUD word choice), it makes the most sense to create an HTTP POST request to a resource URL. Since the Photo model will be returned to the PhotoApi, this makes for a very simple JSON API thanks to the HTTP layer components of the Laravel framework.

$router->post('api/photos', 'App\Http\Apis\PhotoApi@store');

Pro Tip: After a project grows to any reasonable size, using a single routes.php file for all the routes will be cumbersome. Consider organizing the RouteServiceProvider that ships with Laravel to include multiple namespaced route files. It is recommended to move these files into the app/Http/Routes folder, which calls the files semantically api.php and ui.php or the name of the particular UI context.

Create a UI Controller

When an application consumes its own API, it is often called "dogfooding” which is exactly what a well-built HMVC will do. While there are many ways to build on top of the API, including making external and internal API calls as well as simple inheritance and complex dependency injection, always have one simple concept in mind: separation of concern. This is the fundamental distinction between HMVC and basic MVC. While the MVC paradigm considers all controllers as equal and therefore has to concern itself with both requests and responses, HMVC provides a hierarchy of controller layer components (among other components). This means that while the API is only concerned with handling complex inputs (like the form request parameters and HTTP heads) and providing simple outputs (like the Photo model or an even simpler data-transfer object), the UI controllers can concern themselves only with the complex outputs (like HTML views and other representations).

A UI controller is any controller by programmer-design that concerns itself with the specific HTTP URI context. Since Laravel is primarily a web application framework, this means that the UI context is usually an HTML page of the website. The UI context may be a photo upload page for new user registration, a member-only photo upload page, or an administrative photo management page. The UI context often varies while the API is willfully ignorant. Logic surrounding the presentation of the PhotoApi response can, therefore, be customized by a given UI controller based on the UI context. This logic is clearly organized in the UI controller that maps to that specific UI context. Local authorization using Laravel's policy-based access control layer (ACL) can be confined to the appropriate local UI controller, while more general authorization can be defined for the API controller.

Take a look at the following example PhotoController, which builds its UI context directly on top of the API controller using inheritance by class extension. This should clear up any confusion:

use App\Http\Apis\PhotoApi;
use Illuminate\Http\Request;

class App\Http\Controllers\PhotoController extends PhotoApi
{
    public function uploadForm()
    {
        return view('upload');
    }

    public function upload(Request $form)
    {
        $photo = parent::store($form);

        return redirect()
            ->to('photos/'.$photo->id)
            ->with('message', 'Photo uploaded!');
    }
}

The first thing to note is the simple class inheritance provided by PhotoController extends PhotoApi. This inheritance means that the PhotoController has the same methods as PhotoApi including the store() method. This UI controller then introduces new UI contexts, which utilize a different naming convention from the resource-based API controller. Laravel has support for many conventions and while using an action verb like upload and the form suffix works, these could have just as easily been defined as getUpload and postUpload if that makes more sense. If the original store() method of the PhotoApi was used, then it would have to conform to the same signature, which may not be contextually necessary.

The business logic embedded in this controller is rather simple, but it illustrates a common request and response pattern where a view is served for the upload form and then a redirect with a flash message is provided by the upload post back on success. The upload() method simply forwards its call to the parent PhotoApi's store() method and then captures the Photo model it should return on success to a local variable. This example does not handle what to do with an error case but presumably the PhotoApi class would return an appropriate exception should an error occur while trying to call to PhotoRepository's methods. Laravel's default error handler should catch this and handle it appropriately. If a local, contextually-aware message is rendered instead, then the call to parent::store() could be wrapped in a try and catch and a different exception could be thrown.

Another approach to the composition of these two classes could use dependency injection to provide the PhotoApi to the PhotoController. This would get around the method signature problems that could be encountered by inheritance. Another problem with inheritance is that by extending one UI controller onto another, a simple call like parent::store() would not be able to traverse the inheritance tree to find the parent API class. The resulting conflicts can be very challenging to debug and also to get around. A simple trait method such as api() as implemented by esensi/core package can be a handy tool for this purpose. If risk for this sort of conflict is a concern of the application architects, then it might be a good idea to look into composition patterns instead of inheritance patterns.

As before with the PhotoApi, an HTTP route needs to bind to the router so that requests to that URI call the PhotoController, which in turns calls the PhotoApi, which in turn calls the to be rate-limited PhotoRepository:

$router->get('photos/upload', 'PhotoController@uploadForm');
$router->post('photos/upload', 'PhotoController@upload');

Notice how the photos/upload path parameter of the route is contextually defined by the UI itself. While an API may be able to utilize the whole spectrum of HTTP verbs, typically only GET and POST methods are used by HTML pages. This usually leads to more verbose URIs for the UI controller's route bindings. There is also usually the need for a GET binding corresponding to a form view like the one bound to PhotoController@uploadForm and a separate POST binding corresponding to a form processing method like the one bound to PhotoController@upload.

Pro Tip: After a project grows to any reasonable size, referring to specific URIs from within the controllers can become annoying. Changes on the frontend and public URIs will require changes to the controller logic, which is counterproductive. Consider naming routes and referring to the routes by name with calls to route() instead of to() within the controller layer. This will allow URI changes without coupling code unnecessarily. Take some time to choose route names otherwise changing route names will become a new annoyance.

Create the Rate Limiter Service

Now all the necessary application logic is in place to build an organized and maintainable HMVC-based application. The need remains, however, to implement the actual rate-limiting requirement. While implementing HTTP rate limiting would still be advised as a more general approach to the throttling of customer hits against the application's API, consider method rate-limiting as an additional security measure to implement resource specific rate-limiting closer to the root of the problem.

Remember: This article is using a simple business rule as the reason for needing a rate-limiting scheme and is only using rate-limiting as an example of how to implement a useful proxy pattern service class. Always consider the complete context of the application being built when evaluating any sort of security or performance requirements.

First take a thorough look at the service class that will be rate-limiting the PhotoRepository service class. While reading, take note that the Repository interface injected is a Laravel contract that resolves to the underlying cache driver the Cache facade in Laravel uses. Read each line and take the time to understand how it works.

use Illuminate\Contracts\Cache\Repository;

class App\Services\RateLimiter
{
    protected $prefix;

    protected $cache;

    protected $timeout = 10;

    protected $limits = [];

    public function __construct(Repository $cache, array $limits = [])
    {
        $this->cache = $cache;
        $this->limits = $limits;
    }

    public function isLimited($key)
    {
        return in_array($key, array_keys($this->limits));
    }

    public function limitExceeded($key)
    {
        return $this->getHits($key) >= $this->getMax($key);
    }

    public function getMax($key)
    {
        return (int) array_get($this->limits, $key, 10);
    }

    public function getHits($key)
    {
        return $this->cache->get($this->getKey($key), 0);
    }

    public function addHit($key)
    {
        if (!$this->cache->has($this->getKey($key))) {
            return $this->cache->add($this->getKey($key), 1, 1);
        }

        return $this->cache->increment($this->getKey($key), 1);
    }

    public function getKey($key)
    {
        return $this->prefix ? $this->prefix.'::'.$key : $key;
    }

    public function setPrefix($prefix)
    {
        return $this->prefix = $prefix;
    }

    public function getTimeout()
    {
        return (int) $this->timeout;
    }

    public function setTimeout($timeout)
    {
        return $this->timeout = (int) $timeout;
    }

    public function getLimits()
    {
        return $this->limits;
    }

    public function setLimits(array $limits)
    {
        return $this->limits = $limits;
    }
}

This article will not go into great detail about how the RateLimiter works or even demonstrate how to bind it into the application container, as that is not the primary goal of the article. In a nutshell, the rate limiter increments a hit counter with Laravel's built-in Cache store and provides methods for looking up the specific limits for different keys that the cache store has. These limits are set on the class under a $limit property. When the limits are reached then the $timeout property can be used to determine the period of time that the ban should be in effect for. Lastly, there is a $prefix property, which allows the programmer to organize the cached keys under prefixes based on the context in which the RateLimiter service is used. All the methods provided are to make customizing the behavior possible.

Pro Tip: Since the writing of this article, Laravel released a new rate limiter service class which does some of the basics of this implementation. An extension of Laravel's rate limiter could just as easily be used to achieve the same functionality the following PhotoRepository proxy relies on. Neither implementation uses an advanced rate limiter scheme like the "leaky bucket" that is more appropriate for most use cases.

Proxy the Repository

Now that a RateLimiter service class is available, it is time to create the proxy for the PhotoRepository class. This proxy implements the same PhotoRepository interface as the repository and, therefore, can be substituted anywhere it would be used by the PhotoApi or another customer code. While looking at the code that follows, take note that unlike the PhotoApi where the real App\Repositories\PhotoRepository was resolved out of the container using the App\Contracts\PhotoRepository interface type hint, in the App\Repositories\Proxies\PhotoRepositoryProxy proxy the real App\Repositories\PhotoRepository is directly type hinted and therefore injected by Laravel's IoC container. This is a small but necessary implementation detail that makes the pattern work with Laravel.

As the code below will demonstrate, the PhotoRepository proxy uses the magic __call method to forward all method calls along to the real repository class. This is how the proxy adheres to the contract and is a useful trick to learn. Otherwise, all the methods implemented by the contract would have to be boiler-plated here on the proxy with simple call forwarding. Using the magic methods makes the code-base smaller. Notice how any methods that cannot be forwarded to the proxy raise a BadMethodCallException exception:

use App\Exceptions\RateLimitException;
use App\Repositories\PhotoRepository;
use App\Services\RateLimiter;
use BadMethodCallException;

class App\Repositories\Proxies\PhotoRepositoryProxy
{
    protected $timeout = 10;

    protected $instance;

    protected $limiter;

    protected $limits = [
        'create' => 10,
    ];

    public function __construct(PhotoRepository $instance, RateLimiter $limiter)
    {
        $this->instance = $instance;
        $this->limiter = $limiter;
        $this->boot();
    }

    public function __call($method, $parameters)
    {
        if (method_exists($this->instance, $method)) {

            if ($this->limiter->isLimited($method)) {

                if ($this->limiter->limitExceeded($method)) {
                    $callable = get_class($this->instance).'::'.$method;
                    $max = $this->limiter->getMax($method);
                    $timeout = $this->limiter->getTimeout();
                    $message = $callable.'() cannot be called more than '.$max.' in '.$timeout.' minutes.';
                    throw new RateLimitException($message, 429);
                }

                $this->limiter->addHit($method);
            }

            return call_user_func_array([$this->instance, $method], $parameters);
        }

        $message = 'Method '.$method.' not implemented on '.get_class($this->instance).'.';
        throw new BadMethodCallException($message);
    }

    public function boot()
    {
        $this->limiter->setPrefix(get_class($this->instance));
        $this->limiter->setLimits($this->limits);
        $this->limiter->setTimeout($this->timeout);
    }
}

The code should read very clearly, but to elaborate, the dependencies of the proxy, including the underlying real PhotoRepository service class and RateLimiter service class, are injected into the proxy via the constructor. These are assigned to local properties for the same reasons mentioned earlier. A call to the boot() method configures the RateLimiter for this proxy's specific context, including a dynamic cache prefix, the proxy's limits, and the specific timeout for the resource.

When in use, all methods are forward to the magic __call method, which first checks if the method is valid. This check retains the normal behavior of PHP when classes do and do not have methods. As a reminder, the goal of the proxy pattern is not to introduce new interfaces, but rather to maintain existing interfaces and introduce new behavior. This is a crucial part of keeping this class a proxy and nothing else. The main takeaway here is that the proxy can only do what the real subject can do.

If the method does exist on the PhotoRepository, then the proxy will check to see if the called $method is rate limited. If it is not rate limited, then the call is forwarded to the PhotoRepository and that is it. If, however, it is a rate limited method according to the $limits, which were bound to the RateLimiter, then a subsequent statement will check if the hits limit has been exceeded. If the rate has been exceeded, then a RateLimitException exception will be raised and the code will exit the current method. If the rate has not been exceeded, then the hit counter will be incremented and once again the call will be forwarded to the PhotoRepository. The main takeaway here is that the proxy always forwards the calls to the real subject or introduces an alternate behavior when appropriate.

Pro Tip: Since most applications could benefit from the a rate-limiting proxy to limit expensive units of work, it is probably a good idea to abstract this specific proxy class as a trait or as an abstract proxy that each repository-specific proxy can extend.

With the PhotoRepository proxy setup, it is not possible to swap out the real PhotoRepository for the proxy double. Since earlier the repository was bound into the container using the contract, all that is needed is to change the class that is bound to this interface. Recall from earlier where the PhotoServiceProvider was defined and note the change to the use App\Repositories\PhotoRepository statement:

use App\Contracts\PhotoRepository as PhotoRepositoryInterface;
use App\Repositories\Proxies\PhotoRepositoryProxy;

class App\Providers\PhotoServiceProvider extends Illuminate\Support\ServiceProvider
{
    public function register()
    {
        $this->app->bind(PhotoRepositoryInterface::class, PhotoRepositoryProxy::class);
    }
}

Now with the PhotoRepository proxy rate-limiting method calls to the create() method of the real PhotoRepository, the business rules have been implemented. The development team can then report back to the quality assurance team that a new usability test should be conducted to see if limiting the number of requests to the method improves the usability of the application for users. But before the code can be completely ready for production, it would be a good idea to tie up some loose ends.

Code Samples: For the complete source code, head over to Artisans Collaborative's Github account and download the sample code that corresponds with this article series. If you find a bug, be sure to submit an issue so we can update the code and the article.

Handling Rate Limit Exceptions

In the PhotoRepository proxy, notice that a RateLimitException was thrown whenever the limits were exceeded for calls to the create() method. Laravel's default exception handler does not know anything about this and, in fact, this RateLimitException does not yet exist. The reason for throwing a custom exception is so it can be reported and rendered appropriately by the framework's exception handler. The following is a rudimentary implementation:

class App\Exceptions\RateLimitException extends \Exception
{
}

The catch for this exception is handled by the App\Exceptions\Handler. While customizing the Handler is outside of the scope of this article, it may be necessary to report errors differently based on the user session or to render a proper 429 HTTP status code to whatever HTTP customer is hitting the resource or a custom error message to whatever non-HTTP customer (such as a CLI command) is calling the code.

Making the Rate Limiter Smarter

One last glaring problem with the RateLimiter is that the keys are all stored in a global namespace. While this might work if the goal is to simply limit all calls to the resource against a global limit, most likely the RateLimiter needs to be session based. Using unique session keys may be as simple as customizing the prefix assigned to the RateLimiter in the boot() method of the PhotoRepository proxy, though there are no limitations to using IP addresses on large shared networks. Using IP addresses also couples the rate limiting scheme to the HTTP layer. Using the authentication services of Laravel, the Auth::id() could be used to retrieve the session user's ID, but that also breaks down if the user is not authenticated, as could be the case when calls are made from an Artisan console command.

Additionally, it may be necessary to make the limit controls a bit more customizable or even to be policy-based so different users can have different limits. This is often the case for free and paid tier SaaS products that implement an API. Alternatively, it could be possible that the simple hit counter scheme needs to be swapped out with a leaky-bucket rate limiter or a resource size throttler. Finally, consider whether the hits should be stored in a cache or computed based on another resource, in which case the rate limiter is more of a gate control. Again, this can be very useful for limiting the ability of a free-tier subscriber to upload more than say five photos as part of their SaaS plan.

Proxies For Everything Some Things

A proxy prohibits the customer’s direct access and, therefore, knowledge of the subject. The proxy acts as the real subject, while providing an alternate behavior or simply forwards the request to the real subject. The proxy pattern is the most versatile pattern of other similar patterns – adapter, decorator, façade. The benefits of proxies becomes clear when working with middleware pipelines found in many frameworks, including Laravel.

Proxies can be used in different ways other than as a rate limiter. Proxies can be used for just about anything. Proxies can pass calls through a cache service to speed up the response on expensive queries that do not need to be real-time. Proxies can log calls made to the subject using a service otherwise unknown and therefore decoupled from the customer and subject. Proxies could mock expensive real objects with virtual ones for testing purposes. Protection proxies could be used to control customer access based on permissions and the abilities of the session user. By using proxies, developers can do all sorts of aspect-oriented programming (AOP).

While the proxy pattern is a valuable tool in the tool-belt of the application engineer, it is not the right pattern for everything. Just as the problem introduced by MVC arose from the natural hierarchy of a complex application, the use of the proxy pattern should come out of the natural need to solve a problem that the proxy is intended for. The purpose of the proxy is to add new behavior while maintaining decoupled code. Implementing any pattern should be done because it is organically needed or appears naturally in the careful organization of application business logic. Never use a pattern just because it is the newest skill learned or because all the experienced developers are talking about it. Always use the right solution for each specific engineering problem.

For more information on different application architecture concepts mentioned in this article, consider reading the following extended source material:

  1. http://martinfowler.com/eaaCatalog/repository.html
  2. http://www.sitepoint.com/repository-design-pattern-demystified
  3. http://code.tutsplus.com/tutorials/the-repository-design-pattern--net-35804
  4. http://shawnmc.cool/the-repository-pattern
  5. http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
  6. https://en.wikipedia.org/wiki/Leaky_bucket