Symfony Batch Requests

I am trying to reproduce the behavior of facebook batch requests on their api chart.

So, I believe that the easiest solution is to make some requests on the controller for my application, for example:

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) } 

So, with this solution, I think my functional tests will be green.

However, I am filling out how initializing a service container X times can make the application much slower. Because for each request, each set is built, the service container is rebuilt every time, etc.

Do you see any other solution for my problem?

In other words, do I need to make complete new HTTP requests to my server in order to receive responses from other controllers in my application?

Thanks in advance for your advice!

+5
source share
2 answers

Symfony internally processes the request using the http_kernel component. That way, you can simulate a request for each batch action that you want to perform, and then pass it to the http_kernel component, and then develop the result.

Consider this example controller:

 /** * @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); } 

With the following controller method:

 /** * @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'); } 

The query output will be:

 [ {"method":"GET","url":"\/b","code":200,"headers":{},"body":"B"}, {"method":"GET","url":"\/c","code":200,"headers":{},"body":"C"} ] 

PS: I hope I understand correctly what you need.

+3
source

There are ways to optimize testing speed, both with PHPunit configuration (for example, with xdebug configuration, and with running tests using phpdbg SAPI instead of including the Xdebug module in a regular PHP instance).

Since the code will always work with the AppKernel class, you can also put some optimizations in certain environments, including initiali [zs] in the container less often during the test.

I use one such example from Kris Wallsmith. Here is a sample code.

 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; } 
0
source

Source: https://habr.com/ru/post/1260214/


All Articles