Vamos começar com uma pequena introdução.
Atualmente trabalho em uma empresa que usa uma API para servir dados de vários serviços.
Esta API é construída usando silex, o que é incrível.
Temos muitos endpoints de API como:
/ blog / blog_id / comments /
/ blog é mapeado para um controlador de blog usando:
$application = new SilexApplication();
$application->mount('/blog', new AppControllerBlog
O controlador do blog costumava ser algo assim:
namespace AppController;
use SilexApplication,
SilexControllerProviderInterface;
class Blog implements ControllerProviderInterface
{
public function connect(Application $application)
{
$this->app = $application;
$controllers = $this->app['controllers_factory'];
$controllers->get(
'/',
array($this, 'getAllBlogPosts')
);
$controllers->get(
'/{blogpost_id}/',
array($this, 'getOneBlogPost')
);
$controllers->get(
'/{blogpost_id}/authors/',
array($this, 'getAllAuthors')
);
$controllers->get(
'/{blogpost_id}/authors/{author_id}/',
array($this, 'getOneAuthor')
);
$controllers->get(
'/{blogpost_id}/comments/',
array($this, 'getAllComments')
);
$controllers->get(
'/{blogpost_id}/comments/{comment_id}/',
array($this, 'getOneComment')
);
$controllers->get(
'/{blogpost_id}/tags/',
array($this, 'getAllTags')
);
$controllers->get(
'/{blogpost_id}/tags/{tag_id}/',
array($this, 'getOneTag')
);
return $controllers;
}
}
Neste exemplo, deixei de fora os outros métodos, mas você entendeu a idéia geral.
Como você pode imaginar, você pode querer obter comentários como um recurso de API de primeira classe (por exemplo, api_url / comments /. Os comentários seriam mapeados para um controlador de comentários. Este controlador teria muito da mesma lógica dos métodos getAllComments e getOneComment do controlador de blog. Isso é ruim quando você mantém o princípio DRY em mente.
Uma solução melhor para esse problema seria encaminhar os métodos getAllComments e getOneComment do controlador de blog para o controlador de comentários. Deixe-me mostrar como isso pode ser alcançado.
1) crie um controlador de comentários separado que tenha os métodos getAllComments e getOneComments.
namespace AppController;
use SilexApplication,
SilexControllerProviderInterface;
class Comments implements ControllerProviderInterface
{
public function connect(Application $application)
{
$controllers = $app['controllers_factory'];
$controllers->get('/', array($this, 'getAllComments'));
$controllers->get('/{comment_id}/', array($this, 'getOneComment'));
return $controllers;
}
// ... other methods
}
2) mapear / comentários para o controlador de comentários
$ application = new Silex Application ();
// … / blog
$ application-> mount (‘/ comments’, new App Controller Comments
3) No controlador de blog, encaminhe solicitações para / blog / id do blog / comentários / & / blog / id do blog / comentários / comment_id / para o novo controlador de comentários.
namespace AppController;
use SilexApplication,
SilexControllerProviderInterface,
SymfonyComponentHttpFoundationRequest,
SymfonyComponentHttpKernelHttpKernelInterface;
class Blog implements ControllerProviderInterface
{
protected $app;
public function connect(Application $application)
{
$this->app = $application;
$controllers = $this->app['controllers_factory'];
...
$controllers->get(
'/{blogpost_id}/comments/',
array($this, 'forwardToComments')
);
$controllers->get(
'/{blogpost_id}/comments/{comment_id}/',
array($this, 'forwardToComments')
);
...
return $controllers;
}
public function forwardToComments($blogpost_id, $comment_id = null)
{
$request = $this->app['request'];
$query = array('blogpost_id' => $blogpost_id);
$uri = $request->getUriForPath('/comments').'/';
$uri .= $comment_id ? $comment_id.'/' : '';
$query = '?' . http_build_query(array_merge(
$request->query->all(),
$query
));
$subRequest = Request::create(
$uri.$query,
$request->getMethod(),
$request->request->all(),
$request->cookies->all(),
$request->files->all(),
$request->server->all()
);
return $this->app->handle(
$subRequest,
HttpKernelInterface::SUB_REQUEST,
false
);
}
}
É isso, você só precisa criar uma nova instância de Request com os parâmetros corretos e deixar Silex Application cuidar disso.