Пакетные запросы на Symfony
Я пытаюсь воспроизвести поведение пакета facebook просит функция на их графике api.
поэтому я думаю, что самое простое решение-сделать несколько запросов на контроллере на мое заявление типа:
public function batchAction (Request $request)
{
$requests = $request->all();
$responses = [];
foreach ($requests as $req) {
$response = $this->get('some_http_client')
->request($req['method'],$req['relative_url'],$req['options']);
$responses[] = [
'method' => $req['method'],
'url' => $req['url'],
'code' => $response->getCode(),
'headers' => $response->getHeaders(),
'body' => $response->getContent()
]
}
return new JsonResponse($responses)
}
Так с этим решением, я думаю, что мои функциональные тесты будут зеленые.
однако я заполняю, как инициализация контейнера службы X раз может сделать приложение намного медленнее. Потому что для каждого запроса, каждый пакет построен, контейнер обслуживания перестроен каждый раз etc...
вы видите какое-либо другое решение для моей проблемы?
другими словами, Мне нужно сделать полные новые HTTP-запросы на мой сервер, чтобы получить ответы от других контроллеров в моем приложении?
заранее спасибо за Ваши советы!
2 ответов
внутренне Symfony обрабатывать запрос с помощью http_kernel
компонент. Таким образом, Вы можете имитировать запрос для каждого пакетного действия, которое хотите выполнить, а затем передать его в http_kernel
компонент, а затем уточнить результат.
рассмотрим этот пример контроллера:
/**
* @Route("/batchAction", name="batchAction")
*/
public function batchAction()
{
// Simulate a batch request of existing route
$requests = [
[
'method' => 'GET',
'relative_url' => '/b',
'options' => 'a=b&cd',
],
[
'method' => 'GET',
'relative_url' => '/c',
'options' => 'a=b&cd',
],
];
$kernel = $this->get('http_kernel');
$responses = [];
foreach($requests as $aRequest){
// Construct a query params. Is only an example i don't know your input
$options=[];
parse_str($aRequest['options'], $options);
// Construct a new request object for each batch request
$req = Request::create(
$aRequest['relative_url'],
$aRequest['method'],
$options
);
// process the request
// TODO handle exception
$response = $kernel->handle($req);
$responses[] = [
'method' => $aRequest['method'],
'url' => $aRequest['relative_url'],
'code' => $response->getStatusCode(),
'headers' => $response->headers,
'body' => $response->getContent()
];
}
return new JsonResponse($responses);
}
со следующим методом контроллера:
/**
* @Route("/a", name="route_a_")
*/
public function aAction(Request $request)
{
return new Response('A');
}
/**
* @Route("/b", name="route_b_")
*/
public function bAction(Request $request)
{
return new Response('B');
}
/**
* @Route("/c", name="route_c_")
*/
public function cAction(Request $request)
{
return new Response('C');
}
вывод запроса будет:
[
{"method":"GET","url":"\/b","code":200,"headers":{},"body":"B"},
{"method":"GET","url":"\/c","code":200,"headers":{},"body":"C"}
]
PS: надеюсь, что я правильно понял, что вам нужно.
существуют способы оптимизации скорости тестирования, как с конфигурацией PHPunit (например, xdebug config, так и с запуском тестов с помощью PHPDBG SAPI вместо включения модуля Xdebug в обычный экземпляр PHP).
поскольку код всегда будет запускать класс AppKernel, вы также можете поместить туда некоторые оптимизации для определенных сред, включая initiali[zs]ING контейнер реже во время теста.
Я использую один такой пример Крис Wallsmith. Вот его пример кода.
class AppKernel extends Kernel
{
// ... registerBundles() etc
// In dev & test, you can also set the cache/log directories
// with getCacheDir() & getLogDir() to a ramdrive (/tmpfs).
// particularly useful when running in VirtualBox
protected function initializeContainer()
{
static $first = true;
if ('test' !== $this->getEnvironment()) {
parent::initializeContainer();
return;
}
$debug = $this->debug;
if (!$first) {
// disable debug mode on all but the first initialization
$this->debug = false;
}
// will not work with --process-isolation
$first = false;
try {
parent::initializeContainer();
} catch (\Exception $e) {
$this->debug = $debug;
throw $e;
}
$this->debug = $debug;
}