Pair program with me! profile for carousel at Stack Overflow, Q&A for professional and enthusiast programmers

2/09/2014

n-tier meets MVC in Laravel


This is the post about two fundamental architectural patterns that can be found in most todays web framerworks. These patterns are:

  • n-tier represented as client/server model and
  • MVC (model,view,controller)

There is a lot resources online client/server, n-tier so I will take a look at Laravel specific implementations of these patterns. You can argue is MVC architectural or design pattern. I think MVC is closer to well established arch patterns due to its usage and overall complexity.

In Laravel we can exactly detect boundary between them as so as their main flow. Client model starts in the form of HTTP request, which is received from the browser (mostly) and provided to main Application class:

public function __construct(Request $request = null)
 {

  $this->registerBaseBindings($request ?: $this->createNewRequest());

  $this->registerBaseServiceProviders();

  $this->registerBaseMiddlewares();
 }


Request comes in a form of Laravel request which extends Symfony class. After application receives a request, it will registered it as a protected property (object). In this phase, flow is pretty straightforward. If there is no custom middleware functionality, request will end waiting for handler method. There are some minor processing like attaching session driver, but main job is done in a layer that comes after.

I mentioned middleware, which is actually all functionality that lives in a space between the reqeust hits the internal application routes. Laravel (from 4.1 Iversion) implements StackBuilder middleware, which can be used  like a flyweight alternative to caching and session management (and for some other things).

Here is a method that implements StackBuilder:

protected function getStackedClient()
 {
  $sessionReject = $this->bound('session.reject') ? $this['session.reject'] : null;

  $client = with(new \Stack\Builder)
      ->push('Illuminate\Cookie\Guard', $this['encrypter'])
      ->push('Illuminate\Cookie\Queue', $this['cookie'])
      ->push('Illuminate\Session\Middleware', $this['session'], $sessionReject);

  $this->mergeCustomMiddlewares($client);

  return $client->resolve($this);
 }


StackBuilder andLaravel Application class implements Symfony\HttpKernelInterface in the form of handle method. That is why it is called stack - it just forwards request further down the stack till it reaches main Application handler

When request hits Application handler, it is on the door of MVC part of Laravel, which leads further to domain logic and the heart of application.

Take a look at the main handler:

public function handle(SymfonyRequest $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
 {
  try
  {
   $this->refreshRequest($request = Request::createFromBase($request));

   $this->boot();

   return $this->dispatch($request);
  }
  catch (\Exception $e)
  {
   if ($this->runningUnitTests()) throw $e;

   return $this['exception']->handleException($e);
  }
 }


As can be seen, it is dispatched to router, for further processing and which will result with HTTP response.   For now I wont go deeper into source code, since point of this post was just to show conceptual boundary between these two layers. This boundary is sometimes not so visible, due to frameworks specific implementations. One thing that is worth mentioning is that client/server model is dominant model in distributed systems like internet (where client is present), while MVC originated in the deskop environment. If not designed properly, applications made with the mix of these patterns can become very complex and lead to bugs and potential break. For me, it was very important to reckognize them in Laravel, so I could have better insight into awesome framework design.

Thanks for reading.

No comments:

Post a Comment