6
I would like to know the best coding practice that allows the client to define the response format for the request he made, which can also include filters, conditions, ordering, etc...
I made a small model for the answer, I do not know if it is the best practice, but it works (advice are welcome). I coded in Middleware after();
PS.: The format choice will be dynamic after constructing the request code.
Now about the request. I imagined coding in Middleware before(). What is the best way to do?
Follows the code:
index php.
<?php
define('ROOT', dirname(__DIR__));
chdir(ROOT);
require 'vendor/autoload.php';
require 'src/Config/bootstrap.php';
require 'src/Config/routes.php';
$app->run();
bootstrap.php
<?php
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
$app = new Application();
$app['serializer'] = function(){
$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizers = array(new ObjectNormalizer());
return new Serializer($normalizers, $encoders);
};
$app['debug'] = true;
/*$app->before(function (Request $request) use ($app){
$request->query->
});*/
$app->after(function (Request $request, Response $response) use ($app){
//var_dump($response);
$response->headers->set('Content-Type', 'application/xml');
return $response;
});
return $app;
Routes.php
<?php
$app->mount('/classificados', require 'src/App/Controllers/ClassificadosController.php');
Classifiedsontroller.php
<?php
use Symfony\Component\HttpFoundation\Response;
$classificados = $app['controllers_factory'];
$classificados->get('/', function() use ($app) {
$post = array(
'title' => 'Titulo',
'body' => 'corpo',
);
$serializeContent = $app['serializer']->serialize($post, 'xml');
return new Response($serializeContent, 200);
});
return $classificados;
How best to build a logic to streamline the response format (json or xml) for the client?
UPDATE
I refactored my code by the @Guilherme Nascimento response, had the idea of always returning a json from Controller and in after(), if an xml has been asked to deserialize the return and serialize in a new Answer in xml format, if a json is requested it would return the Sponse itself without performing this procedure, with the intention of abstracting this procedure from each route? Does it get too expensive for the server?
Stayed like this:
bootstrap.php
<?php
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
$app = new Application();
$app['debug'] = true;
$app['formatSerialize'] = function($format){
$app['formatSerialize'] = $format;
};
$app->before(function (Request $request) use ($app) {
$app['formatSerialize'] = (array_key_exists('xml', $request->query->all()) == 1) ? 'xml' : 'json';
});
$app->after(function (Request $request, Response $response) use ($app){
if ($app['formatSerialize'] == 'xml'){
$serializer = new Serializer(array(new ObjectNormalizer()), array(new XmlEncoder(), new JsonEncoder()));
$data = json_decode($response->getContent(), true);
$serializeContent = $serializer->serialize($data, $app['formatSerialize']);
$resp = new Response($serializeContent, $response->getStatusCode());
$resp->headers->set('Content-Type', 'application/xml');
return $resp;
}
$response->headers->set('Content-Type', 'application/json');
return $response;
});
return $app;
Classifiedsontroller.php
<?php
$classificados = $app['controllers_factory'];
$classificados->get('/', function() use ($app) {
$post = array(
'title' => 'Titulo',
'body' => 'corpo',
);
return $app->json($post, 200);
});
return $classificados;
This deserialization and re-serialization is very costly?
A good practice is to let and return type being informed by the application header. In the case who is making the request, must inform in the header Content-Type application/json or application/xml
– Flávio Marcheni