Backend Development - Controller Responses

In the previous topic, we learned how routes map URLs to controllers. Now we move one step deeper into backend Drupal: what controllers return.

A controller’s job is not to print HTML. Its job is to return a response object or render array that Drupal knows how to process.

This article explains the different controller response types Drupal supports, when to use each one, and how they fit into Drupal’s request–response lifecycle. We continue extending the same weeklydrupal_demo module so concepts stay connected.

By the end of this topic, you will understand:

  • What a controller response is
  • Render arrays vs response objects
  • HTML page responses
  • Redirect responses
  • JSON responses
  • When to use each type

1. What Is a Controller Response

A controller response is the value returned by a controller method.

Drupal expects that return value to be something it can turn into an HTTP response.

Common controller return types:

  • Render arrays
  • Redirect responses
  • JSON responses
  • Plain response objects

Drupal inspects what you return and handles it appropriately.


2. Render Arrays (Most Common)

Render arrays are the default and recommended response type for HTML pages.

Example:

public function page() {
  return [
    '#markup' => 'Hello from a controller',
  ];
}

What happens internally

  1. Controller returns a PHP array
  2. Drupal processes the render array
  3. Caching and theming are applied
  4. HTML output is generated

Render arrays allow Drupal to manage:

  • Caching
  • Security
  • Theme overrides

This is why controllers should not echo HTML.


3. Why Render Arrays Are Preferred

Render arrays:

  • Integrate with Drupal’s cache system
  • Can be altered by other modules
  • Respect theme layer separation
  • Are safer than raw HTML output

If you are building a page that users view in a browser, render arrays should be your first choice.


4. Using Markup Safely

When using #markup, always remember:

  • Strings are escaped by default
  • Use $this->t() for translatable text

Example:

return [
  '#markup' => $this->t('Welcome to WeeklyDrupal'),
];

Avoid returning raw HTML unless absolutely necessary.


5. Redirect Responses

Sometimes a controller should redirect the user instead of rendering a page.

Example use cases:

  • After form submission
  • Access-based routing decisions
  • Workflow navigation

Example redirect

use Symfony\Component\HttpFoundation\RedirectResponse;

public function redirectExample() {
  return new RedirectResponse('/');
}

Drupal will send an HTTP redirect response to the browser.


6. Redirecting Using Routes (Recommended)

Instead of hardcoding URLs, Drupal recommends redirecting using route names.

use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;

public function redirectExample() {
  $url = Url::fromRoute('<front>')->toString();
  return new RedirectResponse($url);
}

This keeps redirects stable even if paths change.


7. JSON Responses (APIs and AJAX)

For APIs and AJAX callbacks, controllers often return JSON.

Example:

use Symfony\Component\HttpFoundation\JsonResponse;

public function jsonExample() {
  return new JsonResponse([
    'status' => 'ok',
    'message' => 'Hello from backend',
  ]);
}

Drupal will:

  • Set the correct headers
  • Encode the response as JSON

8. When to Use JSON Responses

Use JSON responses when:

  • Building REST-like endpoints
  • Handling AJAX requests
  • Exposing backend data

Do not use JSON responses for normal HTML pages.


9. Plain Response Objects

In rare cases, you may need a full response object.

Example:

use Symfony\Component\HttpFoundation\Response;

public function plainResponse() {
  return new Response('Raw response body', 200);
}

This gives you full control over headers and status codes, but bypasses Drupal’s render system.


10. Choosing the Right Response Type

Use caseRecommended response
HTML pageRender array
RedirectRedirectResponse
AJAX / APIJsonResponse
Low-level controlResponse

Choosing the correct response keeps your backend predictable and maintainable.


11. Common Mistakes to Avoid

  • Echoing HTML in controllers
  • Returning strings instead of render arrays
  • Hardcoding URLs in redirects
  • Mixing business logic with response formatting

Controllers should coordinate responses, not generate data.


12. Learning by Building: weeklydrupal_demo

Our weeklydrupal_demo module now demonstrates:

  • HTML responses via render arrays
  • Redirect responses
  • JSON responses

Future topics will build on these responses for:

  • Forms
  • AJAX interactions
  • API integrations

13. Why Controller Responses Matter

Understanding controller responses helps you:

  • Build clean backend APIs
  • Avoid caching issues
  • Separate logic from presentation
  • Write predictable Drupal code

This knowledge is essential for backend developers.