Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Response Types

Response Types

~12 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026

Besides the simple Response from previous chapters, Symfony has several specialized response classes – each for a concrete, recurring use case.

JsonResponse: returning structured data

use Symfony\Component\HttpFoundation\JsonResponse;

#[Route('/projects/{id}/summary', name: 'project_summary', requirements: ['id' => '\d+'])]
public function summary(int $id): JsonResponse
{
    return $this->json([
        'id' => $id,
        'name' => 'Website Relaunch',
        'taskCount' => 12,
    ]);
}

$this->json(...) (from AbstractController) automatically sets Content-Type: application/json and handles JSON serialization – preferable to manual json_encode() plus new Response(...).

RedirectResponse: redirecting to another route

#[Route('/projects/new', name: 'project_new', methods: ['POST'])]
public function new(Request $request): Response
{
    // ... create the project (block 4) ...

    return $this->redirectToRoute('project_index');
}

Recall chapter 7: redirectToRoute() takes the ROUTE NAME, NEVER a hardcoded URL – if project_index's path changes later, this redirect keeps working correctly regardless.

// With route parameters:
return $this->redirectToRoute('project_show', ['id' => $project->getId()]);

// External URL (rarely needed):
return $this->redirect('https://example.com');

BinaryFileResponse: file downloads

use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

#[Route('/projects/{id}/export', name: 'project_export', requirements: ['id' => '\d+'])]
public function export(int $id): BinaryFileResponse
{
    $filePath = $this->getParameter('kernel.project_dir') . '/var/exports/project-' . $id . '.csv';

    $response = new BinaryFileResponse($filePath);
    $response->setContentDisposition(
        ResponseHeaderBag::DISPOSITION_ATTACHMENT,
        sprintf('project-%d.csv', $id)
    );

    return $response;
}

DISPOSITION_ATTACHMENT triggers a "Save As" dialog instead of an inline display in the browser. $this->getParameter('kernel.project_dir') returns the ABSOLUTE path to the project root – never hardcode a relative path, which would resolve differently depending on the execution context.

StreamedResponse: large amounts of data without a memory blowup

use Symfony\Component\HttpFoundation\StreamedResponse;

#[Route('/projects/export-all', name: 'project_export_all')]
public function exportAll(): StreamedResponse
{
    $response = new StreamedResponse(function () {
        $handle = fopen('php://output', 'w');
        fputcsv($handle, ['ID', 'Name']);
        foreach ($this->iterateAllProjects() as $project) {
            fputcsv($handle, [$project['id'], $project['name']]);
        }
        fclose($handle);
    });

    $response->headers->set('Content-Type', 'text/csv');
    return $response;
}

Achtung: StreamedResponse is only worth it for LARGE amounts of data that could exceed available PHP memory – for small CSV exports (like our task manager's case), a regular Response with a fully assembled body is entirely sufficient. Premature optimization without real need only makes code more complex.

Overview: which response type for what

ClassUse case
ResponseHTML, plain text, or Twig-rendered markup.
JsonResponseStructured data for JavaScript/API clients.
RedirectResponseRedirecting to another page after a successful POST (Post/Redirect/Get pattern).
BinaryFileResponseOffering an EXISTING file for download.
StreamedResponseLARGE, dynamically generated output without building it fully in memory.