Por se tratar de um micro framework totalmente baseado em middlewares o Zend Expressive 2 nos permite inicialmente trabalhar no middleware de aplicação e posteriormente adicionarmos camadas comuns ao projeto.
Faremos um middleware genérico que analisará o header Accept enviado pela requisição, adicionaremos um middleware após a execução da ação principal da rota, e o mesmo formatará a saída de acordo com o solicitado.
Curso Zend Expressive - Microframework PHP
Conhecer o cursoPara entendermos melhor os exemplos, trabalharemos na versão do framework usando o skeleton inicial e definindo a opção “Minimal”, da qual somente a estrutura de configuração base vem pronto.
Usaremos as implementações direto nos arquivos config: routes.php e pipeline.php, o que pode ser facilmente substituído por definições de factories no contêiner de serviços.
Show me the code!
Começamos com uma simples rota ela será somente um exemplo de implementação de persistência de um livro em uma API de livraria.
Veja o código:
$app->post('/api/livros', function ($request, $delegate) {
// Implementação de persistência retorno da identificação do livro
$data['livro_id'] = 12;
// A Resposta é delegada para o proximo middleware
// formatar a resposta xml ou json
$response = $delegate->process($request->withAttribute('data', $data));
// Response já implementado
return $response;
});
Ao ser delegado ao próximo middleware, o mesmo precisará existir, para isso podemos colocá-lo na rota ou na pipeline, ao colocar na pipeline criaremos um modelo de retorno que sempre vai validar a existência de Accept, caso exista, será lido e retornado o tipo pedido, caso contrário retorna JSON.
A seguir colocamos em pipeline.php, após o dispatch dos middlewares de aplicação, o middleware que cuidará das respostas, veja o código a seguir:
// Register the dispatch middleware in the middleware pipeline
$app->pipeDispatchMiddleware();
use ZendDiactorosResponseJsonResponse;
use ZendDiactorosResponseEmptyResponse;
$app->pipe(function ($request, $delegate) {
// Recebe o tipo de retorno aceito
$type = $request->getHeaderLine('Accept');
switch ($type) {
case 'application/xml':
// Implementação de resposta xml
// não implementada!
return new EmptyResponse(501);
break;
case 'application/json':
default:
// Implementação de resposta json
return new JsonResponse($request->getAttribute('data'));
break;
}
});
// At this point, if no Response is return by any middleware, the
// NotFoundHandler kicks in; alternately, you can provide other fallback
// middleware to execute.
$app->pipe(NotFoundHandler::class);
Conclusão
Conseguimos dessa forma isolar a implementação de retorno, que pode futuramente ter mais opções, inclusive podemos implementar posteriormente o padrão Strategy, para que a lógica de cada tipo de formatação fique definida por sua classe seguindo um contrato único.
Observe que o middleware de resposta vai procurar pelo atributo data que deverá existir e precisa ser validado.
Com este exemplo, você poderá facilmente partir para outros middlewares adicionais como validação, permissão, classificação etc.
Quer adentrar ainda mais no assunto? Veja o nosso curso de Zend Expressive 2:
Curso Zend Expressive - Microframework PHP
Conhecer o cursoAté a próxima!