Symfony上的批量请求

Ham*_*bot 6 symfony

我试图在他们的图形api上重现facebook批量请求函数的行为.

所以我认为最简单的解决方案是在控制器上向我的应用程序发出几个请求,例如:

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)
}
Run Code Online (Sandbox Code Playgroud)

所以有了这个解决方案,我认为我的功能测试会是绿色的.

但是,我填写像初始化服务容器X次可能会使应用程序更慢.因为对于每个请求,每个包都是构建的,所以每次都重建服务容器等...

您是否看到了我的问题的其他解决方案?

换句话说,我是否需要向服务器发出完整的新HTTP请求以获取应用程序中其他控制器的响应?

提前感谢您的建议!

Mat*_*teo 5

内部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);
}
Run Code Online (Sandbox Code Playgroud)

使用以下控制器方法:

/**
 * @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');
}
Run Code Online (Sandbox Code Playgroud)

请求的输出将是:

[
{"method":"GET","url":"\/b","code":200,"headers":{},"body":"B"},
{"method":"GET","url":"\/c","code":200,"headers":{},"body":"C"}
]
Run Code Online (Sandbox Code Playgroud)

PS:我希望我能正确理解你的需要.