Skip to main content

JsonResponse

Displaying 1 - 3 of 3

Custom controller with JSON response

how to create a custom controller with JSON response in Drupal 8.

this might work on Drupal 9 and 10, but I never tested it on these versions.

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;
  }
}
use Symfony\Component\HttpFoundation\JsonResponse;

// if you know the data to send when creating the response
$response = new JsonResponse(['data' => 123]);

// if you don't know the data to send or if you want to customize the encoding options
$response = new JsonResponse();
// ...
// configure any custom encoding options (if needed, it must be called before "setData()")
//$response->setEncodingOptions(JsonResponse::DEFAULT_ENCODING_OPTIONS | \JSON_PRESERVE_ZERO_FRACTION);
$response->setData(['data' => 123]);

// if the data to send is already encoded in JSON
$response = JsonResponse::fromJsonString('{ "data": 123 }');

Requests and Responses the Drupal way

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.

RESTful Example using jQuery and core REST module

CREATE Item

var package = {}
package.title = [{'value':'t1'}]
package.body = [{'value':'b1'}]
package._links = {"type":{"href":"http://local.drupal8.org/rest/type/node/page"}}
$.ajax({
  url: "http://example.com/entity/node",
  method: "POST",
  data: JSON.stringify(package),
  headers: {
    "Accept": "application/json",
    "Content-Type": "application/hal+json"
  },
  success: function(data, status, xhr) {
    debugger
  }
})

GET Item

$.ajax({
  url: "http://example.com/node/3?_format=hal_json",
  method: "GET",
  headers: {
    "Content-Type": "application/hal+json"
  },
  success: function(data, status, xhr) {
    debugger
  }
})

GET an Item and then UPDATE Item

$.ajax({
  url: "http://example.com/node/3?_format=hal_json",
  method: "GET",
  headers: {
    "Content-Type": "application/hal+json"
  },
  success: function(data, status, xhr) {
    var package = {}
    package.title = data.title
    package.body = data.body
    package.title[0].value = 'yar'
    package._links = {"type":{"href":"http://example.com/rest/type/node/page"}}
    debugger

    $.ajax({
      url: "http://example.com/node/3",
      method: "PATCH",
      data: JSON.stringify(package),
      headers: {
        "X-CSRF-Token": "niCxgd5ZZG25YepbYtckCy7Q2_GL2SvMUY5PINxRAHw",
        "Accept": "application/json",
        "Content-Type": "application/hal+json"
      },
      success: function(data, status, xhr) {
        debugger
      }
    })
  }
})

Drupal protects its REST resources from CSRF attacks by requiring a X-CSRF-Token request header to be sent when using a non-safe method. So, when performing non-read-only requests, that token is required. 
Such a token can be retrieved at /session/token.

GET an Item and then UPDATE Item with CSRF token.

$.ajax({
  url: 'http://example.com/session/token',
  method: 'GET',
  success: function(token) {
    var csrfToken = token;

    $.ajax({
      url: "http://example.com/node/3?_format=hal_json",
      method: "GET",
      headers: {
        "Content-Type": "application/hal+json"
      },
      success: function(data, status, xhr) {
        var package = {};
        package.title = data.title;
        package.body = data.body;
        package.title[0].value = 'yar';
        package._links = {"type":{"href":"http://example.com/rest/type/node/page"}};
        debugger

        $.ajax({
          url: "http://example.com/node/3",
          method: "PATCH",
          data: JSON.stringify(package),
          headers: {
            "X-CSRF-Token": csrfToken,
            "Accept": "application/json",
            "Content-Type": "application/hal+json"
          },
          success: function(data, status, xhr) {
            debugger;
          }
        });
      }
    });
  }
});

DELETE Item

$.ajax({
  url: "http://example.com/node/3",
  method: "DELETE",
  headers: {
    "Accept": "application/json",
    "Content-Type": "application/hal+json"
  },
  success: function(data, status, xhr) {
    debugger
  }
})