Skip to main content

Method Responses overview

Every day we interact with many websites during web browsing. 

To get any web resource using a web browser we generally fire a HTTP request to the server.
As developers, we should know what we are sending to the server from our browser using an HTTP request and what we are getting from the server as the HTTP response.

 

Drupal 8 and up, is using Symfony's response objects.

Symfony's Response objects are fully supported, but are insufficient to fully support the rich Drupal ecosystem: 

we need more structured metadata than the very simple Symfony Response objects can provide.

Unfortunately, Symfony Response objects do not have an interface: 

every specialized Response "type" needs to extend from Symfony's Response base class.

 

HTTP is all about requests and responses. 

Drupal represents the responses it sends as Response objects. 

Drupal’s responses are Symfony Response objects. 

Symfony’s documentation also applies to Drupal.

 

Drupal’s additional response interfaces

Drupal core defines two response interfaces that any response can implement to indicate it supports these particular Drupal capabilities.

 

CacheableResponseInterface

An interface for responses that can expose cacheability metadata. 

Cache contexts, tags, and max-age.

Note: it can easily be implemented by using the corresponding CacheableResponseTrait.

See CacheableResponseInterface for more about this!

 

AttachmentsInterface

An interface for responses that can expose #attached metadata. 

Asset libraries, <head> elements, placeholders …

Note: it can easily be implemented by using the corresponding AttachmentsTrait.

 

Drupal’s additional response classes

Finally, to make discovery easier, here are the most important specialized Response subclasses available to developers.

 

CacheableResponse

A response that contains and can expose cacheability metadata. 

Supports Drupal's caching concepts: cache tags for invalidation and cache contexts for variations.

This is simply class CacheableResponse extends Response implements CacheableResponseInterface {}.

 

HtmlResponse

This is what a controller returning a render array will result in after going through the Render API and its render pipeline.

This is simply a class HtmlResponse extends Response implements CacheableResponseInterface, AttachmentsInterface {}.
HtmlResponse extends Response implements CacheableResponseInterface, AttachmentsInterface.

use Drupal\Core\Render\HtmlResponse

 

JsonResponse

A JsonResponse returns JSON output.

see the example below.

use Symfony\Component\HttpFoundation\JsonResponse;

 

CacheableJsonResponse

A JsonResponse that contains and can expose cacheability metadata.

This is simply class CacheableJsonResponse extends JsonResponse implements CacheableResponseInterface {} — i.e. it extends Symfony's JsonResponse.

class CacheableJsonResponse extends JsonResponse.

use Drupal\Core\Cache\CacheableJsonResponse;

 

CacheableRedirectResponse

A RedirectResponse that contains and can expose cacheability metadata.

This is simply class CacheableRedirectResponse extends RedirectResponse implements CacheableResponseInterface {} — i.e. it extends Symfony's RedirectResponse.

 

RedirectResponse

To redirect the client to another URL, you can use the RedirectResponse class, but it is safer to use LocalRedirectResponse or TrustedRedirectResponse.

 

LocalRedirectResponse

A redirect response that cannot redirect to an external URL. 

Extends CacheableRedirectResponse.

 

TrustedRedirectResponse

A redirect response should only redirect to a trusted, potentially external URL. 

It also extends CacheableRedirectResponse.

 

Creating JSON Response steps

step #1:

create file mymodule.routing.yml

and add to it route definition, which should look the following

codimth.json_api_articles:
  path: '/api/articles'
  defaults:
    _controller: 'Drupal\mymodule\Controller\JsonApiArticlesController::index'
    _title: 'Codimth JSON api'
  methods:  [GET]
  requirements:
    _access: 'TRUE'

now since we defined a controller file in argument '_controller', let's create this file

#step #2

create src/Controller/JsonApiArticlesController.php

 

getData(): will return article nodes from the database.

 

<?php
namespace Drupal\mymodule\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
 * Class JsonApiArticlesController
 * @package Drupal\mymodule\Controller
 */
class JsonApiArticlesController {

  /**
   * @return JsonResponse
   */
  public function index() {
    return new JsonResponse([ 'data' => $this->getData(), 'method' => 'GET', 'status'=> 200]);
  }

  /**
   * @return array
   */
  public function getData() {

    $result=[];
    $query = \Drupal::entityQuery('node')
      ->condition('type', 'article')
      ->sort('title', 'DESC');
    $nodes_ids = $query->execute();
    if ($nodes_ids) {
      foreach ($nodes_ids as $node_id) {
        $node = \Drupal\node\Entity\Node::load($node_id);
        $result[] = [
          "id" => $node->id(),
          "title" => $node->getTitle(),
        ];
      }
    }
    return $result;
  }
}

you should pay attention to the following points:

  • the code imports Symfony's library HttpFoundation/JsonResponse, which is already included within Drupal8 and up, no need to pre-install it
  • The index method returns a handle to JsonResponse, which includes the data, response type, and response status
  • The actual data is been built in a different method, it is optional, and gives more order which will simplify maintenance.
  • The getData method creates an array of data

 

To those who have read about the Jsonapi module - it was abundant, and it is part of the Drupal core
https://www.drupal.org/project/jsonapi

As of 7 January, 2020, the 8.x-1.x of JSON:API is unsupported.
 

A RedirectResponse Example

use Symfony\Component\HttpFoundation\RedirectResponse;

public function removeGroupResponse($group_id) {
    $redirect = Url::fromRoute('mymodule.route.def')->toString();
    return new RedirectResponse($redirect);        
}